基础的Redis
同步使用很是简单,配置主从同步可让从节点彻底复制节点。无论主节点发生任何事,从节点会在连接断开以后自动重连。redis
这个机制工做使用了三台机子:数据库
key
过时或者回收等。Redis
默认使用高性能高延迟的异步复制,这是大部分Redis
使用场景的天然复制模式。从节点按期异步的从主节点获取大量的数据。缓存
能够在客户端使用WAIT
命令来请求同步复制确认的数据。然而WATI
命令只能确保指定数量的数据被复制到其余实例:数据写入依旧会在故障转移或者因故障转移的致使的缘由中丢失,取决于Redis
持久化配置。你能够查看Sentinel
或者Redis Cluster
文档查看更多关于高可用和故障转移的信息。接下来的文档主要归纳Redis
简单的数据同步的一些基本的特征。安全
接下来是一些关于Redis
同步很重要的事实:网络
Redis
使用异步复制,从节点异步的从主节点获取大量的数据。Redis 4.0
之后,全部的子从节点都将从主节点收到相同的复制流。Redis
同步在主节点是非堵塞的。这意味着主节点能够继续处理请求,当一个或者多个从节点作初始化数据同步或者增量同步的时候。Redis
从节点在复制流来的的时候返回一个错误给客户端,在初始化同步的时候,旧的数据集将被删除,行的数据必须被加载。从节点将会在这个短暂时间窗口堵塞正在进来的链接(这将在巨大的数据集上花费长达许多秒的时间)。从Redis 4.0
开始,删除就数据将会在另外一个线程进行,可是加载新的初始化数据集依旧会在主线程执行,而且堵塞从节点。O(N)
的慢查询操做能够由从节点分担),同步是可伸缩的,也是安全可靠的。AOF
。可是这个操做要很是当心,由于重启住节点将清空数据集:若是此时从节点去同步它,将会让从节点也清空。若是使用Redis
同步,强烈建议在主节点和从节点都打开持久化。若是这由于担忧延迟致使磁盘缓慢,实例应该经过修改配置,避免在重启的时候自动重启。
为了更好的理解在持久化关闭的时候,自动重启是很是危险的,检查下面数据数据从主节点和从节点都消失的模式:并发
当Redis Sentinel
用来作高可用的时候,主节点上将会关闭持久化,同时也关闭自动重启。好比主节点能够快速重启,快到Sentinel
都来不及捕捉错误因此上面归纳的失败的模式就发生了。less
任什么时候候数据安全都是重要的是,当主节点使用同步并关闭持久化的时候,自动重启也要被关闭异步
Redis
同步是怎么工做的每个Redis
主节点有一个同步ID,是一个巨大的位随机字符串标记数据集。同时主节点也为发送到从节点的同步流提供一个增加偏移量,为了让从节点更新数据集状态。同步偏移量即便在没有从节点;连接的时候也会增加,因此每一次都将产生一对:性能
Replication ID, offset
标记主机数据集精确的版本
当从节点链接到主节点的时候,他们使用PSYNC
命令发送他们目前为止执行的旧的同步ID和偏移量。这种方式下,主节点能够值发送增加部分,然而,若是主节点没有足够的日志备份,或者从节点使用了一个过去的同步ID,主节点没法找到他,就会发生全量同步:这种状况下,从节点将会获得一个完成的数据复制集,重新开始。
更多全量同步工做的方式:
主节点开始一个后台进程保存数据,产生一个RDB
文件。同时开始缓存从客户端来的全部写命令。当后台保存进程完成,主节点将会把数据文件发送给从节点,他保存在磁盘中,而后加载到内存。主节点也会立刻发送缓存命令到从节点。这将会以Redis
协议自己相同的命令流格式完成。
你能够足迹经过telnet
尝试。在服务店正在执行一些工做的时候链接Redis
端口并发送SYNC
命令。你能够看到大部分的传输而且主节点收到的全部命令都会telnet
中打印出来。事实上SYNC
是一个旧的协议,不在新的Redis
实例上使用,可是依旧向后兼容的:他不容许从新增量同步,因此PSYNC
用来代替他。ui
正常状况下,一个全量同步须要建立一个RDB
文件,而后从磁盘中读取这个文件,再发送给从节点。
然而磁盘读取是很是慢的,这将给主节点形成很是大的压力。Redis 2.8.18
之后支持无盘同步。在这种设置下,子进程能够直接经过网络发送RDB
给从节点,从而避免使用磁盘当作中间存储。
配置Redis
同步是很简单的,添加如下命令到配置文件就能够了:
slaveof 192.168.1.1 6379
固然你必须使用你主节点的IP和端口覆盖192.168.1.1 6379
参数。当你使用SLAVEOF
命令的时候,主节点就会开始同步数据到从节点
固然还有一些参数用来开启同步日志,让主节点加载到内存中去执行增量同步。能够查看Redis
发行版中的redis.conf
文件查看更新信息。
无盘同步可使用repl-diskless-sync
配置参数开启。延迟传输从而等待更多子节点连接主节点可使用repl-diskless-sync-delay
配置参数控制。更多栗子请查阅发行版中的redis.conf
文件。
Read-only slave
从Redis 2.6
开始,从节点支持只读模式,而且这是默认开启的。这个行为能够用slave-read-only
来控制,能够在redis.conf
修改,也可使用CONFIG SET
来设置。
只读的本身诶单拒绝全部的写命令,因此不可能写入从节点,由于会发生错误。这并不觉得这这个特性是为了在不被信任的网络和客户端中暴露本身,由于管理命令,好比像DEBUG
、CONFIG
之类的依旧可使用。固然,只读实例的安全性能够经过在redus.conf
中的rename-command
禁用命令来提高。
你可能会想为何要容许只读的从节点实例能够被改成可写的。这些写入的数据将会被主节点再次同步数据的时候删除,这里有几个合理的用户场景来讲明为何要短暂的在可写从节点存储数据。
好比统计慢Set
或者Sorted Set
操做,并存储他们到本地,这是一个可写从节点很常见的用户场景
然而,要记住,4.0
之前的可写从节点没办法作到key
的过时时间设置,这意味着,若是你使用EXPIRE
或者其余命令去设置一个key
最大的TTL
,这个key
将会泄露,你将没法使用读命令找到他,你将会在key
的统计中看到他,而且他依旧占据着内存。因此,在一般状况下可写从节点使用TTL
将会致使问题(4.0版本之前)。
Redis 4.0 RC3
和更新的版本彻底解决了这个发生在key
写入超过63个数据库的问题(可是默认状况下Redis
实例只有16个数据库),而且如今可写从节点能够像主节点同样驱逐过时的key
,
一样须要记住的是从Redis4.0
之后,从节点写入的数据只存在本地,不会传播到链接到该子节点的子从节点,子从节点接收到的同步流将会和最高的主节点发送给中间节点如出一辙。下面是栗子:
A ---> B ---> C
即便B
是可写的,C也不会看到B写入的数据,只会看到A中的数据
若是你的主节点经过requirepass
配置属性设置了密码,设置从节点使用密码同步也是很是简单的:
使用redis-cli
链接从节点,输入:
config set masterauth <password>
为了永远记住他,添加到配置文件中:
masterauth <password>
Redis 2.8
之后,能够设置主节点只有在有N台从节点连接的时候能够写入请求。
然而,由于Redis
使用的是异步复制,因此没有办法保证从节点确实收到的给定的写入请求,纵游一个窗口期的数据丢失。
接下来是解释这个特性是如何工做的:
This is how the feature works:
ping
主节点,告知它全部的复制流工做了。ping
若是至少有N个从节点,若是少于延迟M秒,则写入将被接受。
你可能以为经最大努力保证数据安全的机制,虽然数据一致性没法保证,可是至少只是几秒的时间窗口内丢失数据。一般状况下范围数据丢失可比无范围数据丢失好多了。
若是条件不知足,主节点将会返回一个错误,而且写入请求将不被接受
下面是这个特性的两个配置参数:
min-slaves-to-write <number of slaves> min-slaves-max-lag <number of seconds>
查看更多信息,能够查阅打包在Redis
发行版中的redis.config
。
How Redis replication deals with expires on keys
Redis
同步是如何解决key
的过时的Redis
过时容许key
有一个有限的生存时间。这种特性依赖于实例多时间的控制,从节点正确的复制key
和过时,就是这些key
被lua
修改过。
为了实现这种特性,Redis
不能信任主节点和从节点时钟同步的能力,由于这没法解决这个问题而且还会致使静态条件和数据集分离,因此Redis
使用三个主要技术来保证过时key
的同步:
key
过时,而是等待主节点让key
过时。当主节点让一个key
过时(或者由于LRU
被移除),它同步发往全部从节点的DEL
命令。key
,由于这时候主节点没法提供一个DEL
命令。为了解决这个问题,从节点只用它本身的逻辑时钟报告说这个key
不存在,而且只供读操做,并不去影响数据集的一致性(而后新的命令就会从主节点来)。这种方式下,从节点就避免了逻辑上过时的key
还存在的问题。在真实的团推中,一个用从节点抓取的HTML
片断将会避免返回已经比指望存在时间多的缓存。Lua
脚本执行的时候,key
将不会过时,当Lua
脚本执行的时候,概念上来说,主节点的时间是中止的。因此一个key
在脚本执行期间,要么存在,要么不存在。这防止key
在脚本运行中间的时候过时,这也是为了发送相同的脚本到全部的从节点,保证了对数据集的影响是一致的。当一个从节点晋升为主节点,他将会开始独立的过时key
,不须要旧的主节点的任何帮助。
Docker
和NAT
中配置同步当使用Docker
或者其余容器技术作端口转发或网络地址转换的时候,Redis
同步有一些须要额外注意,特别是使用Redis Sentinel
或者其余系统时,主节点INFO
、ROLE
命令须要输出并扫描,用来发现从节点地址。
问题在ROLE
命令,和同步章节的INFO
输出,当发送请求到主节点实例的时候,使用NAT
的环境可能和从节点实例逻辑地址不一样(能够用来链接从节点的那个地址)。
一样的,从节点将会被以配置文件中配置的监听的端口列出,这可能会和转发的端口不一样,要注意端口可能被重映射。
为了解决这个问题,从Redid 3.2.2
开始,强制要求从节点声明一个任意的IP和端口给主节点。这两个配置指定是:
slave-announce-ip 5.5.5.5 slave-announce-port 1234
这被记录在Redis
发行版的redis.conf
文件中。
INFO
和ROLE
命令有两个命令提供了不少关于主节点和从节点当前的同步参数。一个是INFO
。若是这个命令被以INFO replication
的方式调用,则只显示和同步紧密相关的信息。另外一个更加计算机友好
的命令是ROLE
,提供了主节点和从节点同步的状态,同步偏移,列出已链接的从节点等。
Redis 4.0
之后支持重启和故障转移后的增量从新同步,当一个实例在故障转之后提高为主节点,他依旧能够从旧的主节点那边执行增量从新同步。为了作到这一点,从节点记住了从前的主节点的的同步ID和偏移,因此,能够提供部分的记录去链接从节点,尽管他们请求的是旧的同步ID。
然而,晋升的从及诶单提供的新的同步ID将会不一样,由于他构建了一个不一样的数据集历史。好比,有时候,主节点能够返回可使用而且能够继续接受写入,因此在晋升的从节点使用相同的同步ID将会破坏规则,即一个同步ID和偏移对只标记一个数据集。
此外,当优雅关闭或者重启的时候,从节点能够存储从主节点同步必须的信息到RDB
文件中。这对升级颇有用,当必须的时候,最好在从节点使用SHUTDOWN
命令去执行一个保存-退出操做。