redis集群主流架构方案分析Redis在互联网大数据平台有着广泛的应用,主要被用来缓存热点数据,避免海量请求压垮数据库,同时可以提升服务节点的响应速度和并发量。随着数据量的增多,由于redis是占用单台物理机或虚机的内存,内存资源是有限的,要动态地扩容缩容,就需要用到redis集群。redis集群的架构方案经历了一系列演变和改良的过程,本文介绍了四种主流的redis架构方案。客户端分片优点不使用第三方中间件,实现方法和代码可以自己掌控并且可随时调整。这种分片性能比代理式更好(因为少了分发环节),分发压力在客户端,无服务端压力增加缺点不能平滑地水平扩容,扩容/缩容时,必须手动调整分片程序,出现故障不能自动转移,难以运维Twemproxy优点运维成本低。业务方不用关心后端Redis实例,跟操作Redis一样。Proxy的逻辑和存储的逻辑是隔离的缺点a.代理层多了一次转发,性能有所损耗b.进行扩容/缩容时候,部分数据可能会失效,需要手动进行迁移,对运维要求较高,而且难以做到平滑的扩缩容c.出现故障,不能自动转移,运维性很差RedisCluster优点a.无中心节点b.数据按照Slot存储分布在多个Redis实例上c.平滑的进行扩容/缩容节点d.自动故障转移(节点之间通过Gossip协议交换状态信息,进行投票机制完成Slave到Master角色的提升)e.降低运维成本,提高了系统的可扩展性和高可用性缺点a.严重依赖外部Redis-Tribb.缺乏监控管理c.需要依赖SmartClient(连接维护,缓存路由表,MultiOp和Pipeline支持)d.Failover节点的检测过慢,不如“中心节点ZooKeeper”及时e.Gossip消息的开销f.无法根据统计区分冷热数据g.Slave“冷备”,不能缓解读压力ProxyRedisCluster优点SmartClient:a.相比于使用代理,减少了一层网络传输的消耗,效率较高。b.不依赖于第三方中间件,实现方法和代码自己掌控,可随时调整。Proxy:a.提供一套HTTPRestful接口,隔离底层存储。对客户端完全透明,跨语言调用。b.升级维护较为容易,维护RedisCluster,只需要平滑升级Proxy。c.层次化存储,底层存储做冷热异构存储。d.权限控制,Proxy可以通过秘钥控制白名单,把一些不合法的请求都过滤掉。并且也可以控制用户请求的超大Value进行控制,和过滤。e.安全性,可以屏蔽掉一些危险命令,比如Keys、Save、FlushAll等。f.容量控制,根据不同用户容量申请进行容量限制。g.资源逻辑隔离,根据不同用户的Key加上前缀,来进行资源隔离。h.监控埋点,对于不同的接口进行埋点监控等信息。缺点SmartClient:a.客户端的不成熟,影响应用的稳定性,提高开发难度。b.MultiOp和Pipeline支持有限。c.连接维护,Smart客户端对连接到集群中每个结点Socket的维护。Proxy:a.代理层多了一次转发,性能有所损耗。b.进行扩容/缩容时候对运维要求较高,而且难以做到平滑的扩缩容实际项目中该如何选型呢?redis官方文档中有如下这段话:Theredis-cliclustersupportisverybasicsoitalwaysusesthefactthatRedisClusternodesareabletoredirectaclienttotherightnode.Aseriousclientisabletodobetterthanthat,andcachethemapbetweenhashslotsandnodesaddresses,todirectlyusetherightconnectiontotherightnode.Themapisrefreshedonlywhensomethingchangedintheclusterconfiguration,forexampleafterafailoverorafterthesystemadministratorchangedtheclusterlayoutbyaddingorremovingnodes.大意就是目前rediscluster官方客户端功能简陋,依赖于redis节点重定向去到集群中找到数据所在的redis实例。需要有一个更完善的客户端,能够实现一致性hash,failover和集群管理功能。因此使用官方的rediscluster客户端不是一个明智的选择,本文提供3种方案供大家参考,如果有不合理的地方,欢迎大家与我共同探讨。方案1使用nginx开发(OpenResty方式)原因如下a.单Master多Work模式,每个Work跟Redis一样都是单进程单线程模式,并且都是基于Epoll事件驱动的模式。b.Nginx采用了异步非阻塞的方式来处理请求,高效的异步框架。c.内存占用少,有自己的一套内存池管理方式,。将大量小内存的申请聚集到一块,能够比Malloc更快。减少内存碎片,防止内存泄漏。减少内存管理复杂度。d.为了提高Nginx的访问速度,Nginx使用了自己的一套连接池。e.最重要的是支持自定义模块开发。f.业界内,对于Nginx,Redis的口碑可称得上两大神器。性能也就不用说了。方案2codis(豌豆荚采用的基于代理的redis集群方案)参考codis官方文档是一整套缓存解决方案,包含高可用、数据分片、监控、动态扩态etc.。走的是Apps-代理-rediscluster,一定规模后基本都采用这种方式。方案3自己独立开发redis智能客户端主要实现redisslots管理,failover,一致性hash功能。以上就是笔者在实际工作中总结和研究的结果,能力所限,如果您有其它建议和好的思路,欢迎给我留言探讨。本头条号每天都会更新互联网相关的技术分享,欢迎大家订阅。