Redis数据库主从复制html
Redis 支持简单且易用的主从复制(master-slave replication)功能, 该功能可让从服务器(slave server)成为主服务器(master server)的精确复制品。如下是关于Redis复制功能的几个重要方面:node
q Redis 使用异步复制。从Redis 2.8 开始,从服务器会以每秒一次的频率向主服务器报告复制流(replication stream)的处理进度。web
q 一个主服务器能够有多个从服务器。redis
q 不只主服务器能够有从服务器,从服务器也能够有本身的从服务器,多个从服务器之间能够构成一个图状结构。数据库
q 复制功能不会阻塞主服务器:即便有一个或多个从服务器正在进行初次同步,主服务器也能够继续处理命令请求。安全
q 复制功能也不会阻塞从服务器:只要在 redis.conf 文件中进行了相应的设置,即便从服务器正在进行初次同步,服务器也可使用旧版本的数据集来处理命令查询。不过,在从服务器删除旧版本数据集并载入新版本数据集的那段时间内,链接请求会被阻塞。能够配置从服务器, 让它在与主服务器之间的链接断开时, 向客户端发送一个错误。bash
q 复制功能能够单纯地用于数据冗余(data redundancy), 也能够经过让多个从服务器处理只读命令请求来提高扩展性(scalability):好比说,繁重的SORT命令能够交给附属节点去运行。服务器
q 能够经过复制功能来让主服务器免于执行持久化操做:只要关闭主服务器的持久化功能,而后由从服务器去执行持久化操做便可。网络
当配置Redis复制功能时,强烈建议打开主服务器的持久化功能。 不然的话,因为延迟等问题,部署的服务应该要避免自动拉起。less
为了帮助理解主服务器关闭持久化时自动拉起的危险性,参考一下如下会致使主从服务器数据所有丢失的例子:
1. 假设节点A为主服务器,而且关闭了持久化。 而且节点B和节点C从节点A复制数据
2. 节点A崩溃,而后由自动拉起服务重启了节点A. 因为节点A的持久化被关闭了,因此重启以后没有任何数据
3. 节点B和节点C将从节点A复制数据,可是A的数据是空的, 因而就把自身保存的数据副本删除。
在关闭主服务器上的持久化,并同时开启自动拉起进程的状况下,即使使用Sentinel来实现Redis的高可用性,也是很是危险的。 由于主服务器可能拉起得很是快,以致于Sentinel在配置的心跳时间间隔内没有检测到主服务器已被重启,而后仍是会执行上面的数据丢失的流程。
不管什么时候,数据安全都是极其重要的,因此应该禁止主服务器关闭持久化的同时自动拉起。
注:在开启主从复制的时候,强烈建议开启持久化功能。
1、不管是初次链接仍是从新链接, 当创建一个从服务器时, 从服务器都将向主服务器发送一个 SYNC 命令。
2、接到 SYNC 命令的主服务器将开始执行 BGSAVE , 并在保存操做执行期间, 将全部新执行的写入命令都保存到一个缓冲区里面。
3、当 BGSAVE 执行完毕后, 主服务器将执行保存操做所得的 .rdb 文件发送给从服务器, 从服务器接收这个 .rdb 文件, 并将文件中的数据载入到内存中。
4、以后主服务器会以 Redis 命令协议的格式, 将写命令缓冲区中积累的全部内容都发送给从服务器。
从服务器能够在主从服务器之间的链接断开时进行自动重连, 在 Redis 2.8 版本以前, 断线以后重连的从服务器总要执行一次完整重同步(full resynchronization)操做, 可是从 Redis 2.8 版本开始, 从服务器能够根据主服务器的状况来选择执行完整重同步仍是部分重同步(partial resynchronization)。
从 Redis 2.8 开始, 在网络链接短暂性失效以后, 主从服务器能够尝试继续执行原有的复制进程(process), 而不必定要执行完整重同步操做。
这个特性须要主服务器为被发送的复制流建立一个内存缓冲区(in-memory backlog), 而且主服务器和全部从服务器之间都记录一个复制偏移量(replication offset)和一个主服务器 ID (master run id), 当出现网络链接断开时, 从服务器会从新链接, 而且向主服务器请求继续执行原来的复制进程:
若是从服务器记录的主服务器 ID 和当前要链接的主服务器的 ID 相同, 而且从服务器记录的偏移量所指定的数据仍然保存在主服务器的复制流缓冲区里面, 那么主服务器会向从服务器发送断线时缺失的那部分数据, 而后复制工做能够继续执行。不然的话, 从服务器就要执行完整重同步操做。
Redis 2.8 的这个部分重同步特性会用到一个新增的 PSYNC 内部命令, 而 Redis 2.8 之前的旧版本只有 SYNC 命令, 不过, 只要从服务器是 Redis 2.8 或以上的版本, 它就会根据主服务器的版原本决定究竟是使用 PSYNC 仍是 SYNC :
q 若是主服务器是 Redis 2.8 或以上版本,那么从服务器使用 PSYNC 命令来进行同步。
q 若是主服务器是 Redis 2.8 以前的版本,那么从服务器使用 SYNC 命令来进行同步。
配置一个从服务器很是简单, 只要在配置文件中增长如下的这一行就能够了:
slaveof 10.0.0.16 6379 #<==主服务器的IP和端口
另一种方法是调用 SLAVEOF 命令, 输入主服务器的 IP 和端口, 而后同步就会开始:
10.0.0.11:6379> SLAVEOF 10.0.0.16 6379 OK
从 Redis 2.6 开始, 从服务器支持只读模式, 而且该模式为从服务器的默认模式。只读从服务器会拒绝执行任何写命令, 因此不会出现由于操做失误而将数据不当心写入到了从服务器的状况。
即便从服务器是只读的, DEBUG 和 CONFIG 等管理式命令仍然是可使用的, 因此咱们仍是不该该将服务器暴露给互联网或者任何不可信网络。 不过, 使用 redis.conf 中的命令更名选项, 咱们能够经过禁止执行某些命令来提高只读从服务器的安全性。
配置参数以下:
slave-read-only yes
若是主服务器经过 requirepass 选项设置了密码, 那么为了让从服务器的同步操做能够顺利进行, 咱们也必须为从服务器进行相应的身份验证设置。
对于一个正在运行的服务器, 可使用客户端输入如下命令:
config set masterauth <password>
要永久地设置这个密码, 那么能够将它加入到配置文件中:
masterauth <password>
从 Redis 2.8 开始, 为了保证数据的安全性, 能够经过配置, 让主服务器只在有至少 N 个当前已链接从服务器的状况下, 才执行写命令。
不过, 由于 Redis 使用异步复制, 因此主服务器发送的写数据并不必定会被从服务器接收到, 所以, 数据丢失的可能性仍然是存在的。
如下是这个特性的运做原理:
1、从服务器以每秒一次的频率 PING 主服务器一次, 并报告复制流的处理状况。
2、主服务器会记录各个从服务器最后一次向它发送 PING 的时间。
3、用户能够经过配置, 指定网络延迟的最大值 min-slaves-max-lag , 以及执行写操做所需的至少从服务器数量 min-slaves-to-write 。
若是至少有 min-slaves-to-write 个从服务器, 而且这些服务器的延迟值都少于 min-slaves-max-lag 秒, 那么主服务器就会执行客户端请求的写操做。你能够将这个特性看做 CAP 理论中的 C 的条件放宽版本: 尽管不能保证写操做的持久性, 但起码丢失数据的窗口会被严格限制在指定的秒数中。
另外一方面, 若是条件达不到 min-slaves-to-write 和 min-slaves-max-lag 所指定的条件, 那么写操做就不会被执行, 主服务器会向请求执行写操做的客户端返回一个错误。
如下是这个特性的两个选项和它们所需的参数:
min-slaves-to-write <number of slaves> min-slaves-max-lag <number of seconds>
1) slave-serve-stale-data yes
#<==与master失联的应对方式,yes时会回复客户端旧的数据;no会提示报错“SYNC with master in progress”
2) repl-diskless-sync no
#<==是否启动无盘同步方式,即便用socket作同步策略而不会使用到disk。(磁盘IO慢,且带宽足够大时可选择采用。但该功能目前还不处实验状态,建议选择关闭)
3) repl-diskless-sync-delay 5
#<==当repl-diskless-sync设置为yes时,设置传输前的等待时间。要禁用该功能可配置为0。
4) repl-disable-tcp-nodelay no
#<==tcp延时的优化,默认为no。在很是高的网络trafiic条件或者主备距离远时,可开启为yes。
5) slave-priority 100
#<==从节点的优先级。数字越低级别越高,0表示不会被提高带master。