“兄弟,我跟你说,我今天差点当场原地升天。”
我一屁股瘫在工位上,把电脑包往桌上一丢,整个人像从 40°C 的机房里逃出来一样。隔壁工位的小王抬头看了我一眼:“咋了,又面试了?”
我点点头:“对,还是社招那套八股文。但今天这个面试官,兄弟,堪称 Redis 分区界的李白——题目一出,直接把我送上天。”
小王哈哈一笑:“Redis 分区那玩意?”
我沉默五秒:“……对,就是这个,把我整不会了。”
于是,今天这篇文章就诞生了。希望能救你们一命,哪怕只救一个,咱都算功德无量。
接下来,小米我就用最直白、最故事的方式,把“为什么要做 Redis 分区?有哪些方案?每种方案有哪些坑?”讲得明明白白。
故事开始:Redis 为什么需要分区?问你个问题:
“你知道什么时候 Redis 单实例会扛不住吗?”
听上去像灵魂拷问,但实际在生产中太常见了。想象一下你有一个 Redis 实例,里面塞了几千万个 key,数据量 20GB、30GB 地往上涨,写 QPS 上万级别。有一天你发现:
机器内存快满了;
单线程 CPU 飙到天花板;
RDB 或 AOF 时,延迟像坐火箭;
重启恢复时需要十几分钟;
客户端操作开始一卡一卡的。
这时候,你的 Redis 就好比一个人同时扛两个冰箱外加一袋四十斤大米,压得嗓子都快挤不出声了。这就是 Redis 分区要解决的根本问题:
单实例容量瓶颈(内存不够):Redis 是基于内存的,不做分区就只能靠升级机器加内存,但你总不能给它上 1TB 内存吧?
单实例吞吐瓶颈(CPU 不够):Redis 的所有命令都在单线程上执行。单线程处理能力是有限的,再怎么优化,CPU 总有天花板。
主从架构也救不了你:主从只能解决读扩展,解决不了写扩展,也解决不了内存问题。
所以,面试官问你:
“为什么要 Redis 分区?”
你只需要底气十足地回一句:
“因为 Redis 单实例有三大瓶颈:内存瓶颈、吞吐瓶颈和主从写扩展能力不足。分区能让我们横向扩展 Redis,突破单节点能力限制。”
记住,有理有据,稳稳的。
Redis 分区有哪些方案?面试官最想听你说这段当面试官继续问:
“那你知道 Redis 有哪几种分区方案吗?”
我的脑袋当时一片空白,只剩下一行代码在闪烁。
回家回忆了一晚上,终于给你们整理出了 Redis 分区的三大主流方案,用小米的风格总结一下就:
Redis 分区可以分为 3 类:客户端分区、代理分区(中间件分片)和 Redis Cluster(服务端分片)
下面我就用一个故事,让你彻底记住这三种设计。
客户端分区:客户端自己决定把 key 放哪想象你有 3 个 Redis 实例:A、B、C。客户端收到一个 key,比如 “user:100”,它自己做如下步骤:
对 key 做 hash
取模
得到应该放到 A 或 B 或 C
这叫客户端分区,也是最传统的办法。Jedis Sharding、Redisson 的分区功能,都属于这种方式。
优点:
实现简单;
客户端直接知道 key 在哪台 Redis,不需要中转;
请求链路最短,性能好。
缺点致命:
客户端要维护路由规则,业务代码耦合;
节点变化(迁移、扩容、缩容)要改配置;
key 无法跨节点操作(比如 mget、事务、lua 都不行)
总结一句:
客户端分区适合小团队早期,简单暴力;但随着业务发展,会越来越痛苦。
代理分区(Proxy):Redis 上加一个中间件帮你分片比如:
Twemproxy(Twitter)
Codis(国内大厂用得最多)
Dynomite(Netflix)
这种方式是这样玩的:
客户端 → 代理服务器 → 多个 Redis 实例
所有 key 的路由都由代理负责。客户端完全不知道 Redis 背后有多少台机器,它只需要连代理就行。
优点:
对客户端透明,业务接入简单;
可动态扩容缩容;
代理可以做连接池、监控、故障转移。
缺点:
多了一层代理,增加延迟;
代理是额外组件,需要运维;
代理本身可能成为瓶颈(除非做 Proxy 集群)
总结一句:
Proxy 让 Redis 分区变得可控,但你得付出复杂度和延迟代价。Codis 是其中最成熟的方案。
Redis Cluster:官方原生分区方案2015 年之后最主流的方案。Redis Cluster 不需要代理、不需要客户端做 hash,它内部有 16384 个 hash slot。每个 master 管一部分 slot,客户端只要知道 key 属于哪个 slot,就能直接访问对应节点。
最妙的是:
节点之间互相通信
客户端自动跟随重定向(MOVED/ASK)
支持自动故障切换
支持横向扩容缩容
优点:
官方方案,成熟稳定;
支持自动 failover;
支持动态扩容;
不需要代理这一层。
缺点:
无法保证多 key 操作(除非 key 在同一个 slot);
运维复杂度比单实例高一些;
业务必须使用 cluster 兼容客户端;
对 bigkey、慢查询处理较严格。
总结一句:
Redis Cluster 是目前最推荐的生产方案,兼顾扩展性和稳定性。
Redis 分区有什么缺点?能不能在面试里说漂亮?当面试官问你:
“那你觉得 Redis 分区最大的缺点是什么?”
请你千万别回答:
分区很好,没有缺点。
缺点不多。
这种回答只会让面试官觉得你没动过生产环境。正确答案必须包括以下几个核心痛点:
跨节点操作受限(最大痛点)比如:
mget
multi / exec 事务
lua 脚本涉及多个 key
rename
keys 命令
scan 全库扫描
只要 key 分布在不同节点,就直接凉凉。这是 Redis 分区的本质问题,任何方案都无法完美规避。
路由复杂度增加不管是客户端、代理还是 Cluster,都需要路由规则。路由意味着:
要维护节点列表
要支持迁移
要处理重定向
要处理 hash slot
越复杂的系统,越容易出错。
数据迁移成本高扩容 Redis Cluster 时,迁移 slot 要占用带宽和机器性能。
机器本来就忙,你再迁移数据,就等于往火上浇油。
运维复杂度上升分区意味着:
多实例监控
多实例故障处理
多实例平衡
多实例数据一致性
单实例 Redis 10 分钟能搞定的问题,分区后可能要 2 小时。
热点 key 问题更严重你分区只是分散 key,不是分散压力。如果有个 key 被疯狂读写,比如:
排行榜
用户状态
高频计数器
那这个节点依然会被打爆。
总结:面试官真正想听到的版本如果你在面试中被问到 Redis 分区,你可以用我下面这段“标准答案”,基本能稳稳通过。
1、面试官:为什么要做 Redis 分区?
你:
Redis 单实例会遇到三大瓶颈:内存瓶颈、吞吐瓶颈、以及主从架构无法扩展写能力。为了突破单节点限制,我们需要用分区的方式把数据打散到多个实例上,实现水平扩展。

2、面试官:有哪些 Redis 分区方案?
你:
Redis 分区方案主要有三类:
客户端分区:客户端做 key 到节点的路由,比如 Jedis Sharding。简单但业务耦合高。
代理分区:通过 Proxy 组件分片,比如 Codis、Twemproxy。对客户端透明,但增加延迟。
Redis Cluster:官方原生分区,通过 16384 hash slot 分片。支持自动故障切换和扩容,是目前最主流最推荐的方案。

3、面试官:Redis 分区有什么缺点?
你:
主要有五点:
跨节点操作受限(多 key 操作是最大痛点)
路由规则复杂
扩容迁移成本高
运维难度增加
热点 key 仍可能集中在单节点

小王问我:“那你今天回答怎么样?”
我叹口气:“哈哈,兄弟,我 Redis Cluster 部分讲了十分钟,感觉面试官嘴角都上扬了。”
小王竖起大拇指:“你这不是挺厉害的吗!”
我摇头:“后面他问‘Redis Cluster 节点之间是怎么感知对方存活的?广播用啥机制?’我当场卡壳了。”
小王扑通一声笑倒在椅子上:“这面试官太狠了!”
我摊手:“所以啊,我今天把 Redis 分区这篇文章写出来,就是确保你们以后不会像我一样翻车。”
END我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!