Redis 利用 Hash 存储节约内存

2018-12-14  本文已影响42人  杰哥长得帅

刚开始用 String 结构来做一个 key-value 存储
但这样单个简单的 key 存储的 value 很大

优化方案是使用 Hash 结构,由于 Hash 结构会在单个 Hash 元素在不足一定数量时进行压缩存储,所以可以大量节约内存。这一点 String 结构里是不存在的

省内存的原因是新建一个 hash 对象时开始是用 ziplist(又称为 small hash)来存储的。这个 ziplist 其实并不是 hash table,但是 ziplist 相比正常的 hash 实现可以节省不少 hash 本身需要的一些元数据存储开销。 尽管 ziplist 的添加,删除,查找都是 O(n),但是由于一般对象的 field 数量都不太多。 所以使用 ziplist 也是很快的,也就是说添加删除平均还是 O(1) 。如果 field 或者 value 的大小超出一定限制后,redis 会在内部自动将 ziplist 替换成正常的 hash 实现,这个限制可以在配置文件中指定 hash-zipmap-max-entries 参数来控制。将 hash-zipmap-max-entries 设置为 1000 时,性能比较好,超过 1000 后 HSET 命令就会导致 CPU 消耗变得非常大

具体做法

原存储方式:

SET bucket:1111123 999
GET bucket:1111123 
> 999

将数据分段,每一段使用一个 Hash 结构存储,保证了每个 Hash 内部只包含 3 位的 key,也就是 1000 个。如:

HSET bucket:1111 123 999
HGET bucket:1111 123 
> 999

这样公共的前缀只存了一次,也节约了一部分内存

总的 2 个优化:

  1. hash 的压缩列表
  2. 公共部分只存一次
上一篇下一篇

猜你喜欢

热点阅读