Redis
主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis
可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布 记录。同步对读取操作的可扩展性和数据冗余很有帮助。
工作原理 Redis
的主从结构可以采用一主多从或者级联结构,Redis
主从复制可以根据是否是全量分为全量同步和增量同步。
全量同步 Redis
全量复制一般发生在Slave
初始化阶段,这时Slave
需要将Master
上的所有数据都复制一份。具体步骤如下:
1)从服务器连接主服务器,发送SYNC
命令;
2)主服务器接收到SYNC命名后,开始执行BGSAVE
命令生成RDB
文件并使用缓冲区记录此后执行的所有写命令;
3)主服务器BGSAVE
执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
完成上面几个步骤后就完成了从服务器数据初始化的所有操作,从服务器此时可以接收来自用户的读请求。
增量同步 Redis
增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
Redis
主从同步策略 主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave
在任何时候都可以发起全量同步。redis
策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
注意点 如果多个Slave
断线了,需要重启的时候,因为只要Slave
启动,就会发送sync
请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO
剧增宕机。
示例 环境准备 1 2 3 server1:0.0 .0.0 :6379 redis-master server2:0.0 .0.0 :6380 redis-slave server3:0.0 .0.0 :6381 redis-slave
6379配置文件 :
1 2 3 4 5 6 7 8 root@Tony-PC :/tmp/redis-config /6379 daemonize yes port 6379 pidfile /tmp/redis-config /6379 /6379 .pid loglevel notice logfile /tmp/redis-config /6379 /6379 .log dir /tmp/redis-config dbfilename 6379 .rdb
6380配置文件:
使用sed
命令,将6379.conf
中的的6379替换为6380,替换后的结果写入到6380.conf
1 root@Tony-PC:/tmp/redis-config/6379# sed "s/6379/6380/g" redis-6379.conf > ../6380/6380.conf
1 2 3 4 5 6 7 8 9 root@Tony-PC :/tmp/redis-config /6379 daemonize yes port 6380 pidfile /tmp/redis-config /6380 /6380 .pid loglevel notice logfile /tmp/redis-config /6380 /6380 .log dir /tmp/redis-config dbfilename 6380 .rdb slaveof 127.0 .0.1 6379
6381配置文件:
使用sed
命令,将6379.conf
中的的6379替换为6381,替换后的结果写入到6381.conf
1 root@Tony-PC:/tmp/redis-config/6379# sed "s/6379/6381/g" redis-6379.conf > ../6381/6381.conf
1 2 3 4 5 6 7 8 9 root@Tony-PC :/tmp/redis-config /6379 daemonize yes port 6381 pidfile /tmp/redis-config /6381 /6381 .pid loglevel notice logfile /tmp/redis-config /6381 /6381 .log dir /tmp/redis-config dbfilename 6381 .rdb slaveof 127.0 .0.1 6379
启动redis
3个服务 1 2 3 4 5 6 7 8 9 10 11 12 13 root@Tony-PC :/tmp/redis-config /6379 root@Tony-PC :/tmp/redis-config /6379 root@Tony-PC :/tmp/redis-config /6379 root@Tony-PC :/tmp/redis-config /6379 root 5570 5546 0 10 :54 pts/3 00 :00 :00 vim /etc/redis/redis.conf tony 5782 1 0 10 :55 ? 00 :00 :00 /bin/bash /usr/bin/dde-file -manager-pkexec file:///var/log/redis root 5784 5782 0 10 :55 ? 00 :00 :43 /usr/bin/dde-file -manager file:///var/log/redis -w /home/tony root 14081 7206 0 14 :45 pts/4 00 :00 :00 redis-cli root 16443 1 0 15 :48 ? 00 :00 :00 redis-server *:6379 root 16448 1 0 15 :48 ? 00 :00 :00 redis-server *:6380 root 16454 1 0 15 :49 ? 00 :00 :00 redis-server *:6381 root 16464 7362 0 15 :49 pts/5 00 :00 :00 grep redis
查看主从状态 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 root@Tony-PC :~ 127.0 .0.1 :6379 > info replicationrole:master connected_slaves:2 slave0:ip=127.0 .0.1 ,port=6380 ,state=online,offset=252 ,lag=1 slave1:ip=127.0 .0.1 ,port=6381 ,state=online,offset=252 ,lag=1 master_replid:b8566352985ea4d4dd23a1d2a6f333f02c1d5c0c master_replid2:0000000000000000000000000000000000000000 master_repl_offset:252 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:252 root@Tony-PC :/tmp/redis-config 127.0 .0.1 :6380 > info replicationrole:slave master_host:127.0 .0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:6 master_sync_in_progress:0 slave_repl_offset:266 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:b8566352985ea4d4dd23a1d2a6f333f02c1d5c0c master_replid2:0000000000000000000000000000000000000000 master_repl_offset:266 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:266 root@Tony-PC :/tmp/redis-config 127.0 .0.1 :6381 > info replicationrole:slave master_host:127.0 .0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:3 master_sync_in_progress:0 slave_repl_offset:280 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:b8566352985ea4d4dd23a1d2a6f333f02c1d5c0c master_replid2:0000000000000000000000000000000000000000 master_repl_offset:280 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:15 repl_backlog_histlen:266
测试同步 执行代码发现redis-slave
能同步读取redis-master
上的信息,且只有redis-master
允许写入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 127.0 .0.1 :6379 > set country chinaOK 127.0 .0.1 :6379 > keys *1 ) "country" 127.0 .0.1 :6379 > get country"china" 127.0 .0.1 :6380 > set name tony(error) READONLY You can't write against a read only slave. 127.0.0.1:6380> keys * 1) "country" 127.0.0.1:6380> get country "china" 127.0.0.1:6381> get country "china" 127.0.0.1:6381> set name aaa (error) READONLY You can' t write against a read only slave.127.0 .0.1 :6381 > keys *1 ) "country"
主库故障切换主从库 关闭主库 1 2 127.0 .0.1 :6379 > shutdownnot connected>
查看从库状态 检查从库主从信息,此时master_link_status:down
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 127.0 .0.1 :6380 > info replicationrole:slave master_host:127.0 .0.1 master_port:6379 master_link_status:down master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:1782 master_link_down_since_seconds:13 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:b8566352985ea4d4dd23a1d2a6f333f02c1d5c0c master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1782 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1782 127.0 .0.1 :6381 > info replicationrole:slave master_host:127.0 .0.1 master_port:6379 master_link_status:down master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:1782 master_link_down_since_seconds:20 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:b8566352985ea4d4dd23a1d2a6f333f02c1d5c0c master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1782 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:15 repl_backlog_histlen:1768
重新设置主从库 将6380设为主库,6381设为6380的从库
1 2 3 4 5 6 7 8 9 10 127.0 .0.1 :6380 > SLAVEOF no oneOK ---------------------------------- 127.0 .0.1 :6381 > SLAVEOF no oneOK 127.0 .0.1 :6381 > SLAVEOF 127.0 .0.1 6380 OK
查看更新后的主从库状态 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 127.0 .0.1 :6380 > info replicationrole:master connected_slaves:1 slave0:ip=127.0 .0.1 ,port=6381 ,state=online,offset=2034 ,lag=0 master_replid:7851 d7e67129a0483b2925d7ac06dda221123cbe master_replid2:b8566352985ea4d4dd23a1d2a6f333f02c1d5c0c master_repl_offset:2034 second_repl_offset:1783 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:2034 127.0 .0.1 :6381 > info replicationrole:slave master_host:127.0 .0.1 master_port:6380 master_link_status:up master_last_io_seconds_ago:2 master_sync_in_progress:0 slave_repl_offset:1852 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:7851 d7e67129a0483b2925d7ac06dda221123cbe master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1852 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1783 repl_backlog_histlen:70