当前位置:首页 > 问答 > 正文

Redis集群老男孩面对的新难题和那些没完没了的挑战

开始)

对于一群从Redis早期版本就开始摸爬滚打、自诩为“老男孩”的运维和开发者来说,他们曾经亲手搭建主从复制、用哨兵(Sentinel)搞定高可用,甚至可以说是看着Redis成长起来的,但当业务规模膨胀到必须采用真正的分布式集群模式时,他们发现,过去那套娴熟的经验似乎有些不够用了,一系列新的、更复杂的难题像打地鼠一样不断冒出来。

第一个拦路虎:数据迁移的“阵痛”与不确定性。 在过去单实例或简单主从时代,扩容就是加个从库那么简单,但到了集群模式下,扩容意味着resharding(重新分片),数据要在各个节点间来回搬运,这个过程可不是点一下按钮就完事的,根据很多踩过坑的工程师分享,在数据迁移期间,集群性能会受到影响,偶尔会出现短暂的卡顿,更让人头疼的是,如果迁移过程中源节点或目标节点发生故障,或者网络出现波动,整个迁移过程就可能卡住甚至失败,留下一个数据不一致的“烂摊子”等着手动去处理,这种不确定性让每次扩容缩容都像是一场赌博,运维人员得紧盯着监控屏幕,心里捏着一把汗。

Redis集群老男孩面对的新难题和那些没完没了的挑战

第二个烦心事:客户端得变得“聪明”起来,但这带来了复杂性。 单机Redis时,客户端随便连一个地址就行了,集群模式下,客户端必须支持集群协议,它需要知道整个集群的拓扑结构:哪个分片(slot)在哪个节点上,当用户访问一个key时,是客户端自己根据CRC16算法算出这个key属于哪个分片,然后直接连接到正确的节点上去操作,这听起来很智能,但问题也随之而来,不是所有语言的客户端都对集群支持得那么好、那么稳定,有些冷门语言的客户端可能bug不少,当集群发生变更时,比如主节点切换或者扩容缩容,集群的拓扑结构会变化,客户端需要及时感知并更新本地缓存的路由表,如果客户端没能及时更新,或者遇到了网络分区等异常情况,就会导致大量的“MOVED”或“ASK”重定向错误,请求延迟飙升,业务方立马就能感觉到“系统变慢了”,这让“老男孩”们不得不花大量时间去测试、选型和维护这些“聪明”的客户端,生怕它们在某些边缘情况下“犯傻”。

第三个没完没了的挑战:“热点”key问题变得难以处理。 在单机时代,如果出现一个热点key,比如某个明星出轨的消息导致全站都在读同一个key,至少问题很集中,可以考虑给这个实例升配或者做本地缓存,但在集群环境下,一个热点key通过哈希计算后,只会落在某一个特定的节点上,这意味着,对这个key的海量请求会全部压向集群中的某一个节点,瞬间把这个节点的CPU和网络带宽打满,而集群中的其他节点却非常空闲,这种“一家忙死,多家围观”的局面,让集群的水平扩展能力在这个热点key面前形同虚设,解决起来非常棘手,可能需要业务端改造,对热点key进行打散(比如在key后面加随机后缀),或者引入额外的二级缓存机制,这些都超出了单纯运维Redis集群的范畴,需要更深入的业务协作和架构设计。

Redis集群老男孩面对的新难题和那些没完没了的挑战

第四个让人头疼的点:监控和故障排查的复杂度呈指数级上升。 以前监控一个Redis实例,看几个关键指标就行了,现在是一个由几台甚至几十台机器组成的集群,监控对象变成了一个整体,你需要关注的不仅仅是单个节点的内存、CPU、连接数,更要关注集群级别的状态:集群是否健康?所有分片是否都有主节点?节点间的心跳是否正常?数据同步的延迟有多大?任何一个节点的小毛小病,都可能被集群放大,导致雪崩效应,当出现问题时,排查链路也变得非常漫长,一个慢查询可能不是由接收请求的那个节点引起的,而是因为它访问了一个在另一个节点上的大key,需要跨节点协调,日志散落在各个节点上,拼凑出一个完整的请求链路需要花费成倍的时间。

第五个持久存在的挑战:资源规划与成本控制的矛盾。 集群模式本是为了突破单机内存限制,但内存资源的管理变得更精细也更困难,由于数据是分片存储的,很难像单机那样简单地通过“总数据量除以总内存”来估算需要多少节点,因为数据分布可能不均衡,即使总内存足够,也可能因为某个分片的数据量过大导致节点内存溢出,为了避免这种情况,“老男孩”们往往需要设置一个较高的内存水位线作为安全阈值,比如每个节点用到70%内存就报警扩容,这实际上造成了不小的资源浪费,集群模式下的节点数量通常是奇数且至少三个主节点起步,对于中小型项目来说,维护一个集群的资源成本和运维成本,可能远高于业务实际需求,给人一种“杀鸡用牛刀”的负担感。

对于Redis的“老男孩”们而言,拥抱集群就像是从一个熟悉的村庄搬进了一个庞大的现代化都市,他们获得了前所未有的扩展能力,但也必须面对交通拥堵(热点)、复杂的城市管理规则(客户端路由)、频繁的基础设施施工(数据迁移)以及更庞大的监控系统,这些新难题和没完没了的挑战,要求他们不仅要懂Redis本身,还要对分布式系统的原理、网络知识有更深刻的理解,并且需要极强的耐心和细致入微的观察力,这条路,学无止境。 结束)