Redis集群里请求怎么调度,分发那些事儿聊聊
- 问答
- 2026-01-05 02:25:20
- 29
聊到Redis集群里请求怎么调度和分发,这事儿其实挺有意思的,你可以把它想象成一个大型超市,数据就是货架上的商品,如果超市很小,只有一个收银台(一个Redis节点),那所有顾客(客户端请求)都去那个收银台结账就行了,很简单,但当超市变得巨大,商品多到离谱(数据量很大),或者顾客人山人海(请求量很高),一个收银台肯定顶不住,会排长队,效率极低,这时候,超市就得开很多个收银台,并且要想办法告诉顾客,买不同类别商品的应该去哪个区域结账,Redis集群干的就是这个事儿。
这个“办法”的核心,叫做分片,简单说,就是把海量的数据砍成很多小块,每一小块数据放到一个Redis节点(也就是一个收银台)上去存,那具体怎么砍呢?Redis集群用了一个很聪明的机制,叫哈希槽。
(来源:Redis官方文档对集群规范的描述)Redis集群默认会把整个数据空间分成16384个槽位,你可以把这些槽位想象成编号从0到16383的小格子,每个节点会负责管理其中的一部分槽位,比如一个三主三从的集群,可能这么分:节点A管0-5460号槽,节点B管5461-10922号槽,节点C管10923-16383号槽,这样一来,所有的数据就被均匀地分摊到了三个主节点上。
接下来是关键问题了:当一个请求过来,比如客户端要写入一个键值对 set user:1001 "张三",集群怎么知道该把这个 user:1001 放到哪个槽位,从而找到对应的节点呢?
(来源:Redis集群使用的CRC16算法)它用了一个非常快的计算方法:对键名(也就是这里的 user:1001)做一个叫CRC16的校验运算,算出来一个数字,然后把这个数字对16384取个余数,公式大概是 slot = CRC16("user:1001") % 16384,这个计算结果是固定的,也就是说,只要你键名不变,算出来的槽位号永远是同一个数,这样,集群就能精准定位到任何一个键应该属于哪个槽。
知道了槽位号,又知道了每个槽位由哪个节点管理,那么理论上,请求就应该被发送到管理这个槽位的节点上去执行,这个“发送”的动作,就是请求的分发,这里有两种情况:

第一种情况是最理想的状态:客户端是“智能”的,意思是,客户端代码库(比如Java的Jedis,Python的redis-py)已经支持了Redis集群协议,它在启动的时候,会先从一个已知的集群节点那里拉取一份“槽位分布图”,这个图清晰地记录了0-16383每个槽现在由哪个节点(IP和端口)负责,拉取之后,客户端会自己在内存里缓存好这张图。
当你要执行 set user:1001 "张三" 时,这个“智能”客户端会先自己用CRC16算法算出 user:1001 属于槽5000,然后它一查自己缓存的那张分布图,发现槽5000是由节点A(假设IP是192.168.1.101:6379)管理的,好了,它就不会傻傻地把请求发给你最初连接的那个节点,而是直接通过网络连接把请求发送给节点A,节点A处理完后,把结果返回给客户端,这个过程非常高效,因为一步到位,没有中间商赚差价。
第二种情况是容错和重定向:但世界不是完美的,有时候客户端可能是“笨”的(比如老的客户端库不支持集群),它只会把请求随机发到一个节点,或者,客户端虽然是“智能”的,但它缓存的那张“槽位分布图”过时了——比如集群刚刚做了扩容,节点D加入了,重新分配了槽位,原来节点A管的槽5000现在归节点D管了。

这时候,如果客户端还把 set user:1001 "张三" 的请求发给了节点A,节点A一查,发现键 user:1001 计算的槽位5000现在已经不属于我管了,节点A不会直接拒绝请求,它会做一个非常关键的动作:重定向。
(来源:Redis集群的MOVED错误响应)节点A会给客户端回一个叫做 MOVED 的错误消息,这个消息非常友好,它不光告诉你“你找错地方了”,还会直接告诉你“你应该去XXX地方找”,消息内容大概是:MOVED 5000 192.168.1.104:6379,意思是,槽5000这个数据,现在归IP为192.168.1.104,端口为6379的节点D管理了。
“智能”客户端收到这个MOVED响应后,会做两件事:第一,立即根据这个新地址,把请求重新发节点D去执行;第二,也是更重要的,它会更新自己本地缓存的那张“槽位分布图”,把槽5000映射到节点D,这样下次再访问槽5000的数据时,它就能直接发对地方了,这个自我学习、自我更新的过程,保证了客户端能不断适应集群的变化。
还有一种重定向叫 ASK,它和MOVED有点像,但意义不同,ASK通常发生在集群正在迁移数据的过程中,比如槽5000正从节点A迁往节点D,可能大部分数据还在A那儿,但恰好 user:1001 这个键已经迁到D那儿了,如果客户端访问A,A发现自己没有这个键,但知道它可能已经在D上了,就会回复一个ASK重定向,客户端会根据ASK指示临时去节点D获取数据,但不会更新本地的槽位映射,因为它知道迁移还没完全结束,等迁移彻底完成后,它会收到一个MOVED指令再来更新,这相当于一个临时指路牌。
总结一下,Redis集群的请求调度和分发,核心就是靠哈希槽这把尺子来均匀分割数据,靠智能客户端缓存槽位分布图来实现高效直达,靠MOVED/ASK重定向机制来应对集群变化和保证鲁棒性,这一套组合拳打下来,就让一个分布式的Redis集群既能横向扩展,又能对外提供一致的服务。
本文由钊智敏于2026-01-05发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/74684.html
