首页 > 学院 > 开发设计 > 正文

Redis的复制Master-Slave

2019-11-06 06:54:50
字体:
来源:转载
供稿:网友

Redis 的复制 Master/Slave

一、是什么

行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主

二、能干嘛

读写分离容灾恢复

三、怎么玩

3.1、配从(库)不配主(库)

3.2、从库配置

命令:

slaveof 主库 ip 主库端口

每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件

info replication

3.3、修改配置文件细节操作

拷贝多个 redis.conf 文件开启 daemonize yesPid 文件名字指定端口Log 文件名字Dump.rdb 名字

redis6379.conf

daemonize yespidfile /var/run/redis6379.pidPRot 6379logfile "6379.log"dbfilename dump6379.rdb

redis6380.conf

daemonize yespidfile /var/run/redis6380.pidprot 6380logfile "6380.log"dbfilename dump6380.rdb

redis6381.conf

daemonize yespidfile /var/run/redis6381.pidprot 6381logfile "6381.log"dbfilename dump6381.rdb

3.4、常用3招

3.4.1、 一主二仆

窗口 A

$ redis-server redis6379.conf $ redis-cli -p 6379127.0.0.1:6379> pingPONG

窗口 B

$ redis-server redis6380.conf $ redis-cli -p 6380127.0.0.1:6380> pingPONG

窗口 C

$ redis-server redis6381.conf $ redis-cli -p 6381127.0.0.1:6381> pingPONG

窗口 A

127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0127.0.0.1:6379> set k1 v1OK127.0.0.1:6379> set k2 v2OK127.0.0.1:6379> set k3 v3OK127.0.0.1:6379> keys *1) "k1"2) "k2"3) "k3"

窗口 B

127.0.0.1:6380> SLAVEOF 127.0.0.1 6379OK127.0.0.1:6380> get k3"v3"

窗口 C

127.0.0.1:6381> SLAVEOF 127.0.0.1 6379OK127.0.0.1:6381> get k3"v3"

6380、6381 slaveof 之后

窗口 A

127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:2slave0:ip=127.0.0.1,port=6380,state=online,offset=337,lag=1slave1:ip=127.0.0.1,port=6381,state=online,offset=337,lag=1master_repl_offset:337repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:336

窗口 B

127.0.0.1:6380> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6379master_link_status:upmaster_last_io_seconds_ago:8master_sync_in_progress:0slave_repl_offset:449slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0

窗口 C

127.0.0.1:6381> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6379master_link_status:upmaster_last_io_seconds_ago:2master_sync_in_progress:0slave_repl_offset:505slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0

窗口 A

127.0.0.1:6379> set k5 v5OK

窗口 B 直接备份了

127.0.0.1:6380> get k5"v5"

窗口 C 直接备份了

127.0.0.1:6381> get k5"v5"

窗口 A

127.0.0.1:6379> set k6 v6OK

窗口 B

127.0.0.1:6380> set k6 v66(error) READONLY You can't write against a read only slave.

窗口 C

127.0.0.1:6381> set k6 v666(error) READONLY You can't write against a read only slave.

当主机 A 宕了,主机 B,主机 C 会不会上位

窗口 A

127.0.0.1:6379> SHUTDOWNnot connected> exit

窗口 B , 角色还是 slave,连接状态是 down

127.0.0.1:6380> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6379master_link_status:downmaster_last_io_seconds_ago:-1master_sync_in_progress:0slave_repl_offset:1230master_link_down_since_seconds:48slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0127.0.0.1:6380>

窗口 C ,角色还是 slave,连接状态是 down

127.0.0.1:6381> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6379master_link_status:downmaster_last_io_seconds_ago:-1master_sync_in_progress:0slave_repl_offset:1230master_link_down_since_seconds:118slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0

当主机 A 又上线了,从机依旧

窗口 A

$ redis-server redis6379.conf $ redis-cli -p 6379127.0.0.1:6379> pingPONG127.0.0.1:6379> set k7 v7OK

窗口 B

127.0.0.1:6380> get k7"v7"

窗口 C

127.0.0.1:6381> get k7"v7"

当从机死了

窗口 B

127.0.0.1:6380> SHUTDOWNnot connected> exit

窗口 A

127.0.0.1:6379> set k8 v8OK127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:1slave0:ip=127.0.0.1,port=6381,state=online,offset=348,lag=1master_repl_offset:348repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:347

窗口 C

127.0.0.1:6381> get k8"v8"

重新启动 B

$ redis-server redis6380.conf $ redis-cli -p 6380127.0.0.1:6380> pingPONG127.0.0.1:6380> info replication# Replicationrole:masterconnected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0127.0.0.1:6380> get k8(nil)

每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件

重新连接 B

窗口 B

127.0.0.1:6380> SLAVEOF 127.0.0.1 6379OK127.0.0.1:6380> get k8"v8"

3.4.2、 薪火相传

上一个Slave可以是下一个slave的Master,Slave同样可以接收其他 slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力中途变更转向:会清除之前的数据,重新建立拷贝最新的slaveof 新主库IP 新主库端口

窗口 C

127.0.0.1:6381> SLAVEOF 127.0.01 6380OK

窗口 A

127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:1slave0:ip=127.0.0.1,port=6380,state=online,offset=1370,lag=0master_repl_offset:1370repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:1369127.0.0.1:6379> set k9(error) ERR wrong number of arguments for 'set' command127.0.0.1:6379> set k9 v9OK

窗口 B

127.0.0.1:6380> get k9"v9"

窗口 C

127.0.0.1:6381> get k9"v9"

窗口 B , 角色还是 slave , 连接了一个 slave

127.0.0.1:6380> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6379master_link_status:upmaster_last_io_seconds_ago:3master_sync_in_progress:0slave_repl_offset:1384slave_priority:100slave_read_only:1connected_slaves:1slave0:ip=127.0.0.1,port=6381,state=online,offset=29,lag=0master_repl_offset:29repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:28

3.4.3、 反客为主

命令

SLAVEOF no one

使当前数据库停止与其他数据库的同步,转为主数据库

窗口 C (恢复一主二从)

127.0.0.1:6381> SLAVEOF 127.0.01 6379OK

窗口 A

127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:2slave0:ip=127.0.0.1,port=6381,state=online,offset=2206,lag=0slave1:ip=127.0.0.1,port=6380,state=online,offset=2206,lag=0master_repl_offset:2206repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:2205

窗口 B

127.0.0.1:6380> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6379master_link_status:upmaster_last_io_seconds_ago:10master_sync_in_progress:0slave_repl_offset:2206slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:865repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:864

窗口 C

127.0.0.1:6381> info replication# Replicationrole:slavemaster_host:127.0.01master_port:6379master_link_status:upmaster_last_io_seconds_ago:5master_sync_in_progress:0slave_repl_offset:2220slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0

当主机 A 宕了

窗口 A

127.0.0.1:6379> SHUTDOWNnot connected> exit

窗口 B

127.0.0.1:6380> info replication# Replicationrole:masterconnected_slaves:0master_repl_offset:1131repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:1130

窗口 C

127.0.0.1:6381> info replication# Replicationrole:slavemaster_host:127.0.01master_port:6379master_link_status:downmaster_last_io_seconds_ago:-1master_sync_in_progress:0slave_repl_offset:2332master_link_down_since_seconds:154slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0127.0.0.1:6381> SLAVEOF 127.0.0.1 6380OK127.0.0.1:6381> get k10"v10"

当 主机 A 重新上线

$ redis-server redis6379.conf $ redis-cli -p 6379127.0.0.1:6379> pingPONG127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0

四、复制原理

slave启动成功连接到master后会发送一个sync命令Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令, 在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

五、哨兵模式 (sentinel)

5.1、是什么

反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库

5.2、怎么玩

调整结构,6379带着80、81自定义的/myredis目录下新建sentinel.conf文件,名字绝不能错配置哨兵,填写内容 sentinel monitor 被监控数据库名字(自己起名字) 127.0.0.1 6379 1上面最后一个数字1,表示主机挂掉后 salve 投票看让谁接替成为主机,得票数多少后成为主机启动哨兵 redis-sentinel /myredis/sentinel.conf 上述目录依照各自的实际情况配置,可能目录不同正常主从演示原有的master挂了投票新选重新主从继续开工,info replication查查看问题:如果之前的master重启回来,会不会双master冲突?

窗口 B 恢复一主二从

127.0.0.1:6380> SLAVEOF 127.0.0.1 6379OK

窗口 C

127.0.0.1:6381> SLAVEOF 127.0.0.1 6379OK

窗口 A

127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:2slave0:ip=127.0.0.1,port=6380,state=online,offset=141,lag=0slave1:ip=127.0.0.1,port=6381,state=online,offset=141,lag=1master_repl_offset:141repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:140

sentinel.conf

sentinel monitor host6379 127.0.0.1 6379 1

窗口 D ,开启哨兵巡逻

$ redis-sentinel sentinel.conf 9133:X 03 Mar 11:17:50.266 * Increased maximum number of open files to 10032 (it was originally set to 256). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.2.6 (00000000/0) 64 bit .-`` .-```. ```// _.,_ ''-._ ( ' , .-` | `, ) Running in sentinel mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 26379 | `-._ `._ / _.-' | PID: 19133 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 19133:X 03 Mar 11:17:50.268 # Sentinel ID is a102738f97ae0492bf807bd262553bc011a19e6c19133:X 03 Mar 11:17:50.268 # +monitor master host6379 127.0.0.1 6379 quorum 119133:X 03 Mar 11:17:50.269 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 637919133:X 03 Mar 11:17:50.269 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6379

主机 A 宕了

窗口 A

127.0.0.1:6379> SHUTDOWNnot connected> exit

窗口 D ,哨兵投票选取新主机

19133:X 03 Mar 11:20:37.775 # +sdown master host6379 127.0.0.1 637919133:X 03 Mar 11:20:37.775 # +odown master host6379 127.0.0.1 6379 #quorum 1/119133:X 03 Mar 11:20:37.775 # +new-epoch 119133:X 03 Mar 11:20:37.775 # +try-failover master host6379 127.0.0.1 637919133:X 03 Mar 11:20:37.777 # +vote-for-leader a102738f97ae0492bf807bd262553bc011a19e6c 119133:X 03 Mar 11:20:37.777 # +elected-leader master host6379 127.0.0.1 637919133:X 03 Mar 11:20:37.777 # +failover-state-select-slave master host6379 127.0.0.1 637919133:X 03 Mar 11:20:37.853 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 637919133:X 03 Mar 11:20:37.853 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 637919133:X 03 Mar 11:20:37.932 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 637919133:X 03 Mar 11:20:38.900 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 637919133:X 03 Mar 11:20:38.900 # +failover-state-reconf-slaves master host6379 127.0.0.1 637919133:X 03 Mar 11:20:38.955 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 637919133:X 03 Mar 11:20:39.923 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 637919133:X 03 Mar 11:20:39.923 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 637919133:X 03 Mar 11:20:39.980 # +failover-end master host6379 127.0.0.1 637919133:X 03 Mar 11:20:39.980 # +switch-master host6379 127.0.0.1 6379 127.0.0.1 638019133:X 03 Mar 11:20:39.981 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 638019133:X 03 Mar 11:20:39.981 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ host6379 127.0.0.1 6380

窗口 B

127.0.0.1:6380> info replication# Replicationrole:masterconnected_slaves:1slave0:ip=127.0.0.1,port=6381,state=online,offset=26333,lag=1master_repl_offset:26333repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:26332127.0.0.1:6380>

窗口 C

127.0.0.1:6381> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6380master_link_status:upmaster_last_io_seconds_ago:0master_sync_in_progress:0slave_repl_offset:27705slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0

窗口 B

127.0.0.1:6380> set k10 v10OK

窗口 C

127.0.0.1:6381> get k10"v10"

当主机 A 重新上线,哨兵监控到后,老领导变成从机了

$ redis-server redis6379.conf $ redis-cli -p 6379127.0.0.1:6379> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6380master_link_status:upmaster_last_io_seconds_ago:0master_sync_in_progress:0slave_repl_offset:40793slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0

窗口 B

127.0.0.1:6380> info replication# Replicationrole:masterconnected_slaves:2slave0:ip=127.0.0.1,port=6381,state=online,offset=45413,lag=0slave1:ip=127.0.0.1,port=6379,state=online,offset=45413,lag=0master_repl_offset:45413repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:45412

5.3、一组 sentinel 能同时监控多个 Master

六、复制的缺点

复制延迟

由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表