目录
一、redis复制介绍
Redis目前的复制是异步的,只保证最终一致性,而不是强一致性(主从数据库的更新还是分先后,先主后从)。要是一致性要求高的应用,目前还是读写都在主库上去。从当做一个备份机
redis主从配置比较简单,基本就是在从节点配置文件加上
slaveof 192.168.33.130 6379
二、redis主从复制实现的原理
- 主要是通过master server持久化的rdb文件实现
- master server 先dump出内存快照文件,然后将rdb文件传给slave server
- slave server 根据rdb文件重建内存表。
三、redis主从复制的特点
- master 可以有多个 slave
- 除了多个 slave 连到相同的 master 外, slave 也可以连接其他 slave 形成图状结构
- 主从复制不会阻塞 master。也就是说当一个或多个 slave 与 master 进行初次同步数据时, master 可以继续处理 client 发来的请求。相反 slave 在初次同步数据时则会阻塞不能处理 client 的请求。
- 主从复制可以用来提高系统的可伸缩性,我们可以用多个 slave 专门用于 client 的读请求,比如 sort 操作可以使用 slave 来 处理。也可以用来做简单的数据冗余
- 可以在 master 禁用数据持久化,只需要注释掉 master 配置文件中的所有 save 配置,然后只在 slave 上配置数据持久化。
四、redis搭建和复制原理
1)原理:
①从数据库向主数据库发送sync命令。
②主数据库接收sync命令后,判断,是否有正在进行内存快照的子进程,如果有,则等待其结束,否则,fork一个子进程,执行BGSAVE命令(保存快照),创建一个RDB文件,在创建RDB文件期间的命令将保存在缓冲区中。
③当主数据库执行完BGSAVE时,会向从数据库发送RDB文件,而从数据库会接收并载入该文件。
④主数据库将缓冲区的所有写命令发给从服务器执行。
⑤以上处理完之后,之后主数据库每执行一个写命令,都会将被执行的写命令发送给从数据库。
注意:在Redis2.8之前,主从断线或则重启之后再重连接,都需要做一次完整的sync操作(5步骤),即使断线期间只有几条的更新操作或则是没有操作,导致系统资源极度浪费。不能和mysql一样实现增量备份。
Redis2.8之后,会用一个psync来替换sync,不会进行完成的sync操作,只需要同步断线期间的记录。相关参数:repl-backlog-size、repl-backlog-ttl
大致的示意图如下:
2)搭建
复制的配置很简单,就一个参数:
slaveof <主数据库IP> <端口>
可以添加在配置文件里,也可以在命令行中执行。
如主数据库IP是192.168.200.25 端口是6379:(配置多台从数据库的方法也一样)
slaveof 192.168.200.25 6379
注意:通过命令行进行的复制,在主从断开或则主从重启之后复制信息会丢失,即不能保证持久复制,需要再次执行slaveof。但是在配置文件里写死slaveof不会有该问题。
默认情况下从库是只读的,不能进行修改,需要修改需要设置配置文件中的slave-read-only为no。在命令行里执行slaveof no one可以让一个从库变成主库。
3. 相关的参数,注释掉的参数都是使用默认值。
################################# REPLICATION #################################
#复制选项,slave复制对应的master。
#slaveof <masterip> <masterport>
slaveof 192.168.200.25 6379
#如果master设置了requirepass,那么slave要连上master,需要有master的密码才行。masterauth就是用来配置master的密码,这样可以在连上master后进行认证。
# masterauth <master-password>
#当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:
#1) 如果slave-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的请求。
#2) 如果slave-serve-stale-data设置为no,除去INFO和SLAVOF命令之外的任何请求都会返回一个错误”SYNC with master in progress”。
slave-serve-stale-data yes
#作为从服务器,默认情况下是只读的(yes),可以修改成NO,用于写(不建议)。
slave-read-only yes
#是否使用socket方式复制数据。
#目前redis复制提供两种方式,disk和socket。
#如果新的slave连上来或者重连的slave无法部分同步,就会执行全量同步,master会生成rdb文件。
#有2种方式:disk方式是master创建一个新的进程把rdb文件保存到磁盘,再把磁盘上的rdb文件传递给slave。
#socket是master创建一个新的进程,直接把rdb文件以socket的方式发给slave。
#disk方式的时候,当一个rdb保存的过程中,多个slave都能共享这个rdb文件。
#socket的方式就的一个个slave顺序复制。在磁盘速度缓慢,网速快的情况下推荐用socket方式。
repl-diskless-sync no
#diskless复制的延迟时间,防止设置为0。一旦复制开始,节点不会再接收新slave的复制请求直到下一个rdb传输。
#所以最好等待一段时间,等更多的slave连上来。
repl-diskless-sync-delay 5
#slave根据指定的时间间隔向服务器发送ping请求。时间间隔可以通过 repl_ping_slave_period 来设置,默认10秒。
# repl-ping-slave-period 10
#复制连接超时时间。master和slave都有超时时间的设置。master检测到slave上次发送的时间超过repl-timeout,即认为slave离线,清除该slave信息。slave检测到上次和master交互的时间超过repl-timeout,则认为master离线。需要注意的是repl-timeout需要设置一个比repl-ping-slave-period更大的值,不然会经常检测到超时。
# repl-timeout 60
#是否禁止复制tcp链接的tcp nodelay参数,可传递yes或者no。默认是no,即使用tcp nodelay。如果master设置了yes来禁止tcp nodelay设置,在把数据复制给slave的时候,会减少包的数量和更小的网络带宽。但是这也可能带来数据的延迟。默认我们推荐更小的延迟,但是在数据量传输很大的场景下,建议选择yes。
repl-disable-tcp-nodelay no
#复制缓冲区大小,这是一个环形复制缓冲区,用来保存最新复制的命令。这样在slave离线的时候,不需要完全复制master的数据,如果可以执行部分同步,只需要把缓冲区的部分数据复制给slave,就能恢复正常复制状态。缓冲区的大小越大,slave离线的时间可以更长,复制缓冲区只有在有slave连接的时候才分配内存。没有slave的一段时间,内存会被释放出来,默认1m。
# repl-backlog-size 5mb
#master没有slave一段时间会释放复制缓冲区的内存,repl-backlog-ttl用来设置该时间长度。单位为秒。
# repl-backlog-ttl 3600
#当master不可用,Sentinel会根据slave的优先级选举一个master。最低的优先级的slave,当选master。而配置成0,永远不会被选举。
slave-priority 100
#redis提供了可以让master停止写入的方式,如果配置了min-slaves-to-write,健康的slave的个数小于N,mater就禁止写入。master最少得有多少个健康的slave存活才能执行写命令。这个配置虽然不能保证N个slave都一定能接收到master的写操作,但是能避免没有足够健康的slave的时候,master不能写入来避免数据丢失。设置为0是关闭该功能。
# min-slaves-to-write 3
#延迟小于min-slaves-max-lag秒的slave才认为是健康的slave。
# min-slaves-max-lag 10
五、主从没反应解决
描述:
slave : 192.168.160.140
master : 192.168.160.141
- 在slave中设置了slaveof 192.168.160.141 6379
- 启动slave但是,连接slave的服务端,发现数据并没有复制过来
解决:
在master将
bind 127.0.0.1
改为
bind 0.0.0.0
重启启动master