在大部分场景下,Redis都作为纯内存的NoSQL系统运行。所以,有必要了解其内存使用的组成和相应的分析方法。

内存使用量限制及数据淘汰策略

内存使用量限制

Redis的配置项maxmemory默认没有设定值,可以通过此项配置来限制单机最大使用的内存量。在实际使用中,如果超过了此值,则需要根据maxmemory-policy中设定的策略进行数据淘汰。maxmemory-policy的默认值是noeviction。

淘汰策略

规则名称 规则说明
volatile-lru 使用近似的LRU算法删除一个键(只对设置了生存时间的键)
allkeys-lru 使用近似的LRU算法删除一个键
volatile-lfu 使用近似的LFU算法删除一个键(只对设置了生存时间的键)
allkeys-lfu 使用近似的LFU算法删除一个键
volatile-random 随机删除一个键(只对设置了生存时间的键)
allkeys-random 随机删除一个键
volatile-ttl 删除生存时间最近的一个键
noeviction 不删除键,只返回错误

LRU算法(Least Recently Used),最近最少使用算法。即默认删除最近最少使用的键。但是要注意:Redis中并不会准确的删除所有键中最近最少使用的键,而是随机抽取5个键,删除这5个键中最近最少使用的键。5这个数字也是可以设置的,对应位置是配置文件中的maxmemory-samples。

内存使用量分析

可以使用以下命令来查看Redis的内存使用情况:

info

统计大key并处理

redis-cli --bigkeys 命令可以统计bigkey的分布
为了解决删除大键造成redis阻塞的问题, redis 4.0 引入了lazyfree的机制,它可以将删除键或数据库的操作放在后台线程里执行, 从而尽可能地避免服务器阻塞
如果set/zset元素个数较少(少于64个)或者是String类型,也会在主线程中直接删除而不走异步模式

info命令输出的数据可分为10个类别,分别是:

server
clients
memory
persistence
stats
replication
cpu
commandstats
cluster
keyspace

或直接用:

info memory

条目 说明
used_memory 分配器分配的内存量,也就是实际存储数据的内存总量
used_memory_human 以可读格式返回 Redis 使用的内存总量
used_memory_rss 从操作系统的角度,Redis进程占用的总物理内存
used_memory_peak 内存分配器分配的最大内存,代表used_memory的历史峰值
used_memory_lua Lua引擎所消耗的内存
maxmemory_policy noeviction(达到最大内存占用后的清理策略)
mem_fragmentation_ratio used_memory_rss /used_memory比值,表示内存碎片率
mem_allocator libc(Redis 所使用的内存分配器)

计算公式如下:

used_memory = 自身内存+对象内存+缓冲内存+lua内存
used_rss = used_memory + 内存碎片

内存碎片率保持在1.0至1.5之间是最理想的状态。 假若碎片率超过了1.5,有效解决手段就是重启Redis服务器,释放内存回到操作系统。反之,若碎片率为0.9,说明物理内存已不够用,应增添硬件,或修改Redis最大内存限制maxmemory。
最大内存限制maxmemory的设置非常重要。 如果不设置maxmemory,Redis一直会为其分配内存,直至耗尽所有物理内存,直到操作系统进行虚拟内存交换。

内存集群

  1. 客户端分片
    通过业务代码自己实现路由,性能较好但维护成本高。

  2. 代理分片
    使用类似Twemproxy、Codis等中间件实现。
    Codis在Twemproxy基础上优化并实现了预分片来达到Auto Rebalance。

  3. RedisCluster
    官方集群解决方案。方案较重,使用的案例较少。