欢迎来到啾啾的博客。
记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈。
有很多不足不足的地方,欢迎评论交流,感谢您的阅读。
本篇我们继续了解压缩列表与对象。
压缩列表(ziplist)是列表键和哈希键的底层实现之一。
当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。
压缩列表是一种节约内存而开发的顺序型数据结构。
Redis的对象系统实现了基于“引用计数计数”的内存回收机制,当程序不再使用某个对象的时候,对象所占用的内存就会被自动释放。
Redis还通过计数计数实现了对象共享机制,这一机制可以在适当的条件下,通过让多个数据库键共享同一个对象来节约内存。
最后,Redis的对象带有访问时间记录信息,该信息可以用于计算数据库键的空转时长,在服务器启用了maxmemory功能的情况下,空转时长较大的那些键可能会优先被服务器删除。
这个时间信息可以用于Redis的LRU(Least Recently Used)。
Redis 的近似 LRU 较 LinkedHashMap 通过指针操作(元素上浮 / 移动)来实现 LRU 的方式,开销更小。它通过记录时间、采样计算的方式来进行 LRU。虽然只能做到近似效果,但是可以极大节省内存开销。
另外Redis还有LFU(Least Frequently Used) 淘汰访问频率最低的,Random 随机淘汰,noeviction 不淘汰、ttl 淘汰剩余生存时间最短的。这个时间信息lru字段可以复用以支持其他策略。
LFU可以更好地识别热点键,但实现相对复杂,对于访问模式剧烈变化的场景可能响应稍慢。
为了节省内存,Redis 对一些常用的短字符串(特别是数字转换成的字符串)和小的集合对象(在特定编码下)会进行共享。例如,多个键可能都引用值为整数 “10” 的字符串表示,Redis 不会为每个键都创建一份 “10” 的字符串对象,而是让它们共享同一个 redisObject。
Redis会共享值为0到9999的字符串对象。
Redis构建了一个引用计数 reference counting用于实现内存回收机制。
机制通过每个对象设置引用计数信息refcount
实现。当有指正指向共享对象时,refcount++。不再指向时,refcount–。为0时,共享对象没有被引用,可以被回收(通常是调用底层的内存分配器如zfree())。