Redis 你需要注意的地方

本文深入探讨Redis的RDB快照与AOF日志两种持久化方式的工作原理及最佳实践,同时解析主从复制机制,包括网络配置、复制偏移量及全量复制过程中的注意事项。

RDB和AFO篇


(1)父进程执行fork操作创建子进程, fork操作过程中父进程会阻塞, 通过info stats命令查看latest_fork_usec选项, 可以获取最近一个fork操作的耗时, 单位为微秒。 

[root@localhost ~]# /usr/local/redis/bin/redis-cli info stats | grep latest
latest_fork_usec:1087

fork耗时问题定位: 对于高流量的Redis实例OPS可达5万以上, 如果fork操作耗时在秒级别将拖慢Redis几万条命令执行, 对线上应用延迟影响非常明显。 正常情况下fork耗时应该是每GB消耗20毫秒左右。 可以在info stats统计中查latest_fork_usec指标获取最近一次fork操作耗时, 单位微秒。
 

(2)子进程创建RDB文件, 根据父进程内存生成临时快照文件, 完成后对原有文件进行原子替换。 执行lastsave命令可以获取最后一次生成RDB的时间, 对应info统计的rdb_last_save_time选项

[root@localhost ~]# /usr/local/redis/bin/redis-cli info | grep rdb_last_save
rdb_last_save_time:1588234245

 

(3)每当发生AOF追加阻塞事件发生时, 在info Persistence统计中,aof_delayed_fsync指标会累加, 查看这个指标方便定位AOF阻塞问题。

[root@localhost ~]# /usr/local/redis/bin/redis-cli info | grep aof_delay
aof_delayed_fsync:0

 

(4)避免在大量写入时做子进程重写操作, 这样将导致父进程维护大量页副本, 造成内存消耗。Linux kernel在2.6.38内核增加了Transparent Huge Pages( THP) , 支持huge page( 2MB) 的页分配, 默认开启。 当开启时可以降低fork创建子进程
的速度, 但执行fork之后, 如果开启THP, 复制页单位从原来4KB变为2MB, 会大幅增加重写期间父进程内存消耗。 建议设置“sudo echo never>/sys/kernel/mm/transparent_hugepage/enabled”关闭THP。 
 

 

 

RDB配置参数:

stop-writes-on-bgsave-error yes 这个配置也是非常重要的一项配置,这是当备份进程出错时,主进程就停止接受新的写入操作,是为了保护持久化的数据一致性问题。如果自己的业务有完善的监控系统,可以禁止此项配置, 否则请开启。

关于压缩的配置 rdbcompression yes

运维提示:
当遇到坏盘或磁盘写满等情况时, 可以通过config set dir{newDir}在线修改文件路径到可用的磁盘路径, 之后执行bgsave进行磁盘切换, 同样适用于AOF持久化文件。

压缩:rdbcompression yes 。Redis默认采用LZF算法对生成的RDB文件做压缩处理, 压缩后的文件远远小于内存大小, 默认开启, 可以通过参数config set rdbcompression{yes|no}动态修改。虽然压缩RDB会消耗CPU, 但可大幅降低文件的体积, 方便保存到硬盘或通过网络发送给从节点, 因此线上建议开启。

 

 

主从复制


(1)主从节点一般部署在不同机器上, 复制时的网络延迟就成为需要考虑的问题, Redis为我们提供了repl-disable-tcp-nodelay参数用于控制是否关闭TCP_NODELAY, 默认关闭, 说明如下:

·当关闭时, 主节点产生的命令数据无论大小都会及时地发送给从节点, 这样主从之间延迟会变小, 但增加了网络带宽的消耗。 适用于主从之间的网络环境良好的场景, 如同机架或同机房部署。
·当开启时, 主节点会合并较小的TCP数据包从而节省带宽。 默认发送时间间隔取决于Linux的内核, 一般默认为40毫秒。 这种配置节省了带宽但增大主从之间的延迟。 适用于主从网络环境复杂或带宽紧张的场景, 如跨机房部署
 

运维提示:
部署主从节点时需要考虑网络延迟、 带宽使用率、 防灾级别等因素, 如要求低延迟时, 建议同机架或同机房部署并关闭repl-disable-tcp-nodelay; 如果考虑高容灾性, 可以同城跨机房部署并开启repl-disable-tcp-nodelay。

 

(2)复制偏移量的维护如图所示。通过对比主从节点的复制偏移量, 可以判断主从节点数据是否一致。

[root@localhost ~]# /usr/local/redis/bin/redis-cli info replication 
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.179.103,port=6379,state=online,offset=5850,lag=0  --从节点偏移量5850
slave1:ip=192.168.179.104,port=6379,state=online,offset=5850,lag=0
master_replid:999f89051b48418f2b1f498996d9a6f77a4feb5f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:5850   --主节点偏移量

运维提示:
可以通过主节点的统计信息, 计算出master_repl_offset-slave_offset字节量, 判断主从节点复制相差的数据量, 根据这个差值判定当前复制的健康度。 如果主从之间复制偏移量相差较大, 则可能是网络延迟或命令阻塞等原因引起。

(3) 主节点发送RDB文件给从节点, 从节点把接收的RDB文件保存在本地并直接作为从节点的数据文件, 接收完RDB后从节点打印相关日志, 可以在日志中查看主节点发送的数据量:

16:24:03.057 * MASTER <-> SLAVE sync: receiving 24777842 bytes from master
 
自己测试
1734:S 11 May 2020 11:46:39.664 * MASTER <-> REPLICA sync: receiving 175 bytes from master


需要注意, 对于数据量较大的主节点, 比如生成的RDB文件超过6GB以上时要格外小心。 传输文件这一步操作非常耗时, 速度取决于主从节点之间网络带宽, 通过细致分析Full resync和MASTER<->SLAVE这两行日志的时间差, 可以算出RDB文件从创建到传输完毕消耗的总时间。

1734:S 11 May 2020 11:46:39.597 * Full resync from master: c99ea11437b9df513dc5b29cc449de14fd7813bc:0
1734:S 11 May 2020 11:46:39.597 * Discarding previously cached master state.
1734:S 11 May 2020 11:46:39.664 * MASTER <-> REPLICA sync: receiving 175 bytes from master
Full resync from master----------->MASTER <-> REPLICA sync: receiving 175 bytes from master

之间时间间隔可以算出RDB消耗的时间如果总时间超过repl-timeout所配置的值(默认60秒) , 从节点将放弃接受RDB文件并清理已经下载的临时文件, 导致全量复制失败, 此时从节点打印如下日志:

M 27 May 12:13:33.669 # Client id=2 addr=127.0.0.1:24555 age=1 idle=1 flags=S
qbuf=0 qbuf-free=0 obl=18824 oll=21382 omem=268442640 events=r cmd=psync
scheduled to be closed ASAP for overcoming of output buffer limits.

repl-timeout:slave和master之间的复制超时时间,默认为60s, 推荐设置为180s;

[root@localhost ~]# /usr/local/redis/bin/redis-cli 
127.0.0.1:6379> config get repl-timeout
1) "repl-timeout"
2) "60"


a) slave角度,如果在repl-timeout时间内没有收到master SYNC传输的rdb snapshot数据,
b) slave角度,在repl-timeout没有收到master发送的数据包或者ping。
c) master角度,在repl-timeout时间没有收到REPCONF ACK确认信息。
当redis检测到repl-timeout超时(默认值60s),将会关闭主从之间的连接,redis slave发起重新建立主从连接的请求。
对于内存数据集比较大的系统,可以增大repl-timeout参数。
 

(4) 对于从节点开始接收RDB快照到接收完成期间, 主节点仍然响应读写命令, 因此主节点会把这期间写命令数据保存在复制客户端缓冲区内, 当从节点加载完RDB文件后, 主节点再把缓冲区内的数据发送给从节点, 保证主从之间数据一致性。 如果主节点创建和传输RDB的时间过长, 对于高流量写入场景非常容易造成主节点复制客户端缓冲区溢出。 默认配置为clientoutput-buffer-limit slave 256MB 64MB 60, 如果60秒内缓冲区消耗持续大于64MB或者直接超过256MB时, 主节点将直接关闭复制客户端连接, 造成全量同步失败。 对应日志如下:

M 27 May 12:13:33.669 # Client id=2 addr=127.0.0.1:24555 age=1 idle=1 flags=S
qbuf=0 qbuf-free=0 obl=18824 oll=21382 omem=268442640 events=r cmd=psync
scheduled to be closed ASAP for overcoming of output buffer limits.

因此, 运维人员需要根据主节点数据量和写命令并发量调整clientoutput-buffer-limit slave配置, 避免全量复制期间客户端缓冲区溢出。
 

<think>好的,我现在需要帮助用户解决在Redis中设置密码后如何安全地批量删除指定keys的问题。首先,我要仔细分析用户的需求,用户已经启用了密码认证,现在需要安全地进行批量删除,而用户可能担心使用KEYS命令会导致性能问题,比如阻塞Redis实例。 根据用户提供的引用内容,特别是引用[1]提到KEYS命令会收集所有匹配的keys再一次性删除,可能导致实例夯住。所以,我需要避免使用KEYS命令,而推荐使用SCAN命令,因为SCAN是增量式的,不会一次性加载所有keys,减少内存压力和阻塞风险。 接下来,用户提到密码认证,所以执行命令时需要包含认证信息。引用[3]中的例子使用了redis-cli的-a参数来指定密码,这可以作为参考。但要注意安全,避免在命令行中直接显示密码,可以使用--ask-pass选项或者将密码保存在安全的地方,通过环境变量传递。 然后,考虑如何结合SCAN和DEL命令。通常的做法是使用redis-cli的--scan选项配合模式匹配,然后通过管道传递给xargs处理,分批删除。例如,每次删除5000个key,这样可以减少单次操作的压力。引用[3]中的命令使用了xargs -L 5000来分批次处理,这样可以有效避免一次性删除大量key的问题。 另外,引用[4]提到fork函数可能阻塞主线程,如果进行持久化操作的话。所以,在删除大量key时,可能需要考虑是否关闭持久化(如引用[2]所述),但用户需要权衡数据丢失的风险。如果允许临时关闭,可以在删除期间关闭RDB和AOF,但完成后记得重新开启。 还需要注意权限问题,确保执行命令的用户有权限删除这些keys。同时,建议在测试环境先验证命令的正确性,避免误删生产数据。最后,提供一个完整的命令示例,并强调安全措施,比如使用非阻塞命令、分批次处理、密码安全等。 总结步骤应该是:使用SCAN代替KEYS,结合xargs分批次删除,认证时安全传递密码,考虑持久化配置,并在操作前后备份数据。同时,提醒用户监控Redis性能,确保操作不会影响线上服务。</think>在Redis启用密码认证后安全批量删除指定keys,需综合使用SCAN命令、分批次处理和认证参数,避免使用KEYS命令导致性能问题。具体步骤如下: ### 一、安全删除操作步骤 1. **使用SCAN替代KEYS** 通过$SCAN$命令增量遍历匹配的key,避免KEYS命令全量加载导致内存激增: ```bash redis-cli -a "yourpassword" --scan --pattern "*:login" | xargs -L 5000 redis-cli -a "yourpassword" DEL ``` - `--scan`:使用游标分批次扫描,避免阻塞[^1] - `-L 5000`:每批次处理5000个key,控制单次操作量[^3] - `-a "yourpassword"`:密码认证参数 2. **密码安全增强方案** - 通过`--ask-pass`交互式输入密码(避免密码明文出现在命令历史): ```bash redis-cli --ask-pass --scan --pattern "*:login" | xargs -L 5000 redis-cli --ask-pass DEL ``` - 或使用环境变量传递密码: ```bash export REDISCLI_AUTH=yourpassword redis-cli --scan --pattern "*:login" | xargs -L 5000 redis-cli DEL ``` 3. **持久化配置调优(可选)** 若业务允许短暂数据丢失风险,可临时关闭持久化提升性能: ```bash # 关闭RDB redis-cli -a "yourpassword" config set save "" # 关闭AOF redis-cli -a "yourpassword" config set appendonly no ``` 操作完成后需恢复持久化设置[^2] ### 二、操作注意事项 1. **预验证模式** 先执行`SCAN`命令预览待删除keys: ```bash redis-cli -a "yourpassword" --scan --pattern "*:login" --count 1000 ``` 2. **生产环境防护** - 建议在从节点执行删除操作 - 操作前执行`BGSAVE`备份数据 - 使用`SLOWLOG`监控删除耗时[^4] 3. **替代方案参考** 对于超大规模数据(如百万级key),建议使用Lua脚本分片处理: ```lua local cursor = 0 repeat local result = redis.call('SCAN', cursor, 'MATCH', '*:login', 'COUNT', 5000) cursor = tonumber(result[1]) redis.call('DEL', unpack(result[2])) until cursor == 0 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值