Redis 3.0官方文档翻译计划(10)
——复制
Redis的复制(replication)是一种使用和配置起来非常简单的主从(master-slave)复制,允许Redis从服务器成为主服务器的精确副本。以下是关于Redis复制的一些重要方面:
- Redis采用异步复制。从Redis 2.8开始,从服务器会周期性地报告从复制流中处理的数据量。
- 一个主服务器可以拥有多个从服务器。
- 从服务器可以接受其他从服务器的连接。除了连接多个从服务器到同一个主服务器,从服务器也可以连接到其他的从服务器,形成图状结构。
- Redis的复制在主服务器上是非阻塞的。这意味着,当一个或多个从服务器执行初始化同步(initial synchronization)时,主服务器能继续处理请求。
- Redis的复制在从服务器上也是非阻塞的。当从服务器正在执行初始化同步时,假如你在redis.conf中进行了相应配置,也能够继续使用旧版本的数据集处理请求。另外,你还可以配置当复制流宕(dowm)掉的时候,从服务器返回给客户端一个错误。然而,初始化同步结束后,旧的数据集需要被删除,新的数据集需要被载入。在这个简短的窗口期内,从服务器会阻塞到来的连接。
- 复制可以用来支持可伸缩性,用多个从服务器处理只读查询(例如,繁重的SORT操作可以分配到从服务器上),也可以仅仅作为数据冗余。
- 可以使用复制来避免主服务器将全部数据集写到磁盘的开销:只需要配置你的主服务器的redis.conf来防止保存(所有的”保存”指令),然后连接一个不断复制的从服务器。
Redis复制如何工作(How works)
当你建立一个从服务器,连接时就会发送一个SYNC命令。不管是第一次连接上还是重连接上。
然后主服务器开始在后台保存,并且开始缓冲所有新收到的会修改数据集的命令。当后台保存完成以后,主服务器传输数据库文件给从服务器,从服务器将其保存到磁盘上,然后加载到
内存中。然后主服务器开始发送缓冲的命令给从服务器。这是通过命令流完成的,和Redis的
协议是一样的格式。
你可以用telnet试试。连上一台正在工作的Redis的端口,然后发送SYNC命令。你会看到大量的传输,还有主服务器收到的每条命令被重新发送给了telnet会话。
当主从链路由于某些原因断开时,从服务器可以自动重连。如果主服务器收到多个并发的从服务器的同步请求,只会执行一个后台保存来服务所有从服务器。
当主服务器和从服务器断开后重连上,总是执行一次完整重同步(full resynchronization)。然而,从Redis 2.8以后,可以选择执行部分重同步(partial resynchronization)。
部分重同步(partial resynchronization)
从Redis 2.8开始,在复制链接断开后,主服务器和从服务器通常可以继续复制过程,而不需要一次完整的重同步。
这是通过在主服务器上创建一个复制流的内存缓冲区(in-memory backlog)实现的。主服务器和所有从服务器都记录一个复制偏移量(offset)和一个主服务器运行ID(run id),当链接断掉时,从服务器会重连接,并且请求主服务器继续复制。假设主服务器的运行ID还是一样的,并且指定的偏移量在复制缓冲区中可用,复制会从中断的点继续。如果这两个条件之一不满足,将会执行完整重同步(2.8版之前的正常行为)。
新的部分重同步特性使用的是内部PSYNC命令,老的实现采用的是SYNC命令。注意,Redis 2.8的从服务器可以检测主服务器是否不支持PSYNC,然后使用SYNC代替。
配置(Configuration)
配置复制简直小菜一碟:只需要添加下面一行到从服务器配置文件:
class="java">slaveof 192.168.1.1 6379
当然,你得把192.168.1.1 6379替换成你自己的主服务器IP地址(或主机名)和端口。或者,你可以调用SLAVEOF命令和主服务器主机,开始与从服务器的一次同步。
有很多参数可以用来调整执行部分重同步主服务器的上的内存复制缓冲区。可以看看Redis发布版本中自带的样例文件redis.conf以获取更多的信息。
只读从服务器(Read-only slave)
从Redis 2.6开始,从服务器支持默认
开启的只读模式。这个行为由redis.conf文件中的slave-read-only选项控制,可以在运行时使用CONFIG SET来开启和关闭。
只读从服务器会拒绝所有写命令,所以写入数据到从服务器只会引起错误。这并不意味着,这个特性
打算暴露从服务器实例到互联网,或者到网络中不信任的客户端,因为诸如DEBUG和CONFIG这样的管理命令等仍可用。但是,可以通过在redis.conf中使用rename-
command指令来禁止命令,从而改进只读实例的
安全性。
你可能很好奇,为什么需要能够反转只读设置,使得从服务器实例能够成为写操作的目标。尽管这些写入的数据会在从服务器和主服务器重同步时,或者从服务器
重启时被丢弃,还是有一些存储一些短暂的数据到可写的从服务器的
合理场景。例如,客户端可以存储一些主服务器的可达性信息来调整故障转移(failover)策略。
认证主服务器(Authenticate to a master)
如果你的主服务器通过requirepass而有一个密码,很容易配置从服务器在所有同步操作中使用这个密码。
要做到这个,在一个运行的实例上,使用redis-cli并键入:
config set masterauth <password>
要永久设置这个,添加这个倒你的配置文件中:
masterauth <password>
N个副本才能写(Allow writes only with N attached replicas)
从Redis 2.8开始,可以设置Redis主服务器在当前至少拥有N个从服务器的连接的情况下,才能接受写请求。
然而,由于Redis使用异步复制,不能保证从服务器真正收到了一个给定的写请求,于是总是有一个数据丢失的窗口期。
下面是这个特性是如何
运作的:
- Redis从服务器每秒种ping主服务器,上报处理完的复制流的数据量。
- Redis主服务器记录上一次从每一个从服务收到ping的时间。
- 用户可以配置最小从服务器数量,每台从服务器拥有一个不大于最大秒数的滞后(lag)。
如果有至少N个小于M秒滞后的从服务器,写请求才会被接受。
你可能会认为这个像CAP理论中较宽松版本的”C”,不能保证指定写的一致性,但是至少数据丢失的时间窗口被
限制在一个指定的秒数内。
如果条件不满足,主服务器会返回一个错误,并且不会接受写请求。
这个特性有两个配置参数:
min-slaves-to-write <number of slaves>
min-slaves-max-lag <number of seconds>
请查看随Redis源码发布版本自带的redis.conf文件获取更多信息。
===============================================================================
大家好,我是阮威。华中科技大学,计算机软件专业硕士。
毕业后加入腾讯,先后在腾讯电子商务部和无线游戏产品部工作,现供职于欢聚时代基础产品部。IT男,至今。欢迎大家收听我的公众账号。