MyException - 我的异常网
当前位置:我的异常网» NoSQL » NoSQL之Redis-主从复制

NoSQL之Redis-主从复制

www.MyException.Cn  网友分享于:2013-07-17  浏览:0次
NoSQL之Redis---主从复制

[不忘初心]

前文,我们简要翻译了Redis集群的内容,在搭建集群的过程中,我们经常使用的功能就是主从复制,冗余备份。本文我们就来介绍这部分的内容。好了,马上开始我们的正文部分吧。

---------------------------------------------------------------------------------------------------------------------------------------

       Redis的复制功能是非常简单易用的,配置为主从复制功能之后允许Redis的slave服务器复制出与master完全一致的服务器。以下是一些关于Redis复制功能的几个重要方面:

  • Redis使用异步复制。从2.8版本开始 ,slave服务器将以1s的频率想master服务器报告复制流的处理进度。
  • 一个master服务器可以拥有多个slaves服务器。
  • slave服务器也能链接到其他slave服务器。除了链接到master服务器之外,slave服务器也能够和多个slave一起构成图状结构。
  • Redis的复制功能不会阻塞master服务器。话句话说,master服务器能够在向一个或者多个slave进行初始化复制时也能够持续的接受服务请求。
  • 复制功能也不会阻塞slave服务器。当slave在进行初始化复制时,slave也能够处理老版本的数据服务,前提是你在Redis.conf文件中进行了相应的配置。另外,你也可以配置slave在与master断开时,让其返回错误。然而,在异步的初始化之后,旧数据必须被删除,并且新数据必须被加载到slave中。此时,slave将会被阻塞直到复制完成。
  • 复制功能也可以被用于提升扩展性,使得,多个slave提供只读服务(如,繁重的SORT命令操作可以交给复述节点进行)。或者将复制功能单纯的用于数据冗余(datar redundancy)。
  • 使用复制功能来使得master节点避免执行持久化操作。只需要关闭主服务器的持久化功能,然后由从服务器去执行持久化操作即可。特别的:在这种配置之下,请确保master服务器不会自动重启。

在master节点关闭持久化功能时,复制的安全性

       当在设置中开启Redis复制功能时,强烈建议的做法是在master节点中开启持久化功能,或者绝对不可能发生的是:因为延迟问题,将Redis实例被配置为避免自动重启。
       为了更好的理解为什么将关闭持久化功能的master节点配置为自动重启是非常危险的,我们看看下面在数据从master节点与其对应的所有slave节点移除时发生的失败类型:
  • 假设A节点是master节点,B,C节点是其对应的副本。
  • A发生崩溃时,(配置为自动重启),重新启动了进程。然而因为持久化功能是关闭的,所以重启之后,该节点内的数据为空。
  • 节点B,C将会从A进行复制,这时A中的数据集是空的,因此,这时,B,C将会彻底删除他们之前备份的数据。
       为了高可用性,引入了Redis的哨兵(sentinel),关闭了master节点上的持久化,并且两者都配置为自动重启,这种做法也是非常危险的。举个例子:master节点可能非常快的就完成了重启,以至于sentienl都没有感知到失败的发生,接下来就会发生和上面例子一样的结果。
       在任何时间,数据的安全都是非常重要的,因此,在使用复制功能时,master节点如果没有持久化功能,自动重启的功能是必须被禁止的。

复制功能的运行原理

       当你建立一个slave节点时,slave节点都会将master节点发送一个SYNC命令。无论是首次链接还是重新连接。
       当maste节点接受到SYNC命令时,master节点将会开始后台保存功能,并且开始缓存所有接收到的将会修改数据集的新命令。当后台保存任务完成时,master节点将数据文件传送给slave节点,slave节点将会把数据文件保存到本地磁盘,并且加载到内存中。紧接着,master节点将会把之前还存下的所有命令也传输给slave节点。这项功能将会按照指令流来完成并且是一个与Redis协议本身相同的格式。
       你可以通过telnet命令来亲自验证这个同步过程。首先,连接上一个正在处理命令请求的Redis服务器,然后发送SYNC命令,之后,你将看到大量的数据转移以及master节点上接收到的每一条命令将会被再次运行在telnet的会话中。
       当master节点与slave节点断开时,slave节点能够自动的重写链接到master节点上。如果master节点接收到多个同时进行复制请求时,master节点也只需要执行一次SYNC命令,就可以处理到所有的slave服务器的同步请求。
       当master节点与slave节点断线重连之后,一个完整的SYNC命令将会被执行。在2.8版本之后,slave节点将会根据主服务器的情况来选择是完整同步还是部分同步。

部分重新同步

       从2.8版本开始,master节点和slave节点通常情况下能够在断线重连的情况下进行断点续传的复制功能,而不需要进行完整复制过程。
这个特性需要master服务器在内存中创建一个复制流缓冲区。并且,master和slave需要都记录下一个复制偏移量和一个master节点ID,当网络连接断开时,slave节点将会重新连接,并且向master服务器请求继续执行原来的复制进程。
如果master节点ID与slave节点记录的ID保持一致,并且slave记录的复制偏移量指定的数据在master节点中仍然存在,那么复制流将会从断点继续传输。
       如果上面条件哪怕只有一条不满足的话,那就开始一个完整的复制过程。
       Redis2.8版本的部分重新同步的特性会用到一个新增的PSYNC命令,而之前的版本只有SYNC命令。不过,只要服务器版本高于2.8,其将会自动的选择使用PSYNC还是SYNC。

无磁盘复制

       通常情况下,一个完成的再同步复制请求需要创建一个RDB文件,并且把这个RDB文件从磁盘中加载到slave节点中。
       如果是在一个非常慢的磁盘上进行,这对于master节点是一个压力非常大的操作。从2.8.18版本开始,实验性的支持了无磁盘的复制。在该配置下,子进程能够直接通过网络连接发送RDB给slave,而不磁盘作为中间存储。

配置

配置一个slave服务器是非常简单,只需要在配置文件中增加一下的这一张就行:
slaveof 127.0.0.1 6379
当然,你需要将代码中的IP与端口,替换成你自己的master服务器的IP与端口。另外的一种方法就是:使用SLAVEOF命令,输入master服务器的IP和端口,然后,master节点就会开始同步。
127.0.0.1:6379> SLAVEOF 127.0.0.1 6379
OK
这里也有一些专门为master节点执行部分重新同步的过程中调整内存中的复制存储的参数。
无磁盘复制功能可以使用repl-diskless-sync参数开启。为了在第一个slave节点到达之后等待更多slave节点到达,延迟传输动作,可以被repl-diskless-sync-delay参数控制。更多内容请在redis.conf文件的分布式配置中查看。

只读slave服务器

       从2.6版本开始,slave节点只读模式,并且也是默认的。这个模式也是可以被redis.conf文件中的slave-read-only控制的,也可以通过CONFIG SET命令来设置。
       只读模式下的slave节点将会拒绝一切写命令,因此,也不会出现因为错误操作在slave中写入数据的可能。但是,这不是说,我们可以将一个slave节点暴露给互联网或者不信任的网络客户端,因为,管理类的命令如DEBUG,CONFIG命令仍然是可以使用的。但是,我们可以禁用redis.conf文件中的rename-command命令,来提升只读slave节点的安全性。
       你可能会好奇,为什么可能出现重新覆盖只读配置和slave节点会成为写操作的目标。尽管这些写操作在slave节点与master节点再同步或者slave重新启动时将会被丢弃,但是,在可写的slave节点中,这里仍有对所存储的一些临时数据进行合法的使用。然而,在将来,这可能将会被移除。

slave节点的授权配置

如果master节点通过requirepass设置了访问密码,在配置slave节点中也需要配置相应的password,这样才能进行所有的同步操作。
对于一个正在运行的slave可以使用下面的命令:
config set masterauth <password>
要永久的设置这个密码,那么可以将它加入到配置文件中:
masterauth <password>

master服务器只有在只要N个slave服务器的条件下,才执行写操作

       从 Redis 2.8 开始, 为了保证数据的安全性, 可以通过配置, 让主服务器只在有至少 N 个当前已连接从服务器的情况下, 才执行写命令。
不过, 因为 Redis 使用异步复制, 所以主服务器发送的写数据并不一定会被从服务器接收到, 因此, 数据丢失的可能性仍然是存在的。
以下是这个特性的运作原理:
  • slave服务器每秒ping一次master服务器,并且报告复制流的处理情况。
  • master服务器将会记录各个slave服务器最后一次发送ping的时间。
  • 用户可以配置网络延迟的最大时间min-slaves-max-lag(M),以及执行写操作所需的最少slave服务器数量min-slaves-to-write(N).
如果至少存在N个slave服务器,并且延迟都小于M秒,那么写操作将被接受。
       你可以将这个特性看作是CAP理论中的C的宽松条件,尽管不能保证写操作的持久性,但起码丢失数据的窗口会被严格限制在指定的描述中。
如果这些条件没有被满足,master节点将会返回一个错误,并且写操作将会被拒绝。
以下是这个特性的两个选项和所需参数:
  • min-slaves-to-write <number of slaves>
  • min-slaves-max-lag <number of seconds>
详细的信息可以参考Redis源码中附带的redis.conf示例文件

对带有超期时间key的复制策略

       Redis的超时配置允许key拥有生效的有限时间。该特性以来于Redis实例能够计算有效时间,然而,Redis的slave节点准确的复制这些带有超时时间的key,即使当这些key被lua脚本改变了。
       为了实现这样的特性,Redis不能依靠master与slave之间同步时间的能力,因为,这个同步问题是无法解决的,并且将会导致竞争条件的产生和数据集的不一致问题,因此,Redis使用了下面三种策略实现让带有过期时间的key能够被使用:
  1. slave不会将key过期,而是等待master节点将其过期。当master节点将一个key的时间过期之后,使用DEL命令,通知所有slave节点删除该key。
  2. 然而,由于是master驱动过期时间的, 所以在某些时刻,slave仍然有可能保留了一些实际上已经过期的key,原因是master节点没有及时的提供DEL命令。为了处理slave节点使用其正确的时间来报告一个不存在的key,只向一些不违反数据一致性的读操作提供,(因为来自master节点的新命令将会到达)。通过这种方式,slave节点避免了返回一个实际上已经过期的,但未删除的key。
  3. 在Lua脚本执行中,将不会执行key的超时设置。在Lua脚本执行过程中,概念上说master上的时间是停止的,因此,在一个给定的脚本执行期的完整时间内一个给定的key将会只能是存在或者不存在。这阻止了key在执行脚本过程中发生超时现象,并且在为了发送相同的脚本到slave中也是十分必要的,其保证了对数据集产生相同的影响。
正如预期的那样,一旦发生故障转移,slave变为master,其将开始独立的判断key的过期时间,而不是向之前的master询问。
-------------------------------------------------------------------------------------------------------------------------------------
至此,NoSQL之Redis---主从复制

参考资料:
官方文档:http://redis.io/topics/replication
其他资料:http://doc.redisfans.com/topic/cluster-tutorial.html



文章评论

相关解决方案
  • 暂无相关解决方案
代码女神横空出世
代码女神横空出世
我的丈夫是个程序员
我的丈夫是个程序员
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
程序员和编码员之间的区别
程序员和编码员之间的区别
编程语言是女人
编程语言是女人
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
为什么程序员都是夜猫子
为什么程序员都是夜猫子
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
10个调试和排错的小建议
10个调试和排错的小建议
Java程序员必看电影
Java程序员必看电影
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
鲜为人知的编程真相
鲜为人知的编程真相
老程序员的下场
老程序员的下场
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
总结2014中国互联网十大段子
总结2014中国互联网十大段子
 程序员的样子
程序员的样子
程序员必看的十大电影
程序员必看的十大电影
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
程序员应该关注的一些事儿
程序员应该关注的一些事儿
那些争议最大的编程观点
那些争议最大的编程观点
如何成为一名黑客
如何成为一名黑客
一个程序员的时间管理
一个程序员的时间管理
我是如何打败拖延症的
我是如何打败拖延症的
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
旅行,写作,编程
旅行,写作,编程
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
每天工作4小时的程序员
每天工作4小时的程序员
漫画:程序员的工作
漫画:程序员的工作
中美印日四国程序员比较
中美印日四国程序员比较
程序员都该阅读的书
程序员都该阅读的书
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有