在大部分场景下,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一直会为其分配内存,直至耗尽所有物理内存,直到操作系统进行虚拟内存交换。
内存集群
-
客户端分片
通过业务代码自己实现路由,性能较好但维护成本高。 -
代理分片
使用类似Twemproxy、Codis等中间件实现。
Codis在Twemproxy基础上优化并实现了预分片来达到Auto Rebalance。 -
RedisCluster
官方集群解决方案。方案较重,使用的案例较少。