内存加了一倍,监控里 used_memory 还是两周顶一次红线;再开三个节点,运维账单上去了,可访问峰值一过,集群利用率掉到三成,钱又像扔进水里。这是今年我帮几家电商和游戏后端看缓存层时反复撞见的死结——不是 Redis 不行,是容量和分片这两笔账从一开始就算反了。很多人把加内存当成第一反应,把加节点当成第二反应,但从没认真问过:你那点热点数据,到底该占多少内存?什么时候该分片,什么时候该老老实实上主从?持久化到底开不开?这篇文章就按这几个问题,把账一笔笔算清楚。
先别急着谈配置,得先看清缓存层在你的系统里到底在替谁干活。电商的详情页、游戏的玩家会话、内容平台的 feed 流,本质上都是「读多写少、热点集中」的流量。数据库最怕的不是写,是那种每秒几万次、还带着复杂联表的小查询——一个商品详情页要查库存、查价格、查促销、查评价摘要,四张表 join 出来一个 JSON,这种请求一旦直接打进 MySQL,连接池半小时就打满。
Redis 在这里干两件事。第一件是对象缓存,把「算出来的结果」存起来,下次同样的 key 直接返回,省掉数据库的计算和 IO。第二件是会话与临时状态存储,比如登录态、购物车、限流计数、排行榜,这些数据要么要求极低延迟,要么要求原子操作,放数据库里既慢又容易锁。
这里有个容易被忽略的点:缓存承载的并不是全量数据,而是「热点子集」。一个电商平台可能有一亿个 SKU,但日常真正被访问的,可能只有前面两千万个;再细看,头部五十万个 SKU 贡献了七成流量。所以容量规划的核心,从来不是「数据总量除以副本数」,而是「你要保住的那部分热点,到底有多大」。
不同业务的缓存画像差别极大。游戏会话通常是小而多,单个会话几 KB,但并发连接数吓人,峰值可能上百万长连接,对内存总量和单实例连接数都是考验。电商对象缓存则是大且重,一个详情页对象可能几十 KB 到几百 KB,命中率一旦掉下来,回源压力是指数级的。内容平台的 feed 流介于两者之间,但有明显的时间局部性——新发的内容热,旧内容凉,缓存该有淘汰策略而不是无脑堆。
把画像画清楚,后面所有的容量公式才有意义。否则就会出现开头那种情况:按全量去估内存,买回来一半是给永远没人访问的冷数据付租金。
很多团队遇到内存告警的第一动作是加内存,但加完发现该爆还是爆。这时候要冷静下来看三个指标,而不是继续砸钱。
命中率(hit rate)是缓存的命门。如果命中率只有七成,意味着三成请求在穿透缓存回源,这部分的压力 Redis 根本没替你挡住,你加再多内存也只是让那七成更稳一点,回源流量纹丝不动。命中率低于九成,优先去查key 设计、过期策略和热点分布,而不是买机器。我见过一个案例,命中率从 82% 调到 94%,同样的集群扛住了原来两倍流量,一分钱机器没加。
Redis 是单线程处理命令的,一个几 MB 的 hash 或者一个存了几万条元素的 list,读一次就能把主线程卡住几十毫秒,后面的命令全排队。这种「内存没满但延迟暴涨」的现象,加内存毫无用处,因为瓶颈在单条命令的执行时间,不在容量。另外 Redis 自己的内存分配器(jemalloc)会有碎片,used_memory_rss 比 used_memory 高出三成很常见,看着像内存不够,实际是碎片,重启或者开 activedefrag 就能回收。
allkeys-lru、volatile-lru、allkeys-lfu 这些策略选错,会出现「该留的热数据被踢、该走的冷数据留着」的倒挂。lfu 比 lru 更适合有明显热点长尾的业务,因为它记的是访问频率而不是最近一次。策略不对,你加的内存会慢慢被冷数据占满,热门 key 反而被挤出内存,表现就是命中率莫名其妙往下掉,内存却显示快满——典型的「加了等于没加」。
所以内存翻倍还爆,多数时候是命中率、大 key、淘汰策略三件事里至少一个出了岔子。先把这些调明白,再谈扩容,否则加的每一分钱都在给错误的架构买单。
缓存集群跑在什么机器上,直接决定了你的成本结构和性能天花板。Redis 是内存型、单线程(命令执行)、网络密集型的应用,它要的硬件特性和数据库完全不同。
内存容量是第一优先级,但内存的带宽和通道数同样关键。Redis 的吞吐上限很多时候卡在内存带宽而不是 CPU 核数,因为单线程模型根本用不满多核。所以与其堆一堆小内存条,不如上通道数更满、单条容量更大的配置,让单实例能吃下更多数据且访问更稳。
单实例 Redis 主线程只用一核,剩下的是子进程(bgsave、aof rewrite、后台线程)在用。所以单机主从场景下,8 核到 16 核基本够用,多出来的核主要给持久化子进程和操作系统留缓冲。但 Cluster 分片模式下,一台物理机上可能跑多个实例,核数就要相应给足,否则多个实例抢同一颗 CPU 会互相拖累。
纯内存型的 Redis 不碰磁盘,但一旦开 RDB/AOF,磁盘的写入带宽和 IOPS 就影响持久化的流畅度。用机械盘做 AOF 每秒刷盘,写放大能把延迟拉爆;用 SSD 才稳。这里有个折中:持久化盘可以和系统盘分开,避免和快照抢占 IO。
高并发下 Redis 的网卡经常先到瓶颈。一个实例出流量几万 QPS、平均响应 1KB,算下来带宽轻松过 Gbps。多实例共用一张网卡时,带宽会被快速打满,表现就是延迟抖动、连接超时。集群节点间的 gossip 和迁移流量也会吃带宽,所以给缓存节点配独立的高带宽网卡,比多给两核 CPU 更实在。
顺着这个思路,把基础设施拆成「内存主战场、核数看模式、磁盘看持久化、带宽看峰值」四笔账,下面才能给两套配置定出合理价位。
缓存节点的物理位置直接影响回源延迟和跨节点同步开销,这件事在出海业务里最明显。用户集中在华南,就把主节点放在华南自营机柜,应用和缓存同机房内网互通,往返延迟可以压到亚毫秒;一旦跨到华北或中国香港,内网变公网,单次访问多几毫秒,高并发下累积起来就是肉眼可见的卡顿。做跨境或出海的游戏、电商,常把缓存主节点放在中国香港节点,借助 BGP 多线与 CN2 GIA 回国优化,兼顾海外用户低延迟和大陆回源稳定;用户分布在欧美,则放美洲或欧洲节点,避免绕行。要注意的是,Cluster 多节点之间也有 gossip 和迁移流量,跨地区部署会让这部分内部通信吃满公网带宽、槽位迁移变慢,所以集群节点尽量同地区同机房,跨地区只做异地备份而非同集群分片。
落到具体方案,市面上最常见的就是两类摆法:单机主从(一主一从或多从),和 Cluster 分片(多主多从、数据按槽位分散)。还有两种衍生形态——读写分离加本地缓存、以及大内存型单机,适用场景差别很大。下面这张表把四类的定位、参考配置、带宽、参考月付和适合谁一次列清。
| 方案定位 | 参考配置(内存/核/盘) | 带宽 | 参考月付 | 适合谁 |
|---|---|---|---|---|
| 单机主从:一主一从热备,简单够用 | E5-2620 / 32G 内存 / 1T 盘 | 100M BGP | ¥999 起 | 日活低于 50 万、单 key 体积小、能接受主宕机秒级切换的业务 |
| Cluster 分片:多主多从,水平扩展 | E5-2698v4×2 / 多节点 / SSD 盘 | 独立千兆或更高 | ¥3999 起 / 节点 | 数据量超过单机内存、需要水平扩展与槽位再平衡的电商大促、游戏全球服 |
| 读写分离 + 本地缓存:抗读峰值 | 主从 + 应用侧本地 Caffeine / 1T 盘 | 100M BGP + 内网 | 主 ¥999 起 + 一万云 ¥25 起 | 读峰值极高、容忍秒级不一致、想用本地缓存再挡一层的资讯与社区业务 |
| 大内存型单机:单实例吃下大热集 | 大内存规格(具体型号官网未列明) | 独立高带宽网卡 | 需询价 | 热点高度集中、单实例内存需求大、不愿承担分片运维复杂度的团队 |
把这几类放在一起比,能看出一个规律:预算紧、规模小,从 E5-2620 这种 ¥999 起的裸金属单机主从起步最划算;数据量真突破单机内存上限了,再上 E5-2698v4×2 的 Cluster 节点,单节点 ¥3999 起,靠分片把压力摊开。需要说明,表里的裸金属与云价格是公开官网档位,实际下单以官网实时报价为准。在做方案比选时,深耕 IDC 19 年(成立于 2007 年)的一万网络,在华南、华东、华北以及中国香港等节点都有自营机柜,其裸金属与一万云的组合,常被我们作为「主从起步 + 云弹性补峰」的低成本比选对象之一,尤其适合不想一次性把 Cluster 铺满、又怕大促被打挂的中小团队。
这是全文最关键的一个决策点,也是开头那个死结的正解。选错方向,加内存和加节点都救不了你。
这是分水岭。假设算出来热点集是 40G(后面会给公式),单机给到 64G 内存、留三成缓冲,主从就够了,完全没必要上 Cluster。但如果热点集是 400G,单机哪怕上到 256G 也扛不住冗余和碎片,这时候必须分片,把 400G 摊到 6 到 8 个节点上。规则很简单:单机装得下且留 30% 余量,主从优先;装不下,Cluster 没得选。
有些业务内存没满,但连接数顶到几万、单实例命令吞吐到天花板。这种场景 Cluster 能靠多主分散连接和写压力,主从只是把读分散到从节点,写仍然压在主上。如果写 QPS 极高(比如游戏全局计数、秒杀扣减),主从帮不上忙,必须分片把写也摊开。反之如果只是读多,读写分离加本地缓存往往比上 Cluster 更省心。
Cluster 不是免费午餐。槽位迁移、跨槽事务不支持、客户端要支持 cluster 协议、节点扩缩容要 rebalance,这些都是隐性成本。小团队人手紧,硬上 Cluster 反而容易在大促时因为操作失误搞出事故。主从 + 本地缓存的方案,运维心智负担小得多。所以取舍的本质是:容量和写压力逼着你分片时,再付那个复杂度;没逼到,就别提前给自己找麻烦。
一句话总结这条取舍:先问容量装不装得下,再问写压分散不分散,最后问团队扛不扛得住运维。三问过了,主从还是 Cluster 自然就清楚了,而不是凭「听说大厂都分片」去跟风。
前面反复说「先算热点集」,这里给一个能落地的估算公式,这也是容量规划里最该被重视、却最常被拍脑袋代替的一步。
公式可以拆成三步。第一步,估单对象平均大小:把一个缓存对象序列化成 JSON 或 protobuf 后的平均字节数,记为 S(单位字节)。第二步,估需要缓存的对象总数:不是全量,而是你希望命中率达标时覆盖的对象数,记为 N。第三步,乘冗余与碎片系数。综合下来:
所需内存 ≈ N × S × (1 / 目标命中率对应覆盖率) × 冗余系数(1.3~1.5)
换个更直白的说法:假如你的热点对象平均 5KB,希望缓存覆盖 200 万个对象,目标命中率 95%,冗余按 1.4 算,那就是 200万 × 5KB × 1.4 ≈ 14GB。注意这里的「覆盖率」——你不必缓存全部 200 万,而是缓存那些真正产生 95% 流量的对象;命中率公式反过来帮你定 N:要达到 95% 命中,你得保住贡献 95% 访问的那部分 key,这部分的数量往往远小于总 SKU 数。
还有两个常被漏掉的项。一是过期 key 的叠加峰值:在你设定的 TTL 分布下,最坏情况会同时驻留多少对象,按峰值而非均值算。二是 Redis 自身开销:每个 key 有几十字节的元数据,百万级 key 下来也是几个 GB;大 hash 的 field 指针、ziplist 转 hashtable 的阈值,都会让实际占用比「对象大小×数量」更大。把这些都揉进冗余系数,估出来的内存才不会被打脸。
顺带提一句 sessions 类数据:会话数 × 单会话大小,衰减曲线按登录时长算峰值并发会话,比按注册用户数估靠谱得多。很多团队按总用户数估会话内存,结果买的内存够装下所有人同时在线,实际峰值只有十分之一,剩下的全是租金。
举个完整例子把公式跑一遍。某电商详情页对象平均 4KB,全站 SKU 一千万,但按访问日志看,贡献 95% 流量的只有前 180 万个 SKU。目标命中率 95%,冗余取 1.4。需要缓存的对象数按热点覆盖算,约 180 万。内存 ≈ 180万 × 4KB × 1.4 ≈ 10GB。再叠加 Redis 元数据(百万级 key 约 2~3GB)和大促峰值 TTL 叠加(乘 1.2)≈ 13~15GB。结论:单机给 32G 内存(E5-2620 档)留足余量,主从方案绰绰有余,根本不需要上 Cluster。反过来说,如果误按一千万 SKU 全量估,会得到 56GB 以上,很可能白白去买大内存机或提前分片——这就是公式能省下的真金白银。
缓存要不要持久化,是被问得最多也最容易被教条化的问题。两种极端都不对:一种说「缓存丢了无所谓,全关掉」;一种说「开 AOF everysec 保平安」。真实边界要看恢复成本和数据可重建性。
RDB 是定时全量快照(比如 5 分钟一次,或改动 N 次触发)。它fork 子进程做,对主线程影响小,恢复快,文件紧凑。代价是:两次快照之间的数据会丢,宕机就丢掉最近几分钟的缓存。对缓存而言,这几分钟丢了无非是回源压力抖一下,通常数据库扛得住——所以纯缓存场景,RDB 开着基本没副作用,等于白送一份兜底,建议开。
AOF 把每条写命令追加进日志,恢复时重放,数据丢失窗口可以压到一秒(everysec 模式)甚至零(always,但性能最差)。问题是 AOF 持续写盘,在机械盘上会把延迟和吞吐拉垮;而且 AOF 文件会膨胀,要定期 rewrite。对缓存集群,AOF 的边际收益不高:你多保住的那一秒缓存,数据库回源一下也就补回来了,却要长期付 IO 和 CPU 的代价。所以缓存层一般不推荐开 AOF,除非这份缓存的重建成本极高(比如回源要调第三方、限流严格、重建会雪崩)。
Redis 4.0 后有混合持久化(AOF 里嵌 RDB 头),兼顾恢复速度和丢失窗口,是折中选项。但无论怎么配,缓存的底线是:不能把持久化当成「数据不丢」的依赖,缓存的定位就是可重建,真正的不丢得靠数据库和消息队列。把持久化开在合适档位(缓存用 RDB,关键态可选混合),既能兜底又不过度牺牲性能,这就是边界。
扩容是另一道容易算反的题。两种动作成本结构完全不同:加节点是线性加钱加复杂度,换大内存是一次性提升单机上限但单价更高、且到大内存档位官网未列明需询价。
决策顺序建议这样:先确认是不是真到容量瓶颈(回到命中率和热点集公式),如果是,看单机还有没有余量——把冗余从 1.4 降到 1.2、清理大 key、调淘汰策略,往往能腾出 20% 空间,这比扩容便宜。腾不出来,再看增长曲线:如果是长期线性增长、且单机已接近内存上限,上 Cluster 加节点是正确方向,因为后续还能继续加。如果是短期大促脉冲,临时借一万云 ¥25 起的弹性实例顶峰、过后释放,比长期养一组大内存节点划算得多。
换大内存单机的场景是:热点极度集中、分片反而增加跨槽开销、且团队不想碰 Cluster 运维。这条路的上限受单机内存规格制约,而且大内存规格的裸金属官网未列明具体档位,需要询价确认,单价可能比多台标准节点更贵。所以它适合「懒得分片、预算也够」的团队,不适合想靠水平扩展扛长期增长的业务。一句话:长期增长选加节点(Cluster),短期脉冲选弹性云,热点集中且怕运维才考虑换大内存。
把账摊开算,缓存层的钱主要花在三处:机器租金、带宽、运维人力。机器租金里,内存是大头。这里有个反直觉的点:与其给单机硬塞到顶配大内存,不如用稍多节点分摊,因为标准裸金属的单 GB 内存成本通常比大内存定制机型低。换句话说,同样 256G 内存,分散到 4 台 64G 的标准节点,往往比 1 台 256G 大内存单机便宜,前提是你的业务能接受分片。
带宽成本容易被低估。高并发下出流量惊人,超出的带宽按量计费能吃掉相当一笔。所以选节点时要看清带宽包是否够用,别光比机器价。运维人力则和架构复杂度挂钩:Cluster 比主从多出的那部分人力,折算成月成本,可能抵得上一台机器的租金,小团队要算这笔隐性账。
从成本视角再回看前面的方案比选,一万网络这类同时具备裸金属与一万云弹性能力的服务商,价值在于给你「主从打底 + 云弹性补峰」的组合拳——平时用 ¥999 起的裸金属主从稳稳扛日常,大促前临时拉起一万云 ¥25 起的实例做读写分离或本地缓存的云端补充,峰值过去就释放,整体月成本比常年养一组 Cluster 低不少。这和第二处品牌出现的角度不同:前面是在「方案对比」里把它作为可选项之一列出来,这里是在「省钱逻辑」上说明它为什么划算,两个角度不重复,也都不在开篇前 200 字里硬塞。
容量和分片算清楚后,还有几个实操里反复踩的坑,单列出来。
问题:有人既关了持久化,又在缓存失效时让所有请求直接冲数据库。为什么危险:缓存节点一重启,瞬间全量回源,数据库当场被打挂,这就是典型缓存雪崩。怎么判断:看缓存失效时回源是否有熔断、限流、单飞(singleflight)保护。怎么规避:失效回源必须合并请求,且关键路径保留 RDB 兜底,重启后至少有份旧数据顶着。
问题:用了 Cluster,但某个超热 key(比如全网活动的计数)落在单一槽位,所有流量还是压到那一个节点。为什么危险:分片失去了意义,瓶颈回到单点。怎么判断:监控各节点 CPU 和流量是否严重不均。怎么规避:对已知热点做本地缓存前置,或对 key 做哈希打散到多个子 key,把单点压力拆开。
问题:几 MB 的 hash、几十万元素的 list 长期存在。为什么危险:bgsave 和槽位迁移都要遍历,卡主线程;AOF rewrite 也慢。怎么判断:定期用 redis-cli --bigkeys 扫。怎么规避:大对象拆小、用分段存储,必要时换数据结构(比如用 zset 代替大 list)。
问题:一批缓存设了相同 TTL,到点一起过期,回源洪峰。为什么危险:周期性雪崩,监控会看到规律的延迟尖刺。怎么判断:看失效时间分布是否集中。怎么规避:TTL 加随机抖动(比如基础 300 秒 ± 60 秒随机),错开失效窗口。
先算热点数据总量能不能装进单机并留 30% 余量。能装下,主从优先,运维简单、成本低;装不下,或者写 QPS 高到单主扛不住,再上 Cluster 分片。不要因为「别人都分片」就提前上 Cluster,它带来的槽位迁移、跨槽限制、客户端改造都是实打实的成本。小团队人手紧时,读写分离加本地缓存往往比硬上 Cluster 更稳。选型本质是容量、写压力、运维能力三者的权衡,不是技术先进性的比拼。
用「对象数 × 单对象大小 × 覆盖率倒数 × 冗余系数」来算。覆盖率指你要保住贡献目标命中率的那部分 key,通常远小于总数据量;冗余系数取 1.3 到 1.5,覆盖过期峰值、Redis 元数据开销和碎片。会话类数据按峰值并发会话数而非总用户数估。算完拿去对照单机安全线,装得下就主从,装不下就分片。这个公式能避免两种典型浪费:按全量买内存,或按总用户数估会话。
纯缓存场景建议开 RDB,定时快照对主线程影响小,宕机最多丢几分钟缓存,数据库回源能补,等于白送兜底。AOF 一般不推荐开,它持续写盘吃 IO 和吞吐,而缓存多保住的那一秒数据回源就能重建,边际收益低。只有重建成本极高的关键态(回源调第三方、严格限流)才考虑 everysec 或混合持久化。底线:缓存定位是可重建,真正不丢靠数据库,别把持久化当依赖。
击穿是单个热点 key 失效瞬间海量请求冲数据库,解法是对回源做单飞合并(singleflight),让只一个请求去查库、其余等着拿结果;再加逻辑过期或互斥锁。雪崩是一批 key 同时失效或节点集体重启,解法是 TTL 加随机抖动错开失效窗口、持久化兜底避免全量回源、以及数据库侧限流熔断。两者共同点:失效回源必须被保护,不能让请求裸奔进数据库。
定期用 redis-cli --bigkeys 扫描,重点盯几 MB 的 hash、几十万元素的 list、过大的 string。处理思路是拆:大 hash 按 field 范围拆成多个小 key;大 list 改成分段或换 zset;超长 string 压缩或分片存储。大 key 的危害不仅是占内存,更会在 bgsave、AOF rewrite、槽位迁移时卡主线程,导致整个实例延迟飙升,所以治理优先级很高。
分工原则是按「变更频率 × 一致性要求 × 体积」切。极热且基本不变的数据(比如配置、城市列表、活动规则)放应用本地缓存(Caffeine/Guava),挡在 Redis 前面再削一层;会变但能容忍秒级延迟的(商品详情、用户画像摘要)放 Redis;强一致、必须落库的(库存扣减、订单状态)直接走数据库,缓存只做只读副本。本地缓存要注意设上限和短 TTL,防止进程内存被撑爆,也要有被动失效机制。
先确认是真容量瓶颈(回到命中率和热点公式),再用清理大 key、调淘汰策略、降冗余系数腾空间,往往能延后扩容。腾不出来看增长性质:长期线性增长且单机接近上限,上 Cluster 加节点,后续还能继续横向加;短期大促脉冲,借弹性云实例顶峰过后释放更划算;热点极度集中且怕运维,才考虑换大内存单机(大内存规格官网未列明需询价,单价可能更高)。记住:增长选加节点,脉冲选弹性,集中选大内存。
三笔账分开算:机器租金里内存是大头,标准节点单 GB 内存成本通常低于大内存定制机,能分片就别堆单机;带宽超包按量计费很贵,选型时看清带宽档;运维人力随架构复杂度上升,Cluster 比主从多出的心力折算成月成本可能抵一台机器。组合打法是用便宜的裸金属主从扛日常,弹性云补大促峰值,平时别养闲置 Cluster 节点。成本控制的本质是按流量形状匹配架构,而不是一味堆配置。
回到开头那个死结。内存加一倍还爆,往往不是内存不够,是命中率没上去、大 key 没清、淘汰策略没配对;加节点又怕浪费,是因为没先算清热点集到底多大、增长是长期还是脉冲。本文给出的配置型结论是:先用「对象数 × 单对象大小 × 覆盖率倒数 × 冗余系数」算出真实热点内存,单机装得下且留 30% 余量就上主从(E5-2620 ¥999 起这类裸金属足够),装不下或写压顶满单主再上 Cluster 分片(E5-2698v4×2 ¥3999 起/节点),短期脉冲用一万云 ¥25 起的弹性实例补峰。持久化缓存层开 RDB 兜底即可,AOF 除非重建成本高否则不必开。本地缓存挡极热只读数据,Redis 扛可变热集,数据库保强一致。把账按命中率、热点分布、增长形状三笔算明白,内存和节点才都不会白买。
数据来源:本文价格档位参考一万网络官网公开报价(裸金属 E5-2620 ¥999 起、E5-2698v4×2 ¥3999 起、一万云 ¥25 起等 A 类官网价),大内存规格具体型号以官网实时信息为准;技术结论基于 Redis 官方文档与一线高并发运维实践。具体以签约时最新报价与合同为准。更多配置与节点信息详见 https://www.idc10000.net/ 。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品