Redis 是一个非常耗费内存的数据库,它所有的数据都放在内存里。如果我们不注意节约使用内存,Redis 就会因为我们的无节制使用出现内存不足而崩溃。
1、ziplist:是一个紧凑的字节数组结构,每个元素直接都是紧挨着,数据结构如下图:
1)object encoding +key :查询key属于哪种类型
2)若存放hash结构,key和value会作为俩个entry相邻存在一起
2、intset;是一个紧凑的整数数组结构,它用于存放元素都是整数的并且元素个数较少的 set 集合
1)整数可以动态扩容大小,由uint16到uint32、uint64,存储的数据不够后自动往大扩容,如下图所示:
3、存储界限:当集合对象的元素不断增加,或者某个 value 值过大,这种小对象存储也会被升级为标准结构:
1)hash-max-ziplist-entries 512 # hash 的元素个数超过 512 就必须用标准结构存储
2)hash-max-ziplist-value 64 # hash 的任意元素的 key/value 的长度超过 64 就必须用标准结构存储
3)list-max-ziplist-entries 512 # list 的元素个数超过 512 就必须用标准结构存储
4) list-max-ziplist-value 64 # list 的任意元素的长度超过 64 就必须用标准结构存储
5) zset-max-ziplist-entries 128 # zset 的元素个数超过 128 就必须用标准结构存储
6)zset-max-ziplist-value 64 # zset 的任意元素的长度超过 64 就必须用标准结构存储
7)set-max-intset-entries 512 # set 的整数元素个数超过 512 就必须用标准结构存储
例如下图所示:
可以看出entry的value值超出了64,存储结构就升级成标准结构
4、内存回收机制
1)Redis并不总是可以将空闲的内存立即归还给操作系统,因为操作系统回收内存是以页为单位,如果这个页只要有一个key还在使用,那么就不能立刻被回收
2)Redis 虽然无法保证立即回收已经删除的 key 的内存,但是它会重用那些尚未回收的空闲内存
3)flushdb:执行该命令,会使所有的key都干掉了,大部分之间使用的页面都完全干净了
5、
内存分配算法
1)Redis将内存分配的细节丢给了第三方内存分配库去实现,目前Redis使用jemalloc(facebook) 库来管理内存,也可以切换到tcmalloc(google),但是jemalloc 相比 tcmalloc的性能要稍好一些,例如下图查看内存管理: