Redis(四)主从复制
主从复制
简介
主机数据更新之后根据配置和策略,自动同步数据到备机的Master/Slaver
机制,Master以写为主,Slaver以读为主。
这样的机制能够实现:
-
读写分离:Master以写为主,Slaver以读为主
-
容灾的快速分布:从机一个宕机,则去读别的从机

主从复制的一般策略都是一主多从,不能设置多个主机
1.1 搭建一主多从
创建一个myredis文件夹,并复制三分配置文件
[root@hadoop100 /]# mkdir myredis [root@hadoop100 /]# cp /etc/redis.conf /myredis/redis.conf [root@hadoop100 /]# ls - bin boot dev etc home lib lib64 media mnt mydata myredis opt p proc root run sbin srv sys tmp usr var [root@hadoop100 /]# cd /myredis/ [root@hadoop100 myredis]# ls redis.conf [root@hadoop100 myredis]# vi redis.conf [root@hadoop100 myredis]# vi redis6379.conf [root@hadoop100 myredis]# vi redis6380.conf [root@hadoop100 myredis]# vi redis6381.conf
配置文件内容:
include /myredis/redis.conf pidfile /var/run/redis_6379.pid port 6379 dbfilename dump6379.rdb
分别为包含一个公共的配置文件信息、设置redis端口号文件、设置端口号以及设置RDB持久化文件名称
执行redis-server redisxxxx.conf 以配置文件启动对应端口号的redis
[root@hadoop100 myredis]# ps -ef | grep redis root 2476 1 0 02:07 ? 00:01:06 redis-server 127.0.0.1:6378 polkitd 16606 16545 0 22:21 ? 00:00:00 redis-server *:6379 root 16912 1 0 22:29 ? 00:00:00 redis-server 127.0.0.1:6380 root 16916 1 0 22:29 ? 00:00:00 redis-server 127.0.0.1:6381 root 16952 1 0 22:31 ? 00:00:00 redis-server 127.0.0.1:6382 root 16956 16108 0 22:31 pts/1 00:00:00 grep --color=auto redis
执行redis-cli -p xxxx 进入指定端口号的redis
执行 info replication查看redis主从信息
127.0.0.1:6380> info replication # Replication role:master connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6380> info replication
执行 slaveof 为从机绑定主机
[root@hadoop100 ~]# redis-cli -p 6381 127.0.0.1:6381> slaveof 127.0.0.1 6380 OK 127.0.0.1:6381> info replication # Replication role:slave master_host:127.0.0.1 master_port:6380 master_link_status:up master_last_io_seconds_ago:3 master_sync_in_progress:0 slave_repl_offset:57 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
测试主从复制
主机
127.0.0.1:6380> set v1 k1 OK 127.0.0.1:6380> keys * 1) "v1" 127.0.0.1:6380>
从机
127.0.0.1:6381> keys * 1) "v1" 127.0.0.1:6381> set k2 v2 (error) READONLY You can't write against a read only slave. 127.0.0.1:6381>
1.2 复制原理和一主二仆
主机宕机
假设这时候主句6380宕机了,6381 6382仍然是从机,并且仍然不能执行写操作但能执行读操作
127.0.0.1:6380> shutdown not connected> exit
127.0.0.1:6381> info replication # Replication role:slave master_host:127.0.0.1 master_port:6380 master_link_status:down master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:2811 master_link_down_since_seconds:18 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6381> keys * 1) "v1" 127.0.0.1:6381> set k2 v2 (error) READONLY You can't write against a read only slave. 127.0.0.1:6381>
再重新使用6380的配置文件启动主机并连接redis客户端,从机会显示主机正常
[root@hadoop100 myredis]# redis-server /myredis/redis6380.conf [root@hadoop100 myredis]# redis-cli -p 6380 127.0.0.1:6380>
127.0.0.1:6381> info replication # Replication role:slave master_host:127.0.0.1 master_port:6380 master_link_status:up master_last_io_seconds_ago:10 master_sync_in_progress:0 slave_repl_offset:57 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
从机宕机
假设这时候从机6382宕机,主机6380会显示只有一个从机6381
127.0.0.1:6382> shutdown not connected> exit
127.0.0.1:6380> info replication # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6381,state=online,offset=2251,lag=0 master_repl_offset:2251 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:2250
再重新启动redis6382并链接redis客户端,会发现从机变为了主机
[root@hadoop100 ~]# redis-server /myredis/redis6382.conf [root@hadoop100 ~]# redis-cli -p 6382 127.0.0.1:6382> info replication # Replication role:master connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
这时候就需要重新绑定主机,然后可以看到内容依然是主机6380的内容
127.0.0.1:6382> slaveof 127.0.0.1 6380 OK 127.0.0.1:6382> keys * 1) "v1"
复制原理
从机启动成功连接到master的时候,会发送一个sync命令,主机接收到命令之后,会启动后台的存盘进程,在后台启动完毕之后,master会将传送整个RDB数据文件到slave,以完成一次完全同步。
全量复制
:slave在连接成功后,将master发送的数据库文件存盘并加载到内存。
增量复制
:master在每次执行写操作后,会将修改命令依次传递给slave,完成同步。
只要是每次重新连接master,一次完成同步
1.3 薪火相传和反客为主
薪火相传
薪火相传指的是上一个slave可以是下一个slave的master,下面的slave同样可以接收其他slave的连接和同步请求,可以有效减轻master的 写压力 (感觉还是减少的写操作的时候需要调用存盘进程的问题),以此去中心化降低风险
测试
127.0.0.1:6382> slaveof 127.0.0.1 6381 OK 127.0.0.1:6382> keys * 1) "v1" 127.0.0.1:6382> keys * 1) "k2" 2) "v1"
反客为主
当一个主机宕机后,后面的slave从机可以立刻升级为master,其后的slave不用做任何操作。
首先down掉主机6380
127.0.0.1:6380> shutdown not connected> exit [root@hadoop100 myredis]#
然后查看两个从机状态
127.0.0.1:6381> info replication # Replication role:slave master_host:127.0.0.1 master_port:6380 master_link_status:down master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:14137 master_link_down_since_seconds:15 slave_priority:100 slave_read_only:1 connected_slaves:1 slave0:ip=127.0.0.1,port=6382,state=online,offset=6325,lag=1 master_repl_offset:6325 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:6324
127.0.0.1:6382> info replication # Replication role:slave master_host:127.0.0.1 master_port:6381 master_link_status:up master_last_io_seconds_ago:6 master_sync_in_progress:0 slave_repl_offset:6493 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
slaveof no one升级为主机
127.0.0.1:6381> slaveof no one OK 127.0.0.1:6381> 127.0.0.1:6381> 127.0.0.1:6381> info replication # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6382,state=online,offset=6577,lag=0 master_repl_offset:6577 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:6576
1.4 哨兵模式
可以看到上面的从机升级为主机需要手动执行命令,而哨兵模式就是能够自动实现主从切换的,即反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票自动将从库转换为主库
创建哨兵的配置文件sentinel.conf 并配置相关内容
vi sentinel.conf sentinel monitor mymaster 127.0.0.1 6380 1
配置文件名必须为sentinel.conf,mymaster是为监控对象起的服务器名称,1为当有多少个哨兵同意才会迁移
运行哨兵 redis-sentinel /myredis/sentinel.conf
可以看到检测信息:
19743:X 09 Nov 03:14:59.705 # -sdown master mymaster 127.0.0.1 6380 19743:X 09 Nov 03:14:59.705 # -odown master mymaster 127.0.0.1 6380 19743:X 09 Nov 03:16:40.019 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380 19743:X 09 Nov 03:16:50.089 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
即主机6380和它的两个从机6381以及6382
测试
这时候关闭主机6380
127.0.0.1:6380> shutdown not connected> exit
这时候的哨兵输出
19743:X 09 Nov 03:22:39.737 # +switch-master mymaster 127.0.0.1 6380 127.0.0.1 6382 19743:X 09 Nov 03:22:39.737 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6382 19743:X 09 Nov 03:22:39.737 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6382
可以看到切换为了6382从机
再次启动原来的主机,发现主机变为了从机
[root@hadoop100 myredis]# redis-server redis6380.conf [root@hadoop100 myredis]# redis-cli -p 6380 127.0.0.1:6380> info replication # Replication role:slave master_host:127.0.0.1 master_port:6382 master_link_status:up master_last_io_seconds_ago:2 master_sync_in_progress:0 slave_repl_offset:7383 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6380>
主机宕机后,从机中如何选举产生新的主机
会根据设置的优先级产生新的主机,优先级数字越小表示优先级别越高
# The slave priority is an integer number published by Redis in the INFO output. # It is used by Redis Sentinel in order to select a slave to promote into a # master if the master is no longer working correctly. # # A slave with a low priority number is considered better for promotion, so # for instance if there are three slaves with priority 10, 100, 25 Sentinel will # pick the one with priority 10, that is the lowest. # # However a special priority of 0 marks the slave as not able to perform the # role of master, so a slave with priority of 0 will never be selected by # Redis Sentinel for promotion. # # By default the priority is 100. slave-priority 100
复制延时问题
由于所有的写操作都是在Master上操作,然后同步更新到Slave上,所以从Master同步更新到Slave上有一定的延迟,当系统很忙的时候延时会很严重,并且slave机器的数量也会增大这个延时。
1.5 Jedis中的主从复制

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步