本专栏与Redis相关的文章redis
Redis Sentinel机制与用法(一)
Redis Sentinel机制与用法(二)
Jedis的JedisSentinelPool源代码分析
Jedis的Sharded源代码分析
Redis 主从 Replication 的配置
详解Redis SORT命令
JedisCommand接口说明segmentfault
本文参考翻译自 《Redis Replication documentation》
Redis的replication机制容许slave从master那里经过网络传输拷贝到完整的数据备份。具备如下特色:缓存
当有须要使用到replication机制时,通常都会强烈建议把master的持久化开关打开。即便为了不持久化带来的延迟影响,不把持久化开关打开,那么也应该把master配置为不会自动启动的。安全
为了更好地理解当一个不进行持久化的master若是容许自动启动所带来的危险性。能够看看下面这种失败情形:微信
假设咱们有一个redis节点A,设置为master,而且关闭持久化功能,另外两个节点B和C是它的slave,并从A复制数据。
若是A节点崩溃了致使全部的数据都丢失了,它会有重启系统来重启进程。可是因为持久化功能被关闭了,因此即便它重启了,它的数据集是空的。
而B和C依然会经过replication机制从A复制数据,因此B和C会从A那里复制到一份空的数据集,并用这份空的数据集将本身自己的非空的数据集替换掉。因而就至关于丢失了全部的数据。
即便使用一些HA工具,好比说sentinel来监控master-slaves集群,也会发生上述的情形,由于master可能崩溃后迅速恢复。速度太快而致使sentinel没法察觉到一个failure的发生。网络
当数据的安全很重要、持久化开关被关闭而且有replication发生的时候,那么应该禁止实例的自启动。架构
若是你为master配置了一个slave,无论这个slave是不是第一次链接上Master,它都会发送一个SYNC
命令给master请求复制数据。并发
master收到SYNC
命令后,会在后台进行数据持久化,持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完毕之后,master会把这份数据集发送给slave,slave会把接收到的数据进行持久化,而后再加载到内存中。而后,master再将以前缓存在内存中的命令发送给slave。less
当master与slave之间的链接因为某些缘由而断开时,slave可以自动重连Master,若是master收到了多个slave并发链接请求,它只会进行一次持久化,而不是一个链接一次,而后再把这一份持久化的数据发送给多个并发链接的slave。异步
当master和slave断开重连后,通常都会对整份数据进行复制。但从redis2.8版本开始,支持部分复制。
从2.8版本开始,slave与master可以在网络链接断开重连后只进行部分数据复制。
master会在其内存中建立一个复制流的等待队列,master和它全部的slave都维护了复制的数据下标和master的进程id,所以,当网络链接断开后,slave会请求master继续进行未完成的复制,从所记录的数据下标开始。若是进程id变化了,或者数据下标不可用,那么将会进行一次所有数据的复制。
支持部分数据复制的命令是PSYNC
通常状况下,一次复制须要将内存的数据写到硬盘中,再将数据从硬盘读进内存,再发送给slave。
对于速度比较慢的硬盘,这个操做会给master带来性能上的损失。Redis2.8版本开始,实验性地加上了无硬盘复制的功能。这个功能能将数据从内存中直接发送到slave,而不用通过硬盘的存储。
不过这个功能目前处于实验阶段,还未正式发布。
与replication相关的配置比较简单,只须要把下面一行加到slave的配置文件中:
slaveof 192.168.1.1 6379
你只须要把ip地址和端口号改一下。固然,你也能够经过客户端发送SLAVEOF
命令给slave。
部分数据复制有一些可调的配置参数,请参考redis.conf文件。
无硬盘复制功能能够经过repl-diskless-sync
来配置,另一个配置项repl-diskless-sync-delay
用来配置当收到第一个请求时,等待多个slave一块儿来请求之间的间隔时间。
从redis2.6版本开始,slave支持只读模式,并且是默认的。能够经过配置项slave-read-only
来进行配置,而且支持客户端使用CONFIG SET
命令来动态修改配置。
只读的slave会拒绝全部的写请求,只读的slave并非为了防范不可信的客户端,毕竟一些管理命令例如DEBUG
和CONFIG
在只读模式下仍是可使用的。若是确实要确保安全性,那么能够在配置文件中将一些命令从新命名。
也许你会感到很奇怪,为何可以将一个只读模式的slave恢复为可写的呢,尽管可写,可是只要slave一同步master的数据,就会丢失那些写在slave的数据。不过仍是有一些合法的应用场景须要存储瞬时数据会用到这个特性。不过,以后可能会考虑废除掉这个特性。
Setting a slave to authenticate to a master
若是master经过requirepass
配置项设置了密码,slave每次同步操做都须要验证密码,能够经过在slave的配置文件中添加如下配置项:
masterauth <password>
也能够经过客户端在运行时发送如下命令:
config set masterauth <password>
从redis2.8版本开始,master能够被配置为,只有当master当前有至少N个slave链接着的时候才接受写数据的请求。
然而,因为redis是异步复制的,因此它并不能保证slave会受到一个写请求,因此总有一个数据丢失的时间窗口存在。
这个机制的工做原理以下所示:
若是master有至少N个slave,而且ping心跳的超时不超过M秒,那么它就会接收写请求。
也许你会认为这情形好似CAP理论中弱化版的C(consistency),由于写请求并不能保证数据的一致性,但这样作,至少数据丢失被限制在了限定的时间内。即M秒。
若是N和M的条件都没法达到,那么master会回复一个错误信息。写请求也不会被处理。
有两个配置项用来配置上文中提到的N和M:
min-slaves-to-write <number of slaves> min-slaves-max-lag <number of seconds>
若是须要了解更多,请查阅redis.conf配置文件。