Redis怎样防止Hash结构内存溢出_通过配置ziplist参数优化底层编码

落杰酱_5194

落杰酱_5194

2026-03-30

659人浏览

原创

redis 的 hash 在元素个数 ≤ hash-max-ziplist-entries 且每个字段和值长度 ≤ hash-max-ziplist-value 时使用 ziplist 编码;否则升级为 hashtable,且不可逆。

redis怎样防止hash结构内存溢出_通过配置ziplist参数优化底层编码

Hash 什么时候会用 ziplist 编码?

Redis 的 hash 默认不是一直用哈希表(hashtable)存的。当满足两个条件时,它会退化成更省内存的 ziplist:元素个数 ≤ hash-max-ziplist-entries,且每个字段和值的长度都 ≤ hash-max-ziplist-value。一旦任一条件被突破,整个 hash 就会立即升级为 hashtable —— 这个过程不可逆,且会翻倍占用内存。

常见错误现象:HSET user:1001 name "Alice" age "30" city "Beijing" 看似很小,但如果某次写入一个长字符串(比如 HSET user:1001 bio "...",bio 超过 hash-max-ziplist-value),整个 key 就立刻转成 hashtable,哪怕之前只有 3 个短字段。

  • 默认值(Redis 7.0+):hash-max-ziplist-entries = 512,hash-max-ziplist-value = 64
  • 如果你存的是 JSON 片段、base64 图片 ID 或带空格的描述文本,64 字节很容易超
  • 升级后无法自动降级,即使你后续删掉长字段,内存也不会回收回 ziplist

怎么查当前 hash 是什么编码?

别猜,直接用 OBJECT ENCODING 命令确认:

redis-cli> HSET myhash a 1 b 2
(integer) 2
redis-cli> OBJECT ENCODING myhash
"ziplist"
redis-cli> HSET myhash c "x".repeat(65)
(integer) 1
redis-cli> OBJECT ENCODING myhash
"hashtable"

注意:OBJECT ENCODING 返回 ziplist 才说明还在紧凑模式;返回 hashtable 就已经“失守”了。线上如果发现大量 hash 占用异常高,优先批量检查这个。

  • 用 SCAN 配合 OBJECT ENCODING 可以做粗筛,但别在大实例上高频执行
  • redis-cli --scan --pattern "user:*" | xargs -L 1 -I {} redis-cli OBJECT ENCODING {} 这类管道容易丢结果,建议用 Lua 脚本原子判断
  • 监控层面可采集 INFO memory 中的 used_memory_dataset_perc,突然下降可能意味着大量 ziplist 升级(因 hashtable 冗余更高)

调参前必须想清楚的三件事

改 hash-max-ziplist-entries 或 hash-max-ziplist-value 不是越大越好,本质是在内存、CPU、延迟之间做权衡。

  • 增大 hash-max-ziplist-value 到 128 或 256,对存短文本(如邮箱、手机号)友好,但若误存日志片段,单个 field 就可能撑爆 ziplist,触发一次性扩容,卡住主线程
  • 减小 hash-max-ziplist-entries(比如设成 64)能更快进入 hashtable,降低单次查找的平均复杂度(O(1) vs O(N)),但内存立刻多出 3–5 倍
  • 这些参数是全局的,影响所有 hash,不能按 key 区分。如果你有“用户资料”(小而密)和“用户行为日志”(大而稀)两类 hash,硬靠一套参数必然顾此失彼

真实场景中,更推荐:对明确知道结构的小型 hash(如配置项、状态映射),用 HGETALL + 客户端缓存;对可能变大的,从设计上就避免塞进单个 hash,改用 JSON.SET 或拆成多个 key。

内存溢出真正在哪发生?

很多人以为调低 ziplist 阈值就能防溢出,其实不然。真正的风险点不在 ziplist 本身,而在它升级成 hashtable 后的**内存放大效应**和**碎片累积**。

  • 一个 10 字段、每字段平均 20 字节的 hash,在 ziplist 下约占 300 字节;升级后通常要 2KB+(含 dict 结构头、bucket 数组、指针等)
  • 频繁 HDEL + HSET 混用,会导致 ziplist 升级后产生大量小内存块,jemalloc 很难合并,mem_fragmentation_ratio 悄悄升到 1.8 以上
  • Redis 6+ 的 active-defrag 对 hashtable 效果有限,别指望它自动救场

所以最有效的“防止”,其实是控制写入节奏和数据形态:避免在 hash 中存不确定长度的内容,不把 hash 当通用对象容器用。ziplist 参数只是兜底手段,不是安全绳。

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

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

下载

相关标签:

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

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2023.08.07

2175

5

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

3362

1

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

2023.10.13

1136

3

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2025.09.10

3859

7

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1778

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2784

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6124

49

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2023.11.24

5829

6

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

2024.03.22

7454

16

热门下载

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

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.9万人学习