华为云 DCS Redis 实战:实例类型选型、大 Key 与热 Key 治理、缓存三大问题和高可用避坑指南

举报
欣然过了 发表于 2026/11/04 09:28:17 2026/11/04
【摘要】 结合华为云分布式缓存服务 DCS for Redis 的使用场景,梳理单机、主备、集群等实例类型的选型思路,Key 设计与大 Key、热 Key 的治理,缓存穿透、击穿、雪崩的应对办法,过期与内存淘汰策略,持久化与故障切换时应用端的处理,以及上线前检查清单。文中规格与参数请以官方文档和控制台为准。

前言

Redis 几乎是后端系统里最常见的缓存组件。把自建 Redis 换成云上的分布式缓存服务 DCS 之后,部署、监控、主备切换和版本升级由平台承担,但「缓存用得好不好」依然取决于使用方式:同样一个实例,有的团队跑了几年都很稳,有的团队却三天两头遇到内存打满、延迟抖动、主备切换后数据对不上。本文结合 DCS for Redis 的使用场景,按「实例类型选型、Key 设计、缓存三大问题、过期与淘汰、高可用与持久化、监控与上线清单」的顺序整理一套思路。文中涉及的规格、容量、默认参数和命令限制,请以华为云官方文档和控制台页面为准,这里讲的是思路,不是固定参数。

一、实例类型怎么选

DCS for Redis 通常提供单机、主备、读写分离、Proxy 集群、Cluster 集群等不同形态,具体可选项以控制台为准。选型时不要只看容量,要先回答下面几个问题:

  • 数据丢了能不能接受:只做纯缓存、数据丢失后可以从数据库回源的场景,单机版在开发测试环境够用;生产环境一般选主备,主节点故障时可以自动切换到备节点。
  • 单实例的内存和带宽够不够:当数据量或 QPS 超过单个分片的承载能力时,要考虑集群版,把数据分散到多个分片。但集群并不是没有代价,跨分片的多 Key 操作、事务和 Lua 脚本都会受到限制。
  • 读多写少且读流量很大:可以考虑读写分离形态,由从节点分担读请求,但要接受从节点的数据存在复制延迟。
  • 是否依赖特定命令或版本:不同版本支持的数据结构和命令不同,应用用到的新特性要先在目标版本上验证,开发、测试、生产环境建议保持同一大版本。

容量方面有一条经验:不要把内存用到接近 100%。持久化、主备同步、碎片和客户端缓冲区都需要额外内存,一般建议在业务数据量的基础上预留一定余量,并设置内存使用率告警。

二、Key 设计:从源头避免大 Key 和热 Key

绝大多数 Redis 性能事故,都能追溯到 Key 的设计。

  • 命名要有规范:建议采用「业务名:模块:主键」的层级形式,比如 order:detail:1001。这样便于排查、批量清理,也避免不同业务之间互相覆盖。Key 本身不宜过长,否则会白白占用内存。
  • 避免大 Key:单个 String 过大,或一个 Hash、List、Set、ZSet 里装了几十万甚至上百万个元素,都属于大 Key。读写大 Key 会长时间占用单线程,造成其他请求排队;删除大 Key 也会造成阻塞;集群场景下还会让某个分片的内存明显高于其他分片。治理方式是拆分:把一个大 Hash 按照哈希取模拆成多个小 Hash,把超长列表按时间或数量分段。
  • 避免热 Key:某个 Key 的访问量远高于其他 Key,会把压力集中到单个节点上,即使是集群也无法分摊。常见做法是在应用进程内增加一层本地缓存并设置较短的过期时间,或者把热 Key 复制成多份带后缀的副本,读取时随机选择一份。
  • 慎用全量遍历命令:KEYS、对大集合执行 SMEMBERS、HGETALL 等命令在数据量大时会阻塞实例。遍历应使用 SCAN 系列命令分批进行,并控制每批数量。删除大集合时优先使用异步删除的方式,具体命令请确认所用版本是否支持。

发现大 Key 和热 Key 的办法可以是:使用控制台提供的诊断分析功能(以实际功能为准),或者在业务低峰期用 SCAN 配合类型和长度命令抽样统计,不建议在高峰期对生产实例做全量扫描。

三、缓存穿透、击穿与雪崩

这三个问题名字相近,成因和应对完全不同:

  • 缓存穿透:请求的数据在缓存和数据库中都不存在,每次请求都落到数据库。应对方式包括:对参数做合法性校验;对查不到的结果也缓存一个短时间的空值;对于数据范围已知的场景,可以在前面放布隆过滤器。
  • 缓存击穿:某个热点 Key 恰好过期,大量并发请求同时回源数据库。应对方式包括:热点数据设置更长的过期时间或逻辑过期;回源时使用互斥锁,只允许一个请求去加载,其他请求稍等后重新读缓存。
  • 缓存雪崩:大量 Key 在同一时刻过期,或者缓存实例整体不可用,导致数据库被压垮。应对方式包括:过期时间在基础值上加随机偏移;多级缓存;对数据库访问做限流和降级;缓存实例使用主备或集群保证高可用。

下面是一个加随机过期时间并使用互斥锁回源的伪代码,仅作示意:

String key = "product:detail:" + id;
String value = redis.get(key);
if (value != null) return value;

String lockKey = "lock:" + key;
// SET key value NX EX 10:只有一个请求能拿到锁,锁带过期时间避免死锁
if (redis.set(lockKey, requestId, "NX", "EX", 10)) {
    try {
        value = db.query(id);
        int ttl = 600 + random.nextInt(120);   // 基础过期时间加随机偏移,避免同时失效
        redis.set(key, value == null ? "" : value, "EX", value == null ? 60 : ttl);
    } finally {
        // 释放锁时应校验持有者,生产中建议用 Lua 脚本保证原子性
        releaseLock(lockKey, requestId);
    }
} else {
    Thread.sleep(50);
    return retryGet(key);
}
return value;

四、过期与内存淘汰:别把缓存当数据库

Redis 的内存是有限的,当内存达到上限时,行为取决于淘汰策略(maxmemory-policy,具体可选值以所用版本和控制台为准)。常见的几类行为是:不淘汰直接报错、在所有 Key 中按最近最少使用淘汰、只在设置了过期时间的 Key 中淘汰、随机淘汰等。使用时要注意:

  • 纯缓存场景通常适合选择带 LRU 或 LFU 的淘汰策略,让不常用的数据自动让位;
  • 如果实例里同时放了缓存和不能丢的数据(比如分布式锁、计数器、会话),一旦使用「只淘汰带过期时间的 Key」或「全部淘汰」的策略,就要清楚哪些 Key 可能被淘汰。更稳妥的做法是把这两类数据放在不同的实例里;
  • 所有缓存 Key 都应设置过期时间,不设置过期时间的 Key 会随着业务增长无限累积;
  • 过期并不意味着内存立刻释放,删除是惰性删除加定期删除,短时间内大量 Key 过期可能带来延迟抖动,这也是前面强调过期时间要加随机偏移的原因。

五、高可用与持久化:应用端也要配合

主备实例在主节点故障后会自动切换,但切换期间应用会经历短暂的连接中断,还可能丢失少量尚未同步到备节点的写入——Redis 主备复制是异步的。所以应用端要做好这几件事:

  • 使用实例提供的域名或连接地址,不要写死某个节点的 IP,切换后连接地址保持不变;
  • 设置合理的连接超时和命令超时,并配置断线重连和有限次数的重试,重试要保证操作是幂等的,避免重复扣减;
  • 使用连接池并限制大小:每个应用副本都有自己的连接池,容器扩容后总连接数会成倍增长,要和实例的最大连接数做对比;
  • 理解持久化的含义:开启持久化可以降低重启后数据丢失的风险,但并不等于 Redis 变成了强一致的数据库。重要数据仍应以数据库为准,Redis 中只存可以重建的副本;
  • 分布式锁要有超时和续期设计:主备切换时,锁可能因为异步复制而丢失,对强互斥要求高的场景,需要在业务层再加幂等和校验兜底。

六、安全与网络

实例建议部署在与应用相同的区域和 VPC 内,通过内网地址访问;安全组只放行应用所在的网段或安全组,不要对所有地址开放端口。生产环境应开启密码认证,密码要足够复杂并定期更换,如果控制台支持传输加密,建议在跨网络访问时开启。公网访问只作为临时运维手段,用完及时关闭。同时,把高风险命令(如清空整个库的命令)在运维流程上加以限制,避免误操作,具体可用的命令限制方式请参考官方文档。

七、监控告警与上线前检查清单

DCS 与云监控服务 CES 集成,建议至少为下面这些指标设置告警:内存使用率、CPU 使用率、带宽使用率、连接数使用率、每秒操作数、命令平均时延,以及主备实例的复制状态。再配合慢查询日志,定期查看耗时较长的命令。上线前可以逐项对照:

  • 实例类型、规格和容量经过业务评估,并预留了内存余量;
  • 生产环境使用主备或集群,不使用单机版;
  • Key 命名规范,没有明显的大 Key,热 Key 有本地缓存或副本方案;
  • 缓存 Key 都设置了过期时间,且带随机偏移;
  • 对穿透、击穿、雪崩都有对应的防护和数据库降级方案;
  • 淘汰策略与业务匹配,缓存与不能丢的数据尽量分开;
  • 应用使用域名连接,有超时、重连和幂等重试,连接池大小经过核算;
  • 安全组、密码认证已配置,高风险命令有管控;
  • 内存、CPU、带宽、连接数、时延等指标有告警和处理手册,并做过一次主备切换演练。

结语

云上的 Redis 把部署、监控和故障切换这些重复性的工作接了过去,但缓存的设计,包括 Key 怎么起、数据怎么过期、回源怎么保护数据库、故障时应用怎么表现,仍然需要团队自己负责。把本文的几个环节逐项对照一遍,大部分常见问题可以在上线之前就发现。欢迎在评论区交流你们在 DCS 使用中遇到的问题和经验。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。