03.06 Redis集群方案应该怎么做?

黄晴清


公司redis集群有了蛮大的规模,权且来分享下redis集群!

首先,不可否认的是,redis的单机性能相当高,但是就算把内存大量扩大(垂直扩展),也不可能满足大业务需要的性能和可维护性!所以,集群是很好的一个选择,通过集群可以实现水平扩展,提升整体的性能!

集群方案1:使用客户端分片的方式,增加多台redis服务器之后,在业务端使用某种路由规则(hash算法等),将不同key对应的数据放在不同的redis服务器中,实现内容分发!

但是这样的方式有很多缺点,比如业务代码和redis数据路由代码严重耦合,可扩展性也十分底下,需要增加redis实例的同时,修改原先的分发规则,而一旦出现问题,排查难度大(因为运维和代码端都要查)!

集群方案2:使用开源产品twemproxy作为redis代理!中间件twemcache负责接收业务端的请求,然后从不同的redis实例中收集数据传送给业务方,起到一个中间代理的作用!业务端像连接一个redis实例一样连接twemproxy,实现了业务代码和redis之间的解耦合!同时,对于失效的redis会被自动踢出,防止数据的丢失,不过twemproxy作为一个中间件,肯定会对需要实时性强的系统造成性能损失,动态无痕迹的增加redis实例也是很困难的!!


集群方案3:使用codis集群,类似于twemproxy,客户端也不需要去连接redis实例,而使用codis作为中间件,让codis底层自己去获取数据,增加的codis dashboard可以对codis proxy和codis server进行统一管理,对实例节点的改变可以有效应对!


集群方案4:redis自主集群,使用纯redis实现集群,完全的去中心化!redis集群把所有的key放在16384个slot中,各个redis可以通过重定向引导客户端访问数据所在的集群点,比如client访问redis2,redis2发现数据的key在redis1中,就引导客户端重定向去redis1中取数据,这样不需要别的中间件就能很好的实现数据获取,而且这样的纯redis方式,部署起来也是十分方便的!

集群方案5:直接买阿里,腾讯的集群吧,想要啥样的给你啥样的。。

我们公司现在使用的是基于codis的redis集群,管理相对来说比较简单,算是比较不错的集监控,代理于一身的组件!

redis集群具体的使用过程中,如果有问题,可以私信我进行交流!更多的技术分享,敬请关注。。。


此生唯一


Redis在3.0之前,是只支持单实例模式的,虽然现在服务器的内存也可以达到几百G的规模,但是考虑到成本问题,大多数公司都会采用集群方案,把数据分片存到多个Redis实例中。


客户端分片

这个方案比较简单,也就是在客户端中,通过定义好的路由规则,把不同的key存储(路由)到不同的Redis实例中;比如hash(key)%N,根据结果把key路由到Redis1-RedisN中。

  • 优点:不依赖第三方中间件,完全自己实现,能够自我掌控。

  • 缺点:增加或者减少Redis实例的时候,需要调整程序,而且在调整之后的一段时间,大部分缓存会失效(路由结果改变了);


Redis中间件

客户端把请求发送到Redis中间件,中间件根据路由规则发送请求到正确的Redis实例,然后中间件再把结果返回给客户端。常用的几个:

  • Twemproxy:由Twitter开源;客户端可以像连接Redis实例一样连接Twemproxy,不需要修改代码逻辑;Twemproxy可以自动地Redis保持连接(可以看成数据库连接池),而且可以自动删除无效Redis实例;缺点也是有的,客户端和Redis中增加了一层,性能方面多少会有一些损耗,更大的问题,是Twemproxy无法平滑地增加Redis实例。


  • Codis:豌豆荚开源;它最大的优势在于可以平滑增加或减少Redis实例,可以透明地迁移数据。

Redis3.0集群

Redis3.0集群采用无中心节点方式实现,无需proxy代理,Redis把所有的Key分成了16384个slot,每个Redis实例负责其中一部分slot;客户端直接与redis集群的每个节点连接,根据同样的hash算法计算出key对应的slot,然后直接在slot对应的redis上执行命令(集群中的所有信息通过节点之间定期的数据交换而更新)。

Redis客户端在任意一个Redis实例发出请求,如果所需数据不在该实例中,通过重定向命令引导客户端访问所需的实例。

我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。


会点代码的大叔


Redis集群有以下三种方式,分别进行详细说明。


1 Redis Cluster

官方3.0版本提供的集群解决方案。分片采用slot概念,整个集群共分成16384个slot,对于每个进入Redis的键值对根据key进行散列,分配到这16384个slot中某一个。散列算法是CRC16后16384取模。

客户端在访问时可以连接到集群中任意一个节点,如果这个节点没有数据,则会转到含有该数据的节点(类比Elasticsearch协调节点)。

若某个node发生故障,那它负责的slots也就失效,整个集群将不能工作。所以官方推荐部署为主从模式,即每个主节点有一个从节点。


2 客户端分片(推荐)

在官方3.0版本之前这是最通用的方法。首先Redis服务器分别独立部署,然后客户端采用一致性Hash算法将数据KEY和Redis服务器地址进行散列,特定KEY会映射到特定Redis节点上。同理为了保证高可用性也可以采用主从模式。

Java Redis客户端驱动Jedis提供了Redis Sharding功能,注意配置文件需要配置Redis服务器地址。


3 代理方式

上述客户端方式有一个问题:连接不能共享导致资源浪费。所谓代理方式就是在客户端和Redis服务端之间,设置了一个代理,所有请求先经过代理,通过代理转发至Redis服务端。业界比较流行的代理中间件有twemproxy和Codis,其中Codis由豌豆荚团队开源。


敬请关注

请点击关注按钮【IT徐胖子】会持续为大家奉献互联网和技术干货内容,感谢支持


分享到:


相關文章: