当前位置: 首页 > news >正文

Redis - 数据分布优化:如何应对数据倾斜

文章目录

  • 数据量倾斜
    • Bigkey 导致的倾斜
    • Hash Tag 滥用
    • 槽分配不均
  • 数据访问倾斜
    • 热 key 的来源
    • 定位热 key
    • 应对方式:本地缓存
    • 应对方式:热 key 副本
    • 应对方式:客户端缓存(Redis 6.0)
  • 数据倾斜的预防
  • 实践建议

切片集群把数据均匀打散到多个节点,理论上能让每个节点的负载差不多。但生产环境经常出现这样的情况:明明用了集群,某个节点还是被打爆了,其他节点却很闲。这就是数据倾斜——数据或访问没有均匀分布。倾斜分两种:数据量倾斜和数据访问倾斜,原因和应对方式都不一样。

数据量倾斜

数据量倾斜指某个或某几个节点存的数据明显多于其他节点。原因主要有三个。

Bigkey 导致的倾斜

某个 key 本身的 value 极大——一个 List 几百万元素、一个 Hash 几百万 field、一个 Set 几亿成员。这种 key 不管路由到哪个节点,都会把那个节点占满。

定位 bigkey:

redis-cli--bigkeys# 扫描所有 key,输出每种类型最大的几个

或者用MEMORY USAGE命令查看具体 key 的内存占用:

MEMORY USAGE user:profile:big_one

应对方式:拆分 bigkey

原 key: user:followers:1001 = Set(1000万成员) 拆分后: user:followers:1001:0 = Set(100万) user:followers:1001:1 = Set(100万) ... 拆成 10 份

读取时按规则去多个 key 聚合。代价是逻辑变复杂、跨节点查询多了,但解决了数据倾斜的根本问题。

Hash Tag 滥用

Redis Cluster 支持 Hash Tag——key 中{}内的部分用于计算槽位:

user:{1001}:profile → CRC16("1001") → 槽 X user:{1001}:orders → CRC16("1001") → 槽 X

这能把同一用户的多个 key 聚到同一节点,方便做跨 key 操作。但如果大量 key 用了相同的 Hash Tag,所有这些 key 都会落到同一个槽、同一个节点。

最常见的错误是用业务前缀做 Hash Tag:

order:{shop_1}:1001 order:{shop_1}:1002 order:{shop_1}:1003 ... 该店铺所有订单全到一个节点

如果店铺 1 是大客户,几百万订单全压在一个节点上。

应对方式:只在确实需要原子操作的 key 上用 Hash Tag,不要随意加。

槽分配不均

集群初始化或扩容时,如果手工分配槽,可能没分均匀。比如 4 个节点:

节点A:0-80008000个槽) 节点B:8001-120004000个槽) 节点C:12001-140002000个槽) 节点D:14001-163832000个槽)

A 节点承载的槽数是 D 的 4 倍,数据量自然倾斜。

应对方式:用redis-cli --cluster rebalancecluster reshard重新均匀分配。

数据访问倾斜

数据量分布均匀,访问量却不均匀。某个 key 被频繁访问,导致它所在的节点 CPU、网络打满,而其他节点很闲。这就是热 key 问题。

热 key 的来源

  • 明星动态:某条微博突然爆火。
  • 热销商品:双 11 的爆款。
  • 热点事件:突发新闻、明星八卦。
  • 抢购页面:限时优惠。

热 key 往往是业务侧无法预测的。

定位热 key

# Redis 4.0+ 支持redis-cli--hotkeys# 需要 maxmemory-policy 设为 allkeys-lfu 或 allkeys-lru

也可以通过MONITOR抽样观察请求分布,但 MONITOR 性能开销大,慎用。

应对方式:本地缓存

热 key 的访问大部分是只读的。在应用层加本地缓存(如 Caffeine、Guava Cache),让大部分请求在应用本地就返回,不走 Redis:

LoadingCache<String,String>localCache=Caffeine.newBuilder().maximumSize(1000).expireAfterWrite(5,TimeUnit.SECONDS).build(key->redis.get(key));

短 TTL(几秒)能保证一致性,长 TTL 能更好挡流量。具体值看业务容忍。

应对方式:热 key 副本

把热 key 复制到多个 key,分散到多个节点:

原 key:hot_news_1001 副本: hot_news_1001:0,hot_news_1001:1,...,hot_news_1001:N

读取时随机选一个副本:

copy_id=random.randint(0,N)key=f"hot_news_1001:{copy_id}"

写入时所有副本都更新(牺牲一致性换取读性能)。

这个方案适合读多写少的热 key。如果是写多读少的(比如计数器),副本方案就不行了。

应对方式:客户端缓存(Redis 6.0)

Redis 6.0 引入了 Tracking 机制,服务端在 key 变更时主动通知客户端失效。客户端可以放心做本地缓存,不用担心读到旧数据。

CLIENT TRACKING ON GET hot_news_1001# 服务端会记住这个客户端读过这个 key# key 变更时主动通知失效

这是优雅的方案,但需要客户端库支持。

数据倾斜的预防

事后处理不如事前预防。架构设计阶段就要考虑:

  1. 避免单一维度的 key 设计:不要让所有 key 都按一个 ID 分布。
  2. 慎用 Hash Tag:只在跨 key 原子操作时用,不要为了"看起来整齐"加。
  3. 预估数据规模:业务上线前估算每个 key 的数据量,超过阈值的提前拆。
  4. 监控告警:每个节点的内存、QPS、CPU 都要监控,倾斜要及时发现。

实践建议

  1. 定期扫 bigkey--bigkeys命令成本不高,可以每周运行一次。
  2. bigkey 拆分要趁早:等到把节点压垮再拆,要做的工作多得多。
  3. Hash Tag 只用在必要的地方:默认不要加,要加之前问清楚为什么。
  4. 热 key 做本地缓存:成本最低收益最大的方案。
  5. 关键业务做读副本:电商首页的爆款商品、社交平台的热门内容。
  6. 集群扩容时重新均衡:扩容只是加节点,不会自动迁移数据,必须手动 rebalance。

数据倾斜是切片集群必然会遇到的问题。理解倾斜的两种来源——数据量和访问量——才能对症下药。bigkey 拆分、Hash Tag 谨慎使用、热 key 副本和本地缓存,构成了应对数据倾斜的工具箱。把这些手段用对,集群才能真正发挥"水平扩展"的价值。

http://www.jsqmd.com/news/1050690/

相关文章:

  • 寄电瓶车到乡镇有啥坑?农村托运避坑攻略 - 快递物流资讯
  • 跨省寄大件重物哪家物流便宜?2026省钱全攻略 - 快递物流资讯
  • MATLAB实现AES-128图像加密:从原理到工程实践
  • 合肥理工学校招生办电话号码是多少?2026年合肥理工学校最新权威发布! - 教育为先
  • P89LPC915/916/917看门狗与Flash IAP-Lite实战配置与避坑指南
  • 2026 AI 搜索 GEO 优化公司推荐:国内外 GEO 服务商选择与避坑指南 - GrowthUME
  • 2026中考美术联考冲刺机构选型参考:罗丹艺术培训学校行业适配性深度分析 - 云南美术头条
  • Netgear路由器终极救援指南:3步掌握nmrpflash固件修复技术
  • 2026年6月最新萧邦中国官方售后服务电话网点及客服中心地址 - 亨得利官方服务中心
  • 如何快速掌握MAA明日方舟自动化助手:新手完全指南
  • 2026年合肥市哪所中职学校升学率最高?管理最严格?——推荐合肥理工学校! - 教育为先
  • Locust性能测试报告生成与深度定制:从CSV到HTML的完整实践
  • 告别叛逆网瘾!2026 东营十大权威特训学校盘点,20 年经验 + 全封闭管理,帮孩子重回正轨 - 辛云教育资讯
  • 巧用自定义协议:将RTSP流无缝接入NVR并模拟GB28181通道
  • 武汉护理中专学校哪家好?2026年最新排名+招生要求一览 - 辛云教育资讯
  • 通信系统滤波(5):正交频分复用(OFDM)及其滤波技术——4G/5G的基石与演进
  • 保安赶走避雨母子,店家道歉够吗?3个追问直击核心
  • 基于MATLAB的数据科学实战:从特征工程到集成学习预测NCAA篮球锦标赛
  • 企业内网如何构建远程AI编码工作流(非Codex方案)
  • 3分钟解决iPhone USB网络共享Windows驱动问题:一键安装方案
  • 湖北现代科技学校护理专业怎么样?2026年初中毕业生的热门选择! - 辛云教育资讯
  • 跨平台开发抉择:从技术基因到项目落地,剖析UniApp与Flutter的实战适配性
  • qmcdump工具实战:解密QQ音乐专属格式,实现音频文件通用播放
  • 移动端UI自动化测试框架对比:Espresso与XCUITest的核心差异与实践指南
  • VScode调试按钮神秘消失?深入剖析C/C++插件IntelliSense Engine与setting.json的同步陷阱
  • 终极指南:用MouseTracks可视化你的数字足迹,发现隐藏的操作模式
  • 通信系统滤波(6):非线性滤波与限幅技术——对抗非高斯噪声与硬件缺陷的艺术
  • 合肥理工学校招生电话多少?2026年6月21号最新发布! - 教育为先
  • 嵌入式GUI开发实战:emWin工程化配置与移植指南
  • 库拉米托振子模型:从同步现象到Python模拟实现