本文整理了redis当前的高可用方案,以及比较各方案的优劣和我们最后的选型。

Redis-Cluster

  • 引入Hash slots概念,便于分片以及数据迁移.解决了按照节点分片带来的扩容以及数据迁移的困难

    slot = crc16(“foo”) mod NUMERSLOTS

  • 节点都是对等的,复制是基于slots的,不是基于节点的.每个slots有两份冗余,可以容忍随机的两台节点宕机而不影响服务
  • 支持自动重新分片以及故障迁移
  • 节点通过PING-PONG以及Gossip互相感知,不需要中心监控服务监控节点的状态
  • 通过SmartClient在Client端缓存了slots的分布图,无需中心代理.

详情参看 Redis_Cluster.pdf 

  1. 优点
    • 优点很多 能确保高可用 高性能,基本上是分布式缓存的完美方案
  2. 缺点:
    • 还是beta版本,不能在生产环境使用

HAProxy + Twemproxy + redis-twemproxy-agent(NodeJS) + redis sentinel

方案来源(REDIS-SENTINEL TWEMPROXY AGENT)

  • Twemproxy 是twitter开源的代理服务,支持Memcached和Redis协议,在这里主要的作用是 1.解决分片的问题,这样就不需要客户端自己做分片,分片对客户端是透明的.2.客户端应用连接Twemproxy,主从切换对客户端透明
  • Redis sentinel 是redis官方提供的redis检测工具,会检测redis的状态然后触发事件.
  • Redis-Twemproxy-Agent主要是用于监听redis sentinel的变更事件,修改Twemproxy的配置.
  • HAProxy 主要是为了解决Twemproxy的高可用问题。
  1. 优点
    • 解决了分片问题
    • 能保证高可用
  2. 缺点
    • Twemproxy的hash规则和我们当前使用的方式不兼容,改造后会有数据迁移的问题,比较麻烦
    • 这个方案引入的组件过多,担心不好运维
    • 不支持读写分离Slave节点只起备份的作用

Keepalived + HAProxy + Redis sentinel + 自定义脚本

这个方案基本上是上个版本的简化版本 redis-ha

  • Keepalived负责虚拟ip和高可用
  • HAProxy 负责代理Redis的端口,同一个实例可以代理多个redis节点
  • Redis sentinel负责检测Redis的存活状况,并进行主从切换
  • 自定义脚本由Keepalived的定时调用,通过命令向Redis sentinel查询Redis Master的ip,判断是否发生变化,如果变化则修改HAProxy配置文件并重启HAProxy.
  1. 优点:
    • 组件较少,并且都比较成熟,运维成本较低
  2. 缺点:
    • redis的slave一直处于备用状态 比较浪费(同上一个方案)
    • 没有解决分片问题,分片由应用解决
    • 代理对性能有影响
    • 脚本是定时轮询的机制通过Redis sentinel查询redis状态,主从变更后感知会比较慢,如果发生切换,整体上服务会有分钟级别的时间处于不可用状态

Zookeeper + Redis sentinel + 自定义同步服务 + SmartClient

这个方案的思路和RedisCluster有一定的共通之处,

  • Redis sentinel 检测redis实例并进行主从切换
  • 自定义同步服务负责监听Redis sentinel的状态变更,将redis实例的状态同步到Zookeeper
  • Zookeeper扮演配置中心角色
  • SmartClient连接到Zookeeper并且watch Redis 实例的状态,根据状态将请求发送到正确的redis节点
  1. 优点:
    • 不需要代理 没有性能浪费
    • SmartClient机制是当前分布式缓存的一种通用解决方案
  2. 缺点:
    • 自定义同步服务以及SmartClient当前都需要额外开发 考虑到RedisCluster本身已经包含了这些改造,不如等待Cluster正式发布.

结论

基于当前流量不是太大,数据分片也不是当前最大的的问题,主要的需求点在高可用,最后使用了方案二.上线后整体稳定,服务器重启,网络不通等故障,基本不用人工处理redis的问题