Redis是基于内存存储的,非关系型,键值对数据库。因此,对Redis来说,内存空间的管理至关重要。那Redis是如何内存管理的呢?
一、最大内存限制
Redis 提供了 maxmemory 参数允许用户设置 Redis 可以使用的最大内存大小。当 Redis 使用的内存量达到 maxmemory 设置的上限时,Redis 会根据配置的淘汰策略(如 LRU、LFU、TTL 等)自动删除某些键值对以释放内存。
二、过期键删除策略
用户可以为键设置过期时间,当键过期后,Redis 采用多种方式处理:
1、定期删除:Redis 会周期性地随机检查并删除一部分已过期的键。
2、惰性删除:在访问某个键时,如果发现该键已过期,则立即删除它。
3、主动淘汰:结合上述两种方法,在内存不足时按照特定策略主动淘汰未过期的键。
三、内存分配与回收
Redis 使用jemalloc或libc等高效的内存分配器进行内部数据结构(如字符串、哈希表、链表、集合等)的内存分配与回收,减少内存碎片。
四、结合数据结构和编码方式做内存优化
Redis 的内部数据结构经过特殊设计,能够紧凑存储不同类型的数据,例如简单动态字符串SDS、压缩列表ziplist等。
Redis 还支持多种编码方式,针对不同场景下的数据量和访问模式选择最节省空间的编码方式,如哈希表的ziplist编码和hashtable编码切换。
五、内存淘汰策略
当达到内存上限且有新数据需要插入时,Redis 会按照预设的淘汰策略从数据集中选择合适的键删除,常见的淘汰策略包括:
noeviction:不删除任何数据,返回错误给客户端(当内存达到 maxmemory 时不再执行写操作)。
volatile-lru/volatile-ttl/allkeys-lru/allkeys-random/allkeys-lfu:基于 LRU(最近最少使用)、TTL(过期时间)、LFU(最不经常使用)或随机选择键进行删除。
在java中,我们了解过jvm的垃圾回收机制对未被引用的对象进行回收的过程。那在Redis中,是如何被回收呢?
答:在 Redis 中,内存管理采用了引用计数(Reference Counting)的方式来跟踪对象的生命周期。这意味着每个 Redis 对象都有一个引用计数器,当有新的引用指向该对象时,引用计数加1;当引用移除时,引用计数减1。
当一个 Redis 对象的引用计数变为0时,表示没有任何其他对象引用它,此时 Redis 会立即释放这个对象所占用的内存空间。因此,Redis 的内存回收是实时且确定性的,不需要像Java那样等待垃圾收集器不定时地进行扫描和清理无用对象的过程。