集群的价值在于高可用,在于负载均衡,那么对Redis来说如何做到这一点呢?我想到一种方案。
由于Redis的同步机制是 master / slave 方式,而且 slave 还可以有 slave,那么就可以方便的实现链式结构。什么是链式结构?如下:
master -> slave -> slave -> slave ... ...
这样的架构需要高度封装的代码来配合,例如一个 RedisOperator 类。这个类应该把 Redis 相关操作封装起来,特别是连接信息,一定要对外透明。这样就可以把Redis的问题限定在这个类之内来解决。
负载均衡。master 负责写操作,其他 slave 负责读操作。这样读取操作得到负载均衡,而 master 不用负责通常来说会更频繁的读取操作,也减轻了不少压力。这一定程度上达到了负载均衡的目的。
另一方面来看高可用问题:
读取操作的高可用。slave 的读取操作应该有一个选择具体 slave 的算法,从已知的在线 slave 列表(slave list)里面获得一个来完成最终的读取操作,具体算法可以根据实际情况选择(例如:轮询,随机等等)。如果其中一个 slave 失去连接,那么就把它及“它的子孙们”剔除在 “slave list” 之外(并给维护者发出告警),确保程序正常运行。如果所有 slave 都阵亡了则不得不用 master 来顶一下。这实现了读取操作的高可用。
写入操作的高可用。只有一个 master 负责写操作,如果它失去连接,那么 RedisOperator 应该将这个 Redis 实例的直属 slave 设置为新的 master 而在抛弃原 master 的同时向维护人员发出警告。依此类推,master 的角色逐个传递下去,从而实现写入操作的高可用。
以上方案实现了 Redis 服务的负载均衡和高可用,并且通过程序实现自动切换。