Redis资源池化技术+Sentinel哨兵模式进行集群通信

        redis在线上使用的时候,为了高可用和可扩展性,一般不会是单台或者一组的模式运行,而是按照一个集群的模式运行。一个集群包括多组redis,一组redis包含一个master和多个slave,这样我们为了便于管理和故障转移,使用了Sentinel哨兵模式来对集群中的redis进行管理。

        工程上,为了避免应用和redis之间的链接频繁的创建和销毁,提高性能效率,一般使用池化技术,对于链接进行管理,类比于数据库连接池,一般会使用Apache的common-pool来创建自己的资源池,利用GenericObjectPool来进行Redis的创建,当然JedisPool本质上已经创建了一个这样的API,那么我们在工程上使用Jedis的jar的时候,需要做的就是进行相关资源池参数的配置。

    这里需要考虑几个问题

    1、由于我们是面对的是集群的形式,我们需要对集群中的分片(即一组)服务器进行池化缓存,并且对于一组中的链接需要进行区分,读写区分进行连接的有效管理

    2、我们需要针对集群变化实时进行更新,并且对池化进行变更,这里的变更有两种,redis本身的故障转移和人为的redis扩容和缩容,以及分片的变化。

    3、针对redis操作过程中进行的链接释放和链接管理,以及redis异常之后的链接处理

 

    综上我们在实现这个框架的时候需要考虑以下几点:

        1、redis数据模板可配置化

        2、支持redis数据分片,支持不同路由规则,支持分片的增加/减少(这里应用需要考虑下分片数量变化之后的数据迁移,当然redis集群可以在不下线的情况下进行重新分片)的监听,支持故障转移框架池化自我调整。

        3、支持不同节点类型(主节点/从节点)的读写策略,redis命令的路由

        4、支持自定义/丰富的缓存API,对上层应用屏蔽底层redis集群变化带来的影响,增加透明性

        5、连接池的管理

        6、框架进行调整时,相关获取的链接的管理。

        7、异常处理,网络故障的情况进行相关调整。

    相关的实现方案:

        redis数据模板可配置化

                一般通过监听zk来实现节点数据的变化,来实现配置的实时更改。能够保证节点数据获取的实时和一致性。

                数据分片,分片内容可以在zk中配置,当然也可以不配置,直接从Sentinel示例中获取: 

redis 127.0.0.1:26381> sentinel get-master-addr-by-name mymaster
     * 1) "127.0.0.1"
     * 2) "6379"
redis 127.0.0.1:26381> sentinel masters
     * 1)  1) "name"
     *     2) "mymaster"
     *     3) "ip"
     *     4) "127.0.0.1"
     *     5) "port"
     *     6) "6379"
     *     7) "runid"
     *     8) "93d4d4e6e9c06d0eea36e27f31924ac26576081d"
     *     9) "flags"
     *    10) "master"
     *    11) "pending-commands"
     *    12) "0"
     ..................

     也可以获取到相关的Master的slave的端口信息,通过这些信息可以按照MasterName进行分组来进行redisPool的示例化。

    通过监听Sentinel中的消息订阅,来监听分片节点的故障转移(+switch-master),进而获取到新的master节点的NewIP和OldIp,进行redisPool的切换。

    路由策略:

        关于集群分片路由,可以在客户端中做,也可以利用redis集群来做,redis集群本身会将整个集群分成16384个槽,每个节点进行相关的槽指派。客户端中做,集群中就不需要关注主节点的状态,每个节点部署的时候直接部署,省却了硬编码中的风险,但是也带来了一个问题,如果集群中增加了一个主节点,由于不清楚客户端的路由策略,数据迁移不方便。

        一般是通过一致性hash的算法,为每个节点分配一段槽,对于Key落在这段槽内的就选取这个槽归属的节点。

        一般的一致性Hash算法,采用MURMUR_HASH+TreeMap的方式实现。获取TreeMap中最靠近MURMUR_HASH值的分片信息,不同的权重分配不同的hash值。

   Q:分片节点的变化,这个比较麻烦,可能需要重新刷全量缓存,需要客户端做自己数据迁移。当然,框架中可以存留上一次的快照,

     RWPolicy——读写策略的实现

        针对相关的redis操作指令设置相关的读写策略,通过路由获取分片之后,来决定获取Jedis是slave节点还是master节点的链接。这里需要注意的是,主从之间同步会有一致性的问题。

    链接异常处理

        操作redis的时候,jedis获取数据的时候,可能会导致IOException,但是这时数据已经缓存到了本地,这是Jedis会抛出JedisConnectException,对于这种抛出异常的链接,我们需要销毁,重新创建新的链接,防止异常的链接不销毁,下个线程重新获取带来新的问题。

    其它

        采用Pipline方式提高redis吞吐量,等等。

转载于:https://my.oschina.net/guanhe/blog/2984135

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值