如何防止Redis Hash出现数据大Key_通过用户ID取模进行分Hash存储

冬伟酱_2464

冬伟酱_2464

2026-08-20

294人浏览

原创

直接结论:用用户id取模分片hash能防止单个hash key膨胀,但须避开hashcode()负数取模陷阱、uuid哈希不均问题,应采用crc32等确定性哈希,做无符号处理(hash & 0x7fffffff)% n,拆分key并统一读写逻辑,预留扩容分片,初期推荐32或64分片。

如何防止redis hash出现数据大key_通过用户id取模进行分hash存储

直接结论:用用户ID取模分片Hash,能有效防止单个Hash Key膨胀,但必须避开 hashCode() 和负数取模陷阱,且要预留扩容余量。

为什么不能直接用 user_id.hashCode() % N

Java 的 String.hashCode() 可能返回负数,-123 % 4 结果是 -3,不是你想要的 1;Python 的 hash() 在不同进程里结果还不稳定。更糟的是,UUID 类型的 user_id(如 "a1b2c3d4-...")哈希后分布并不均匀,容易导致某些分片严重倾斜。

实操建议:

  • 改用确定性哈希函数,比如 CRC32 或 MurmurHash3,确保同个 ID 每次算出相同正整数
  • 取模前先做无符号处理:Math.abs(hash) % N 不够安全,应改用 (hash & 0x7fffffff) % N
  • 避免用 user_id 原字符串哈希——优先截取或解析出数字部分(如从 "user_123456" 提取 123456),再哈希

HSET 写入前必须拆 key:按分片规则生成新 key 名

不要把所有用户塞进一个 user:profile Hash 里。正确做法是把大 Hash 拆成多个小 Hash,每个只存一部分用户数据。

例如分 64 片,用户 ID 是 "u10086":

  • 算哈希:hash = CRC32("u10086") → 293847123
  • 算分片:shard = 293847123 % 64 → 35
  • 新 key 名:user:profile:shard35
  • 写入:HSET user:profile:shard35 u10086 '{"name":"Alice","age":30}'

注意:shard 后缀建议用固定位数(如 shard035),避免 key 名排序混乱;别用 shard:35 这种带冒号的,可能和 Redis 命名习惯冲突,也影响 KEYS 扫描。

Redis Skill - 高性能缓存管理
Redis Skill - 高性能缓存管理

Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。

下载

查用户时必须复现相同分片逻辑,否则查不到

读取时若用了另一套哈希或漏了无符号处理,就会去错的 key 里找,返回空——这种错误在线上极难排查,因为表现就是“用户资料丢了”,但其实数据完好躺在另一个分片里。

关键检查点:

  • 读写两端哈希函数完全一致(推荐封装成公共工具类,禁止复制粘贴)
  • 分片数 N 必须硬编码或配置中心统一管理,禁止运行时动态读取、尤其不能从节点数推导
  • 上线前用一批真实 user_id 样本跑对账:同一 ID,写入分片和读取分片编号必须严格一致
  • 加一层 fallback 日志:当 HGET user:profile:shardXX uid 返回空时,记录该 UID 和计算出的 shardXX,方便快速定位逻辑偏移

分片数选 16、32 还是 64?看扩容容忍度

分片越多,单个 Hash 越小,内存碎片越少,但聚合查询(比如“查某城市所有用户”)就得遍历更多 key,HGETALL + 合并成本直线上升。更重要的是:一旦要扩容,比如从 32 片扩到 64 片,旧数据不会自动迁移——你得自己跑脚本重分,且期间不能写入,风险极高。

务实建议:

  • 初期选 32 或 64,别贪多;128 以上基本就失去运维友好性
  • 预留 1–2 个“保留分片号”(如永远不用 shard0 和 shard1),将来扩容时可把旧数据往里迁,避免全量重刷
  • 如果业务已明确会快速增长,直接上一致性哈希(如 CRC16(key) % 16384),但代价是需要客户端支持或代理层(如 Twemproxy / Redis Cluster)

最常被忽略的一点:分片逻辑一旦上线,就等于锁死了用户数据物理位置。后续任何变更都得带着迁移方案一起上线,而不是“改行代码就完事”。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

4289

19

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.14

3775

11

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.02

6832

6

redis怎么做缓存服务器
redis怎么做缓存服务器

redis 作为缓存服务器的答案:redis 是一款开源、高性能、分布式的键值存储,可作为缓存服务器使用。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

623

6

redis怎么解决数据一致性
redis怎么解决数据一致性

redis 提供了两种一致性模型,以维护副本数据一致性:强一致性 (sync) 确保写操作仅在复制到所有从节点后才完成;最终一致性 (async) 则在主节点上写操作后认为已完成,牺牲一致性换取性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

736

6

mysql和redis怎么保证双写一致性
mysql和redis怎么保证双写一致性

确保 mysql 和 redis 双写一致性的技术包括:1、事务性更新:同时更新 mysql 和 redis,保证一致性;2、主从复制:mysql 主服务器更改同步到 redis 从服务器;3、基于事件的更新:mysql 记录更改并发送到 redis等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

6422

6

redis缓存一般存些什么数据
redis缓存一般存些什么数据

redis缓存中存储的数据类型包括:字符串、哈希、列表、集合、有序集合、位图、地理空间数据和hyperloglog。这些数据类型适用于存储各种数据,从简单信息到复杂对象和地理位置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

1140

6

redis的8种数据类型有哪些
redis的8种数据类型有哪些

redis 提供 8 种数据类型:字符串(文本、数字、二进制)、哈希(键值对)、列表(有序集合)、集合(无序唯一元素)、有序集合(按分数排序)、地理空间(地理位置)、hyperloglog(估计大数据基数)和位图(位序列存储)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

1016

6

redis主要作用有哪些
redis主要作用有哪些

redis 的主要作用包括:1. 缓存数据,提高访问速度;2. 充当消息队列,实现消息传递;3. 存储各种数据类型,如字符串、散列和集合;4. 管理会话信息,确保可靠性和可用性;5. 限制请求速率,防止服务器超载等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

5738

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.5万人学习