我命由我,不由天!


  • 搜索
prometheus docker golang linux kubernetes

redis-小对象压缩(十五)

发表于 2021-06-02 | 0 | 阅读次数 375

开源节流——小对象压缩

Redis是非常耗内存的数据库,所有数据放在内存里。为了优化数据结构的内存占用,增加了非常多的优化点,以牺牲代码的可读性为代价

32bit VS 64bit

Redis如果使用32bit进行编译,内部所有的数据结构使用的指针空间将会少一半,可以考虑使用32bit进行编译,能够节约大量内存

小对象

小对象压缩存储

如果Redis内部管理的集合数据结构很小,它会使用紧凑存储形式压缩存储

ziplist

Redis的ziplist是一个紧凑的字节数组结构,每个元素之间都是紧挨着的。

image.png
如果存储的是hash结构,那么key和value会作为两个entry被相邻存储

如果存储的是zset结构,那么value和score会作为两个entry被相邻存储

intset

Redis的intset是一个紧凑的整数数组结构,用于存放元素都是整数且元素个数较小的set集合

如果整数可以用uint16表示,那么intset的元素就是16位的数组,如果新加入的整数超过了uint16的表示范围,那么就使用uint32表示,如果新加入的元素超过了uint32的表示范围,那么就使用uint64表示。Redis支持set集合动态从uint16升级到uint32,再升级到uint64

image.png

如果set里存储的是字符串,那么sadd立即升级为hashtable结构

小对象升级为标准结构

  • hash的元素个数超过512就必须使用标准结构存储
  • hash的任意元素的key/value的长度超过64就必须用标准结构存储
  • list 的元素个数超过512就必须用标准结构存储
  • list的任意元素的长度超过64就必须用标准结构存储
  • zset的元素个数超过128就必须用标准结构存储
  • zset的任意元素的长度超过64就必须用标准结构存储
  • set的整数元素个数超过512就必须用标准结构存储

内存回收机制

Redis并不总是将空闲内存立即归还给操作系统

当前Redis内存有10GB,当删除1GB的key时,内存变化不会太大。因为操作系统是以页为单位来回收内存的,这个页上只要还有一个key在使用,那么就不能被回收。虽然删除了1GB的key,但是这些key分散到很多的页面上,每个页面仍然还有其他key存在,这就导致内存不会被立即回收。

Redis会重新使用那些尚未回收的空闲内存

内存分配算法

Redis为了保持自身结构的简单,直接由jemalloc(facebook)库来管理内存,比tcmalloc(google)性能更好

  • 本文作者: Dante
  • 本文链接: https://gaodongfei.com/archives/redis-小对象压缩
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
registry删除镜像
redis-主从同步(十六)
  • 文章目录
  • 站点概览
Dante

Dante

119 日志
5 分类
5 标签
RSS
Creative Commons
0%
© 2023 Dante
由 Halo 强力驱动
|
主题 - NexT.Pisces v5.1.4
沪ICP备2020033702号