方案概述:
对于ycache-client,如下图,在一致性hash环上的每个节点都有一个备用的节点。正常情况下slave节点不参与key的分配(冷备)。只有当master挂了,ycache client读取/监听了zk上的slaveof节点,从而得知那些cache实例是slave状态的,把slave实例排除掉。数据变更时,如果变更的redis实例当前自己在使用,就重新初始化这个pool的所有链接。
当master发生故障时,master、slave的切换时在yagent完成的。yagent定时将redis实例对应的master/slave关系写到zk的slaveof节点上。然后slave上会每5秒检查一次master的状态。如果master没有响应,就将slave升级为master。
yconsole负责master/slave关系的管理,可以将某个redis服务设置为slave状态,查看状态等。
![](https://images0.cnblogs.com/blog/614747/201507/151542003763247.png)
实现说明:
- redis版本升级为3.0.1(也可以使用2.8.*的版本,但需要确保主、备版本是相同的)
- 打包新的redis rpm包
- redis使用开源的3.0.1的源码包
- 将https://github.com/zwChan/remirepo/tree/master/redis 拷贝到rpmbuild的source目录(/root/rpmbuild/SOURCES/),然后执行rpmbuild -bb redis.spec.
- 更新缺省的redis配置文件,支持aof(?)
- 检查命令的兼容情况
- yagent适配
- 读取自己管理的slave,定时更新一次这个信息(缺省10s,可配置)
- 定时检查一下slave对应的master是否正常,如果不正常,将自己设置为master,将原来的master设置为slave(缺省间隔为1s,连续检查5次失败后才算失败,所以延时5秒)
- 定时检查当前的master实例是否在zk上被配置为slave,如果是,将它转换为slave状态(5秒间隔)
- 每次一个redis实例重启后,如果它有slave且正常,都将正在起的实例变更为slave,将它原来的slave变更为master。这样做是为了避免redis实例快速重启导致数据丢失。详细的问题见: http://redis.io/topics/replication “Safety of replication when master has persistence turned off”
- 如果redis实例的主备状态和zk上的状态不一样,修改为与zk上的一样。(5秒间隔)
- yconsole适配
- 添加slaveof命令,配置和删除redis之间的主从关系;yconsole { slaveof } slave master
- 添加slaves命令,显示主从关系;同时检查zk上的主从关系是否与redis真实的主从关系一致。
- 主从关系发生变化时,通过命令行slaveof动态通知redis做出对应改变;
- add命令计算容量时不计算slave
- add/app/mod命令将slave也自动写到cache id的内容里
- list命令显示主从关系
- ycache-client适配
- slaveof目录的子节点增加和删除时,要进行重新初始化pool的处理
- 初始化pool时,将slaveof下的slave状态的实例去除
- 当slave的master变化时,不需要处理
- 每个pool只初始化一个zkproxy
- 限制:
- 每个master最多只能有一个slave,slave不能作为master;
使用方法:
- ycache-client:此功能对ycache-client使用者透明,仅须升级为2.2.0及以上版本的;
- yconsole:添加了slaves和slaveof命令,请查看 yconsole help命令获取命令格式。
- slaves: 查看slave和master对应的关系,后面的状态“ok”标识现在zk上的主备关系与redis本身主备关系的是一致的。
- slaveof:添加或删除slave/master关系(master参数为‘none’时删除关系)
刚配置后的几秒内,zk状态和redis状态可能不一致。等几秒后状态就一致了。 - 添加cache id时,如果一个redis实例已经被指定为slave,它所占用的资源不被计算到命令行指定的资源中;但如果分配后才配置slave/master关系的,cache id的容量会变少(因为slave是不参与使用)
将master添加到test中,它的slave会自动加到test中。但是,如果你单独将slave添加到test中,不会带着master加到test。 这是一种错误的配置,slave不应该直接被使用(尽管没有被禁止) - yagent:升级版本大于等于‘2015-06-02';升级redis版本为2.8.*。 使用方法不变。redis新的rpm包在svn上。
问题与改进
当前有性能问题:
- 所有的redis 的client都监听slaveof目录,很容易造成惊群问题;
- 老版本的client不能在主从环境的redis上用。所以要确保client升级后,才能用yconsole设置主从关系。
当然其他方面也要相应修改,但修改后的架构更为清晰,当前架构反而不是很好。当前yhd使用redis的不多,而且主从很少变化,所以惊群问题还不明显。