文章目录
Redis主从复制
-
也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主
-
能干什么:读写分离,容灾恢复
-
大概怎么玩: 1.配从(库)不配主(库) 2.从库配置:- slaveof主库IP主库端口: 每次与 master 断开之后,都需要重新连接,除非你配置进redis.conf文件 - Info replication 3.修改配置文件细节操作 1. 拷贝多个redis.conf文件 2. 开启daemonize yes 3. Pid文件名字 4. 指定端口 5. Log文件名字 6. Dump.rdb名字 4.常用3招 一主二仆 薪火相传 #1.上一个Slave可以是下一个slave的Master,Slave同样可以接收其他,slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力 #2. 中途变更转向:会清除之前的数据,重新建立拷贝最新的 #3. Slaveof新主库IP新主库端口 反客为主。
大概修改如下几处:
###
pidfile /var/run/redis_6380.pid
###
port 6380
####
logfile "自定义路径/6380.log"
###备份
dbfilename dump6380.rdb
###
一主二仆
-
修改完配置文件用
redis-server 文件路径
启动3台 redis -
-
-
-
master(6379)
-
[root@iZuf619z87y4phm0888ytzZ bin]# redis-cli #进入6379,逻辑上把这个定义为 主库(第一个窗口) 127.0.0.1:6380> Info replication # Replication role:master connected_slaves:0 master_failover_state:no-failover master_replid:48640383a43972c4636bdff1d92f67c72334a66f master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6379> Info replication # # Replication role:master connected_slaves:2 #可以发现6379 有两个小弟,角色还是master slave0:ip=127.0.0.1,port=6380,state=online,offset=262,lag=0 slave1:ip=127.0.0.1,port=6381,state=online,offset=262,lag=0 master_failover_state:no-failover master_replid:b6eadd48de9fa1abb73fd50b594c9897c5a0e058 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:262 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:262 127.0.0.1:6379> SHUTDOWN #当主机master挂了,6380/6381是原地待命,依旧是 slave ##### 127.0.0.1:6379> Info replication #当从机6380挂了 # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6381,state=online,offset=336,lag=1 master_failover_state:no-failover master_replid:69f484109a34847443d42cdcaa1aa176bbfeecad master_replid2:0000000000000000000000000000000000000000 master_repl_offset:336 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:336 127.0.0.1:6379>
-
slave(6380,6381)
-
[root@iZuf619z87y4phm0888ytzZ bin]# redis-cli -p 6380 #进入从库(第二个窗口) 127.0.0.1:6380> Info replication #一开始都默认自己是 master(6381也一样) # Replication role:master connected_slaves:0 master_failover_state:no-failover master_replid:48640383a43972c4636bdff1d92f67c72334a66f master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 #使6380变为从库 OK 127.0.0.1:6380> Info replication #role:slave 从master 变为slave # Replication #当从机第一次复制主机时是全量复制(把主机中所有内容都复制),后续数据是增量复制 role:slave master_host:127.0.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_read_repl_offset:122 slave_repl_offset:122 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:b6eadd48de9fa1abb73fd50b594c9897c5a0e058 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:122 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:122 127.0.0.1:6380> set k2 v3 #从机不能写入 (error) READONLY You can't write against a read only replica. 127.0.0.1:6380> Info replication #当主机master 挂了(shutdown),role:slave # Replication role: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_read_repl_offset:1494 slave_repl_offset:1494 master_link_down_since_seconds:5 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:b6eadd48de9fa1abb73fd50b594c9897c5a0e058 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1494 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1494 127.0.0.1:6380> SHUTDOWN 127.0.0.1:6380> SHUTDOWN not connected> [root@iZuf619z87y4phm0888ytzZ ~]# redis-server /zzyyuse/redis-6.2.7/Redis-con/redis6380.conf [root@iZuf619z87y4phm0888ytzZ ~]# redis-cli -p 6380 127.0.0.1:6380> Info replication #当从机从新恢复时,role:master,角色默认为master,应为没有把SLAVEOF 127.0.0.1 6379 配置进 redis.conf文件 # Replication role:master connected_slaves:0 master_failover_state:no-failover master_replid:9b594f2e5ffa120ea2649609e67ea44f8c758a0b master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6380>
薪火相传
-
A. [从机6380]--->[主机]<---[从机6381] #一主二从 #中心化严重,现在有两台 从机(也可能会有更多从机) 都找主机拿数据(一对多,主机压力大) B. [主机]---->[从机6380]---->[从机6381] #薪火相传 #去中心化,减轻主机负担,缺点:复制数据会有延迟 1.上一个Slave可以是下一个slave的Master,Slave同样可以接收其他,slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力 2. 中途变更转向:会清除之前的数据,重新建立拷贝最新的
-
master(6379)
-
127.0.0.1:6379> Info replication # Replication #主机现在只有6380一个小弟了 role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6380,state=online,offset=2842,lag=1 master_failover_state:no-failover master_replid:69f484109a34847443d42cdcaa1aa176bbfeecad master_replid2:0000000000000000000000000000000000000000 master_repl_offset:2842 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:2842 127.0.0.1:6379> keys * 1) "k1" 127.0.0.1:6379> set k2 v2 OK
-
slave(6380)
-
[root@iZuf619z87y4phm0888ytzZ ~]# redis-cli -p 6380 127.0.0.1:6380> ping PONG 127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 #6380还是跟这老大6379 OK 127.0.0.1:6380> INFO replication # Replication role: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_read_repl_offset:3006 slave_repl_offset:3006 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:1 slave0:ip=127.0.0.1,port=6381,state=online,offset=3006,lag=1 master_failover_state:no-failover master_replid:69f484109a34847443d42cdcaa1aa176bbfeecad master_replid2:0000000000000000000000000000000000000000 master_repl_offset:3006 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2759 repl_backlog_histlen:248 127.0.0.1:6380> get k2 "v2" 127.0.0.1:6380>
-
slave(6381)
-
[root@iZuf619z87y4phm0888ytzZ ~]# redis-cli -p 6381 127.0.0.1:6381> SLAVEOF 127.0.0.1 6380 OK 127.0.0.1:6381> Info replication # Replication #6381则 复制6380的数据 role:slave master_host:127.0.0.1 master_port:6380 master_link_status:up master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_read_repl_offset:3048 slave_repl_offset:3048 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:69f484109a34847443d42cdcaa1aa176bbfeecad master_replid2:0000000000000000000000000000000000000000 master_repl_offset:3048 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2787 repl_backlog_histlen:262 127.0.0.1:6381> get k2 "v2"
反客为主(slaveof no one 使当前数据库停止与其他数据库的同步,转成主数据库)
-
master(6379)
-
127.0.0.1:6379> Info replication #环境还原到 一主二仆 # Replication role:master connected_slaves:2 slave0:ip=127.0.0.1,port=6380,state=online,offset=3314,lag=0 slave1:ip=127.0.0.1,port=6381,state=online,offset=3314,lag=0 master_failover_state:no-failover master_replid:69f484109a34847443d42cdcaa1aa176bbfeecad master_replid2:0000000000000000000000000000000000000000 master_repl_offset:3314 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:3314 127.0.0.1:6379> SHUTDOWN #假设 master 挂了 not connected> [root@iZuf619z87y4phm0888ytzZ bin]# redis-server /zzyyuse/redis-6.2.7/Redis-con/redis6379.conf [root@iZuf619z87y4phm0888ytzZ bin]# redis-cli 127.0.0.1:6379> Info replication #6379从新恢复,还是master,但没了小弟,与6380和6381不在是一个体系了 # Replication role:master connected_slaves:0 master_failover_state:no-failover master_replid:0488038bd16c4e679f9c77ec3dcaa07f1f4092f6 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6379>
-
slave(6380)–>master
-
127.0.0.1:6380> INFO replication # Replication role: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_read_repl_offset:3006 slave_repl_offset:3006 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:1 slave0:ip=127.0.0.1,port=6381,state=online,offset=3006,lag=1 master_failover_state:no-failover master_replid:69f484109a34847443d42cdcaa1aa176bbfeecad master_replid2:0000000000000000000000000000000000000000 master_repl_offset:3006 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2759 repl_backlog_histlen:248 127.0.0.1:6380> INFO replication # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:down #与主库的连接变为down,6381也一样 master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_read_repl_offset:4392 slave_repl_offset:4392 master_link_down_since_seconds:45 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:69f484109a34847443d42cdcaa1aa176bbfeecad master_replid2:0000000000000000000000000000000000000000 master_repl_offset:4392 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2759 repl_backlog_histlen:1634 127.0.0.1:6380> SLAVEOF no one #使当前数据库停止与其他数据库的同步,转成主数据库 OK 127.0.0.1:6380> INFO replication #6380由slave 变为 master # Replication role:master connected_slaves:0 master_failover_state:no-failover master_replid:220e415553b5effbd4da906181bb0fab3254edf0 master_replid2:69f484109a34847443d42cdcaa1aa176bbfeecad master_repl_offset:4392 second_repl_offset:4393 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2759 repl_backlog_histlen:1634 127.0.0.1:6380> set k80 v80 OK
-
slave(6381)
-
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379 OK 127.0.0.1:6381> Info replication # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_read_repl_offset:3314 slave_repl_offset:3314 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:69f484109a34847443d42cdcaa1aa176bbfeecad master_replid2:0000000000000000000000000000000000000000 master_repl_offset:3314 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2787 repl_backlog_histlen:528 127.0.0.1:6381> SLAVEOF 127.0.0.1 6380 #很显然 6381 要跟着新老大 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 #与6380的连接成功了,第一次先全量复制,后续在增量复制 master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_read_repl_offset:4392 slave_repl_offset:4392 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:220e415553b5effbd4da906181bb0fab3254edf0 master_replid2:69f484109a34847443d42cdcaa1aa176bbfeecad master_repl_offset:4392 second_repl_offset:4393 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2787 repl_backlog_histlen:1606 127.0.0.1:6381> get k80 "v80"
浅谈复制原理
- Slave启动成功连接到master后会发送一个sync命令
- Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
- 全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
- 增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步
- 但是只要是重新连接master,一次完全同步(全量复制)将被自动执行
哨兵模式(sentinel)
-
哨兵模式: 反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
-
大致步骤:
-
在redis.conf 所在的文件夹创建 sentinel.conf
-
在sentinel.conf 文件中写入:
- sentinel monitor host6379(被监控的主机(master)名字,自己定义) 127.0.0.1(是在本机做的实验) 6379(端口) 1(票数要大于1票,就是新master)
- sentinel monitor host6379 127.0.0.1 6379 1
-
启动哨兵: redis-sentinel 文件sentinel.conf路径
- 例子:redis-sentinel /zzyyuse/redis-6.2.7/Redis-con/sentinel.conf
-
-
master(6379)
-
127.0.0.1:6379> Info replication #环境一主(master)二仆(slave) # Replication role:master connected_slaves:2 slave0:ip=127.0.0.1,port=6380,state=online,offset=28156,lag=0 slave1:ip=127.0.0.1,port=6381,state=online,offset=28156,lag=0 master_failover_state:no-failover master_replid:99b0992e4bfdac6502aa6f105b456a6e2edaee1c master_replid2:0000000000000000000000000000000000000000 master_repl_offset:28289 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:28289 127.0.0.1:6379> SHUTDOWN #master6379 挂了 not connected> #当6379 从新回归时 127.0.0.1:6379> INFO replication #从master变为slave,数据与6380同步 # Replication role:slave master_host:127.0.0.1 master_port:6380 master_link_status:up master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_read_repl_offset:112463 slave_repl_offset:112463 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:ef6d02f3909871518439462fa831152ceea2ac48 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:112463 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:111762 repl_backlog_histlen:702 127.0.0.1:6379> keys * 1) "k1" 2) "k3" 3) "k2"
-
-
slave(6380)
-
127.0.0.1:6380> info replication #当master6379挂了时,一开始是down状态说明还没选出来master # Replication role: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_read_repl_offset:75071 slave_repl_offset:75071 master_link_down_since_seconds:13 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:4d6fe188fcf0e0569b24a1e559a13aeaa15e9db6 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:75071 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:62694 repl_backlog_histlen:12378 127.0.0.1:6380> info replication #选举完后的效果(新master) # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6381,state=online,offset=98698,lag=0 master_failover_state:no-failover master_replid:ef6d02f3909871518439462fa831152ceea2ac48 master_replid2:4d6fe188fcf0e0569b24a1e559a13aeaa15e9db6 master_repl_offset:98698 second_repl_offset:75072 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:62694 repl_backlog_histlen:36005 127.0.0.1:6380> keys * 1) "k2" 2) "k1" 127.0.0.1:6380> set k3 v3 OK 127.0.0.1:6380> keys * #数据还在也可以从新写入,因为现在6380是master 1) "k3" 2) "k2" 3) "k1" 127.0.0.1:6380> info replication #当6379恢复时,6380从一个小弟变为两个小弟 # Replication role:master connected_slaves:2 slave0:ip=127.0.0.1,port=6381,state=online,offset=134856,lag=0 slave1:ip=127.0.0.1,port=6379,state=online,offset=134723,lag=0 master_failover_state:no-failover master_replid:ef6d02f3909871518439462fa831152ceea2ac48 master_replid2:4d6fe188fcf0e0569b24a1e559a13aeaa15e9db6 master_repl_offset:134856 second_repl_offset:75072 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:62694 repl_backlog_histlen:72163 127.0.0.1:6380>
-
-
slave(6381)
-
127.0.0.1:6381> info replication # Replication role: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_read_repl_offset:75071 slave_repl_offset:75071 master_link_down_since_seconds:30 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:4d6fe188fcf0e0569b24a1e559a13aeaa15e9db6 master_replid2:fa856dcf09927d13529529cb87705af42d22c917 master_repl_offset:75071 second_repl_offset:52353 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:75071 127.0.0.1:6381> info replication #可以看出6381还是slave,单已经跟着6380混了 # Replication role:slave master_host:127.0.0.1 master_port:6380 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_read_repl_offset:102093 slave_repl_offset:102093 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:ef6d02f3909871518439462fa831152ceea2ac48 master_replid2:4d6fe188fcf0e0569b24a1e559a13aeaa15e9db6 master_repl_offset:102093 second_repl_offset:75072 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:102093
-
由图片可知选举成功(新master->6380)
-
-
-
-
复制的缺点:(复制延迟)由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Masterl同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更严重,Slave机器数量的增加也会是这个问题更加严重
Redis基础以五大常用数据类型-传送门==/==