主从刚连接的时候,会进行全量同步,全量同步结束后进行增量同步
如果有需要会在任何时候发起全量同步,首先进行增量同步,如果不行就进行全量同步
redis主从复制的特点
1.是异步复制,实时性较差
2.一个主redis可以含有多个redis
3.可以使用级联结构
4.非阻塞的同步(因为是异步复制),同步时依然可以处理请求
5.提高的可用性和扩展性(可扩展,读负载均衡
redis主从复制过程
全量同步阶段(disk方式)
slave第一次启动时,初始化阶段,此时slave将master节点数据复制一遍
在2.8版本之前,重启slave节点也会进行全量同步
此时slave无法提供服务
1.slave连接master,发送sync
2.master收到sync,执行bgsave,生成快照文件
3.master向所有slave发送快照文件(会缓存此时写入的命令)
4.slave节点清空自己的数据,并且载入快照
5.master发送之前缓存的写命令
6.slave执行之前缓存的写命令
注: 需要关闭master节点的自启,因为可能会导致数据被清空
这种方式可以让多个slave节点同时进行读取rdb文件
全量同步会对从服务器产生很大的压力,所以启动后的同步都是增量同步
增量同步阶段
增量同步是从redis2.8后新增的功能(或slave重启后的阶段)
正常情况:
slave初始化后开始正常工作时,将master发生的写操作同步到slave
master每执行一个写命令,都会给slave发送同步写命令
slave节点宕机重启情况(2.8版本后):
增量同步依赖于master内存中给每个slave维护了一份同步日志和同步标识
具体而言,主服务器为复制流维护了一个内存缓冲区。维护复制偏移量和master run id
当slave重新连接上时,会进行判断
1.主从服务器的master run id是否相同
2.指定偏移量在内存缓冲区还有效(如果时间太久或短时间内大量写入就会失效)
如果满足就会从上次中断的点继续同步
如果其中一个不满足就会进行全量同步
无磁盘复制(socket方式)
在redis2.8.18版本后增加的功能,是串行复制
全量同步需要再磁盘上创建RDB文件,然后加载文件发送数据,如果使用低速磁盘会造成压力
使用无磁盘复制时,子进程直接将RDB通过网络发送给从服务器,不使用磁盘进行中间存储,避免IO性能问题
如果硬盘性能高(比如使用SSD作为内存)而网络性能紧张时,建议使用disk方式复制
如果硬盘性能低,而网络性能高时,建议使用socket方式复制
开启方式:redis.conf文件
repl-disless-sync yes
开启无磁盘复制
repl-diskless-sync-delay
传输延迟时间sec,设置尽量大
在这个时间范围内等待slave注册,注册了就传;如果没有注册,就需要等待下一批传输
主从复制的宕机情况
1.slave节点宕机
重新启动后,redis从库重启后自动加入主从结构,2.8版本前会全量同步,2.8版本后如果偏移量大就会全量同步,反之增量同步
2.master节点宕机
(1)在slave节点执行SLAVEOF NO ONE
,断开主从关系,并提升为主库继续服务
(2)主库修复启动后,执行SLAVEOF
,将其设置为其他库的从库,把数据更新回来
哨兵模式可以自动进行切换
主从复制配置与优化参数
相关参数
1 2 3 4 5 6 7 8 9 10 11 12
| slaveof 192.168.10.100 6379 开启主从复制(启动后自动开启) masterauth 123456 主从密码验证(slave需要有master的密码) slave-serve-stale-data yes yes: slave失去连接或正在同步时,slave会继续响应客户端请求 no: slave失去连接或正在同步时,除了info和slaveof以外的命令都会报错SYNC with master in progress slave-read-only yes 只读状态,默认为yes repl-diskless-sync no 是否使用socket方式复制(无磁盘复制) repl-diskless-sync-delay 5 传输延迟时间 repl-ping-slave-period 10 slave向master发送ping的时间间隔 repl-timeout 60 复制连接超时时间,如果上次slave发送时间超过60s就认为其离线 repl-backlog-size 5mb 复制缓冲区,用来保存新的缓存的命令:缓冲区越大,slave可以离线的时间更长 repl-backlog-ttl 3600 没有slave时释放缓冲区内存的时间3600s
|
简单演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| mkdir /var/log/redis -p 从 cat >redis-6379.conf<<EOF bind 127.0.0.1 dir ./ protected-mode yes port 6379 slave-serve-stale-data yes Logfile "/var/log/redis/redis-6379.log" databases 16 daemonize yes save 900 1 save 300 10 save 60 10000 EOF 主 cat >redis-6380.conf<<EOF bind 127.0.0.1 dir ./ protected-mode yes port 6380 slave-serve-stale-data yes Logfile "/var/log/redis/redis-6380.log" databases 16 daemonize yes save 900 1 save 300 10 save 60 10000 EOF
redis-server redis-6379.conf redis-server redis-6380.conf ss -tunlp |grep redi tcp LISTEN 0 128 127.0.0.1:6379 *:* users:(("redis-server",pid=19067,fd=6)) tcp LISTEN 0 128 127.0.0.1:6380 *:* users:(("redis-server",pid=19072,fd=6))
redis-cli -p 6379 SLAVEOF 127.0.0.1 6380
tail -f /var/log/redis/redis-6379.log 19067:S 21 Sep 2024 22:49:58.054 * MASTER <-> REPLICA sync started 19067:S 21 Sep 2024 22:49:58.054 * Non blocking connect for SYNC fired the event. 19067:S 21 Sep 2024 22:49:58.054 * Master replied to PING, replication can continue... 19067:S 21 Sep 2024 22:49:58.054 * Trying a partial resynchronization (request f93a36cd8e21e9b4b66ab7700436d7542898011c:1). 19067:S 21 Sep 2024 22:49:58.104 * Full resync from master: a8860a38e64e9b953173dcb04d20f06c38349198:0 19067:S 21 Sep 2024 22:49:58.104 * Discarding previously cached master state. 19067:S 21 Sep 2024 22:49:58.155 * MASTER <-> REPLICA sync: receiving 175 bytes from master 19067:S 21 Sep 2024 22:49:58.155 * MASTER <-> REPLICA sync: Flushing old data 19067:S 21 Sep 2024 22:49:58.155 * MASTER <-> REPLICA sync: Loading DB in memory 19067:S 21 Sep 2024 22:49:58.155 * MASTER <-> REPLICA sync: Finished with success
tail -f /var/log/redis/redis-6380.log 19072:M 21 Sep 2024 22:48:49.743 * DB loaded from disk: 0.000 seconds 19072:M 21 Sep 2024 22:48:49.743 * Ready to accept connections 19072:M 21 Sep 2024 22:49:58.054 * Replica 127.0.0.1:6379 asks for synchronization 19072:M 21 Sep 2024 22:49:58.054 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for 'f93a36cd8e21e9b4b66ab7700436d7542898011c', my replication IDs are 'e95f6a7290a9971653e08814f2f20db13e88ae43' and '0000000000000000000000000000000000000000') 19072:M 21 Sep 2024 22:49:58.054 * Starting BGSAVE for SYNC with target: disk 19072:M 21 Sep 2024 22:49:58.054 * Background saving started by pid 19141 19141:C 21 Sep 2024 22:49:58.105 * DB saved on disk 19141:C 21 Sep 2024 22:49:58.105 * RDB: 4 MB of memory used by copy-on-write 19072:M 21 Sep 2024 22:49:58.155 * Background saving terminated with success 19072:M 21 Sep 2024 22:49:58.155 * Synchronization with replica 127.0.0.1:6379 succeeded
搞个脚本写入一些数据
PORT=6380
for (( i=1; i<=1002; i++ )) do KEY="k_$i" VALUE="v_$i" redis-cli -p $PORT set "$KEY" "$VALUE" done
|