Replication 复制
:
Redis 复制的基础是一个非常简单来使用和配置master-slave 复制, 允许slave Redis 服务器可以准确的拷贝master servers.
slave 会自动的重新连接到master 每当连接断开时,
会尝试成为它的确切副本 不管master发生了什么
这个系统使用下面3个主要机构:
1.当一个master 和一个slave 实例是很好连接的,
master 保持slave 被更新通过发送命令流为了复制数据发生的影响在master 数据库
2.当master和slave之间的连接断开, 对于网络问题或者因为一个超时是被感觉到在master 或者slave,
slave 重新连接尝试处理部分同步:
这意味着 它会尝试得到命令流的部分 它在断开期间丢失部分
3.当一个部分重新同步是不可能的,slave会要求一个完整重新同步。
这是涉及一个更加复杂的过程 master 需要创建一个所有它的数据的快照,发送到slave,
继续发送命令流作为数据改变。
Redis 默认使用异步复制,这个是高延迟和高性能的,
是自然的复制模式对于大量的多数Redis 使用案例。
然而Redis slaves 异步的收到大量的数据从master 接收。
某些数据同步复制可以通过客户端请求使用WAIT 命令。
然而WAIT 只是确保,有指定的接收到的副本数量在另外的Redis 实例:
写仍旧会丢失在一个failover 对于不同的实例在一个failover 或者依赖
Redis 保留的配置。
下面是一些非常重要的因素关于Redis 复制:
1.Redis 使用异步复制,使用异步slave-to-master 接收数据的处理
2.一个master 可以有多个slaves:
3.Slaves 是可以接收其他slaves的连接,除了连接大量的slaves 到相同的master,
slave也可以连接到其他slave 在一个级联结构。
Redis 复制是非堵塞的在master端。
这个意味着master 会继续处理请求当一个或者多个slave执行初始同步或者一个部分重新同步
复制也是大部分非堵塞的在slave上,当slave是执行初始化同步,
它可以处理请求使用数据集的老版本,假设你配置Redis 在Redis.conf里。
否则,你可以配置Redis slaves 来返回一个错误给客户端如果复制stream is down.
然而, 在初始化之后,老的数据集必须被删除 新的必须被加载。
slave 会堵塞进来的连接在这个短暂的窗口(对于非常大的数据集来说,这可能是很多秒的事情).
复制可以用于扩展性,为了有多个slave 用于只读查询(比如,慢的操作可以被放到slaves上),或者仅仅为了数据安全。
它是可以的使用复制来避免maater 写完整的数据到磁盘的成本:
一个典型的技术表明配置你的master redis.conf 来避免所有持久到磁盘,
连接到一个slave 配置来节省时间,或者 启用AOF 。
但是,必须小心的处理这个设置,因为一个重启的master 会启动一个空的数据集:
如果slave尝试同步它, slave也会被清空。
复制的安全性当master 持久性关闭:
在设置 Redis 复制是被使用,它是强烈建议启用持久化在master和slave上。
当这是不可能的,例如 因为延迟问题由于很慢的磁盘,实例应该被配置避免在一个机器重启后自动重启
为了更好的理解为什么master 在持久化关闭配置为自动启动是危险的,
检查下面的failure 模式 当数据是从master或者所有它的slave中清除:
1.我们有一个配置node A 作为一个master,关闭持久化down,nodes B和C 从node A复制
2. Node A 崩溃,然而 它有自动重启,重启进程。
然而因为持久化是关闭的,节点重启使用一个空的数据集
3.节点B和C 会从节点A 中复制,它是空的,因此它们会有效的销毁数据的副本
当Redis 是用于高可用,在master上关闭持久化,使用进程自动重启,是危险的。
例如 master可以足够快的重启对于Sentinel 没有检测到failure,
因此failure mode 描述上面的发生:
数据安全是重要的, 复制是用于master 配置为不持久化,自动重启应该被关闭
How Redis replication works Redis 复制如何工作:
每一个Redis master 有一个复制ID: 它是一个大的随机字符串
标记一个给定的数据集。
每个master 采取一个偏移量 ,增量用于复制stream的每个字节 它是被产生用于发送到slaves,
Replication ID, offset
标识 是一个master的精确版本:
当slaves连接到master,它们使用PSYNC 命令为了发送它们老的master 复制ID
和它们处理的偏移量。
这种方式master可以发送只是需要的增量部分。
然而 如果没有足够的backlog在master的buffers,
或者如果slave是针对一个history(replication ID),已经不知道了,
然后一个全重新同步发生:
在这种情况下 slave 会得到一个完整的数据集的完整copy:
这就是一个完整同步在更多细节的地方:
master 开始启动后台进程为了产生一个RDB文件。
在同时,它开始buffer 所有新的写的命令从clients接收的,保存到磁盘,
然后加载它到内存里。
master 然后发送所有缓存的命令到slave,这是作为一个命令的流,是和redis协议本身一样
你可以自己尝试通过telnet,连接到Redis 端口当server 是做同样的工作,执行SYNC命令。
你可以看到一个批量传输和然后每个命令从master接收会重新执行在telnet session.
实际上SYNC 是一个老的协议 不在被新的Redis 实例使用,但是仍旧为了向后兼容性。
它不允许部分同步,现在PSYNC来代替
node2:/root#telnet 192.168.137.2 6379
Trying 192.168.137.2...
Connected to 192.168.137.2.
Escape character is '^]'.
auth 'r,uLgt.313'
+OK
sync
$18
REDIS0006³C띲V*1
$4
PING
*2
$6
SELECT
$1
0
*3
$3
set
$2
aa
$2
bb
*1
$4
PING
如前所述,slaves是可以自动冲连当master-slave 连接down了由于一些原因。
如果master 接收多个并发lsave的同步请求,它执行一个单独的后台保留为了服务它们。
无盘复制:
通常一个完整的同步要求来创建一个RDB文件在磁盘,然后加载相同的RDB从磁盘为了提供给slaves.
使用慢速的磁盘可以是一个非常有压力的操作对于master,Redis 版本2.8.18是第一个版本支持无盘复制。
在这个设置 child process 直接发送RDB 通过在线到slaves,不需要使用磁盘作为中间存储
配置:
配置基本的Redis复制是很平常的,只需要增加下面行到slave 配置文件:
slaveof 192.168.1.1 6379
当然你需要替换192.168.1.1 6379 为你的master ip地址和端口。
或者,你可以调用slaveof 命令,master host会开启一个sync 使用slave
如果master 是密码保护的(使用"requirepass" configuration)
它是可以告诉slave 来认证在开始复制同步过程前,否则master 会拒绝slave的请求
masterauth r,uLgt.313
复制:
Master-Slave replication. 使用slaveof 来让一个Redis 实例 是另外一个Redis server的一个拷贝。
一些少的事情来了解ASAP 关于Redis 复制:
1) Redis 复制是异步的,但是你可以配置一个master 来停止接收写如果它出现一定数量的slaves是断开的
2)Redis slaves 是可以执行一个部分同步如果复制链接是丢失的对于一个相对小的时间段。
你可能需要配置复制backlog size 使用一个合适的值 依赖你的需要
3)
slave上的情况:
node2:/data01/redis#strings appendonly.aof
SELECT
SELECT
czcb
1234567
tlcb
9999999
node2:/data01/redis#strings dump.rdb
REDIS0006
czcb
有一些少的参数对于调整复制backlog 在内存通过master 执行部分复制。
只读模式:
127.0.0.1:6379> set czcb aa
(error) READONLY You can't write against a read only slave.
自从Redis 2.6, slaves 支持只读模式默认是启用的,是通过slave-read-only选项在redis.conf文件,
slave-read-only yes
Read-only slaves 会拒绝所有的写命令,因此它是不能写到一个slave.
这不意味着功能是打算暴露给一个slave实例到互联网或者更广泛的一个网络 不信任的客户端存在。
因为 管理命令像DEBUG 或者CONFIG 是仍旧启用的。
然而,只读实例的安全可以通过禁用命令在redis.conf来改善
你可能想知道它是可以恢复read-only 设置,让slave 实例可以被针对的写操作。
那些写会被丢弃 如果slave和master 同步或者如果slave 是重启了,
slave 一重启,数据就恢复原状。
有一些合法的使用case用于存储短暂的数据在写的奴隶。
1.例如 计算慢的结果集或者排序集操作 存储它们到本地的keys 是一个使用案例对于写slave
2.但是请注意,写slave 在版本4.0是不能过期keys 。
这意味着 如果你使用EXPIRE 或者其他命令来设置一个最大的TTL 用于一个key,
这个key 会泄露,当你不在看到它房你访问它使用read 命令,
你可以看到它在keys的统计计数,它仍旧使用内存。
Setting a slave to authenticate to a master 设置一个slave 验证到master:
如果你的master 有一个密码保护通过requirepass,配置slave 来使用那个密码在所有的同步操作:
允许只能写在有N个连上的副本:
从2.8版本开始,它是可以配置一个Redis master来接收写只有当至少N个slaves是当前连接到master:
然而,因为Redis 使用异步复制 它是不能确定slave 实际接收到的一个给定的写,
所以总有窗口对于数据丢失:
这就是功能工作的原理:
1.Redis slaves ping master 每秒,确认大量复制流处理:
2.Redis masters 会记住它收到一个ping最后的事件从每个slave
3.用户可以配置一个slave的最小数目 延迟不大于最大数量的秒数
如果至少N个slaves, 延迟少于M秒,写才被接受
你可能考虑最好的数据安全机制,一致性是不确定的对于一个给定的写,
但是至少时间窗口对于数据丢失是限制的对于给定的秒数。
如果条件不符合,master 会代替回复一个错误,写会不接受
有两个配置参数对于这个功能:
min-slaves-to-write <number of slaves>
min-slaves-max-lag <number of seconds>
Redis 复制处理过期的keys:
Redis 过期允许keys 有存活的时间限制。
这样的功能取决于实例的能力来统计时间,然而Redis slaves 当前复制keys 使用过期,