Redis 3.0中文官方文档翻译计划(14) ——高可用客户端指引
本帖最后由 旧收音机 于 2015-4-25 17:44 编辑问题导读
1、怎么去支持Redis Sentinel的Redis客户端指引
2、怎么通过Sentinel去实现Redis服务器?
3、怎么去处理重连?
4、Sentinel遇到故障怎么转移断开?
5、怎么去连接从服务器?
6、怎么去处理连接池?
7、遇到错误时的处理方式?
8、Sentinel列表自动刷新怎么实现?
9、怎么来改进响应能力?
10、怎么去获取额外信息?
static/image/hrline/4.gif
本文档是一篇草案,其包含的指引将来可能会随着Sentinel项目的进展而改变。
支持Redis Sentinel的Redis客户端指引
Redis Sentinel是Redis实例的监控解决方案,处理Redis主服务器的自动故障转移和服务发现(谁是一组实例中的当前主服务器)。由于Sentinel具有在故障转移期间重新配置实例,以及提供配置给连接Redis主服务器或者从服务器的客户端的双重责任,客户端需要有对Redis Sentinel的显式支持。
这篇文档针对Redis客户端开发人员,他们想在其客户端实现中支持Sentinel,以达到如下目标:
[*]通过Sentinel实现客户端的自动配置。
[*]改进Sentinel自动故障转移的安全性。
要想获得Redis Sentinel如何工作的细节,请查看相关文档(请查看本系列相关文章,译者注),本文只包含Redis客户端开发人员需要的信息,期待读者已经比较熟悉Redis Sentinel的工作方式。
通过Sentinel实现Redis服务发现(Redis service discovery)
Redis Sentinel通过像”stats”或”cache”这样的名字来识别每个主服务器。每个名字实际上标识了一组实例,由一个主服务器和若干个从服务器组成。
网络中用于特定目的的Redis主服务器的地址,在一些像自动故障转移,手工触发故障转移(例如,为了提升一个Redis实例),或者其他原因引起的这样的事件后可能会改变。
通常,Redis客户端中有一些硬编码的配置来指定IP地址和端口作为网络中Redis主服务器的地址。但是,如果主服务器的地址改变了,就需要手工介入到每个客户端了。
支持Sentinel的Redis客户端可以从使用Sentinel的主服务器的名称自动发现Redis的地址。所以支持Sentinel的客户端应该可以从输入中获得,而不是硬编码的IP地址和端口:
[*]指向已知的Sentinel实例的ip:port对列表。
[*]服务的名称,像”timelines”或者”cache”。
下面是客户端为了从Sentinel列表和服务名称获得主服务器地址而需要遵循的步骤。
第1步:连接第一个Sentinel(connecting to the first Sentinel)
客户端应该迭代Sentinel地址列表。应该尝试使用较短的超时(大约几百毫秒)来连接到每一个地址的Sentinel。遇到错误或者超时就尝试下一个Sentinel地址。
如果所有的Sentinel地址都没有尝试成功,就返回一个错误给客户端。
第一个回应客户端请求的Sentinel被置于列表的开头,这样在下次重连时,我们会首先尝试在上一次连接尝试是可达的Sentinel,以最小化延迟。
第2步:请求主服务器地址(ask for master address)
一旦与Sentinel的连接建立起来,客户端应该重新尝试在Sentinel上执行下面的命令:
SENTINEL get-master-addr-by-name master-name这里的master-name应该被替换为用户指定的真实服务名称。
调用的结果可能是下面两种回复之一:
[*]ip:port对。
[*]一个null回复。这表示Sentinel不知道这个主服务器。
如果收到了ip:port对,这个地址应该用来连接到Redis主服务器。否则,如果收到了一个null回复,客户端应该尝试列表中的下一个Sentinel。
第3步:在目标实例中调用ROLE命令(call the ROLE command in the target instance)
一旦客户端发现了主服务器实例的地址,就应该尝试与主服务器的连接,然后调用ROLE命令来验证实例的角色真的是一个主服务器。
如果ROLE命令不可用(Redis 2.8.12引进的),客户端可以使用INFO复制命令来解析角色:输出中的某一个字段。
如果实例不是期待中的主服务器,客户端应该等待一小段时间(几百毫秒)然后再尝试从第1步开始。
处理重连(Handling reconnections)
一旦服务名称被解析为主服务器地址,并且与Redis主服务器实例的连接已经建立,每次需要重新连接时,客户端应该重新从第1步开始使用Sentinel来解析地址。例如,下面的情况下需要重新联系Sentinel:
[*]如果客户端在超时或者socket错误后重连。
[*]如果客户端因为被显式关闭或者被用户重连而重连。
在上面的情况下或者任何客户端丢失了与Redis服务器连接的情况下,客户端应该再次解析主服务器地址。
Sentinel故障转移断开(Sentinel failover disconnection)
从Redis 2.8.12开始,当Redis Sentinel改变了实例的配置,例如,提升从服务器为主服务器,故障转移后降级主服务器来复制新的主服务器,或者只是改变一个旧的(stale)从服务器的主服务器地址,会发送一个CLIENT KILL类型的命令给实例,来确保所有的客户端都与重新配置过的实例断开。这会强制客户端再次解析主服务器地址。
如果客户端要联系一个还未更新信息的Sentinel,通过ROLE命令验证Redis实例角色会失败,允许客户端发现联系上的Sentinel提供了旧的(stale)信息,然后会重试。
注意:一个旧的主服务器返回在线的同时,客户端联系一个旧的Sentinel实例是有可能的,所以客户端可能连接了一个旧的主服务器,然而ROLE的输出也是匹配的。但是,当主服务器恢复回来以后,Sentinel将会尝试将其降级为从服务器,触发一次新的断开。这个逻辑也适用于连接到一个旧的从服务器,其会被重新配置来复制一个不同的主服务器。
连接从服务器(Connecting to slaves)
有时候客户端有兴趣连接到从服务器,例如,为了分离(scale)读请求。简单修改一下第2步就可以支持连接从服务器。不是调用下面的命令:
SENTINEL get-master-addr-by-name master-name客户端应该调用:
SENTINEL slaves master-name用于检索从服务器实例的清单。
相应地,客户端应该使用ROLE命令来验证实例真的是一个从服务器,以防止分离读请求到主服务器。
连接池(Connection pools)
对于实现了连接池的客户端,当单个连接重连时,应该要再次联系Sentinel,如果是主服务器的地址改变了,所有已经存在的连接都要关闭并且重新连接到新的地址。
错误报告(Error reporting)
客户端应该在遇到错误时正确的返回信息给用户,尤其是:
[*]如果没有Sentinel能够联系上(这样客户端不可能从SENTINEL get-master-addr-by-name获得回复),应该返回明确表明Redis Sentinel不可达的错误。
[*]如果所有池中的Sentinel返回null回复,用户必须被通知Sentinel不认识这个主服务器名称的错误。
Sentinel列表自动刷新(Sentinels list automatic refresh)
一旦收到get-master-addr-by-name的成功回复,客户端会按照下面的步骤来更新其内部的Sentinel节点的列表:
[*]使用SENTINEL sentinels <master-name>命令获取这台主服务器的其他Sentinel列表。
[*]添加每个不在列表中的ip:port对到列表的后面。
客户端不需要更新自己的配置文件来持久化列表。更新内存中表示的Sentinel列表的能力对改进可靠性已经很有用了。
订阅Sentinel事件来改进响应能力(Subscribe to Sentinel events to improve responsiveness)
介绍Sentinel的文档中展示了客户端可以使用发布订阅来连接Sentinel以订阅Redis实例的配置变更。
这种机制可以用来加快客户端的重配置,也就是,客户端可以监听发布订阅,以知道配置变更什么时候发生,从而运行上文解释的三步协议来解析新的Redis主服务器(或者从服务器)地址。
但是,通过发布订阅收到的变更消息不能代替上面的步骤,因为不能保证客户端可以收到所有的变更消息。
额外信息(Additional information)
要获得额外信息或者讨论这个指引的特定方面,请发消息到Redis Google Group。
相关内容:
Redis 3.0官方文档翻译计划(1)——Redis介绍
Redis 3.0官方文档翻译计划(2) ——从入门到精通(上)
Redis 3.0官方文档翻译计划(3) ——从入门到精通(中)
Redis 3.0官方文档翻译计划(4) ——从入门到精通(下)
Redis 3.0中文官方文档翻译计划(5) ——使用Redis实现Twitter(上)
Redis 3.0中文官方文档翻译计划(6) ——使用Redis实现Twitter(下)
Redis 3.0中文官方文档翻译计划(7) ——使用Redis作为LRU缓存
Redis 3.0中文官方文档翻译计划(8) ——分片
Redis 3.0中文官方文档翻译计划(9) ——复制
Redis 3.0中文官方文档翻译计划(10) ——持久化
Redis 3.0中文官方文档翻译计划(11) ——集中插入
Redis 3.0中文官方文档翻译计划(12) ——高可用(上)
Redis 3.0中文官方文档翻译计划(13) ——高可用(下)
Redis 3.0中文官方文档翻译计划(14) ——高可用客户端指引
Redis 3.0中文官方文档翻译计划(15) ——集群(上)
Redis 3.0中文官方文档翻译计划(16) ——集群(中)
Redis 3.0中文官方文档翻译计划(17) ——集群(下)
页:
[1]