Redis 的内存
Redis 的内存
内存消耗
内存使用统计
使用info memory 命令查看内存相关指标:
属性名 | 属性说明 |
---|---|
used_memory | redis分配器的内存总量 |
used_memory_human | 以可读的格式返回used_memory |
used_memory_rss | 操作系统角度显示redis进程占用物理内存总量 |
used_memory_peak | 内存使用的最大值,表示used_memory的峰值 |
used_memory_peak_human | 以可读形式返回used_memory_peak |
used_memory_lua | lua殷勤所消耗的内存大小 |
mem_fragmentation_ratio | used_memory_rss/used_memory 比值,表示内存碎片率 |
mem_allocator | redis所使用的内存分配器,默认jemalloc |
内存消耗划分
redis进程内消耗主要包括:自身内存+对象内存+缓冲内存+内存碎片
- 对象内存:redis内存中占用最大的一块,储存着所有用户的数据,redis所有数据都采用key-value数据类型,所以对象内存消耗可以理解为 sizeof(keys)+sizeof(values)
- 缓冲区内存:缓冲区内存主要包括客户端缓冲、复制挤压缓冲区、AOF缓冲区。 客户端缓冲区是指所有接入到redis服务器TCP链接的输入输出缓冲。 复制挤压缓冲区是指redis在2.8版本后提供了一个可重用的固定大小缓冲区是用于实现部分复制的功能。AOF缓冲区指的是redis在重写期间保存最近的写入命令
- 内存碎片。频繁做更新操作、大量过期键删除、数据对齐、安全重启会出现高内存碎片问题
子进程内存消耗
子进程内存消耗主要是指执行AOF/RDB重写时Redis创建的子进程内存消耗。Redis执行fork操作产生的子进程内存
内存管理
设置内存上限
Redis使用maxmemory参数限制最大可用内存,限制内存的目的主要有:
- 使用缓存场景。当超出内存上线maxmemory是使用LRU等删除策略释放空间
- 防止内存超过服务器物理内存
动态调整内存上限
Redis的内存上限可以用过config set maxmemory进行动态修改
内存回收策略
Redis的内存回收机制主要体现在以下两个方面 :删除到达过期时间的键对象。内存到达上限时触发内存溢出控制策略
删除过期键。 redis所有键都可以设置过期属性,redis采用惰性删除和定时任务删除
- 惰性删除:惰性删除用于当客户端读取带有超时属性的键时,如果已经超过过期时间,会执行喊出操作并返回空。
- 定时任务删除:redis 内部维护一个定时任务,默认每秒运行10次,采用自适应算法根据键的过期比例采用快慢两种速率模式删除过期键
内存溢出控制策略,当Redis到达maxmemory上限是触发相应的溢出控制策略
1)noeviction:默认策略,不会删除任何数据,拒绝所有写入操作,并返回客户端错误信息,此时只相应读操作
2)volatile-lru:根据LRU算法删除设置了超时属性的键,直到腾出足够空间为止,如果没有可删除对象,退回到1)
3)allkeys-lru:根据LRU算法删除键,不管有没有过期属性,直到腾出足够空间
4)allkeys-random:随即删除所有键,直到腾出足够空间为止
5)volatile-random:随机删除过期键,直到腾出空间
6)volatile-ttl:根据键值对象ttl属性,删除最近将要过期数据,如果没有回退1)
内存优化
- 缩减键值对象:降低key和value值的长度
- 共享对象池:redis在内部维护了一个0~9999 的整数对象池可以降低内存使用
- 字符串优化:redis内部字符串(SDS)存在预分配机制,日常开发小心预分配带来的内存浪费
- 编码优化:
- 控制键的数量:hash结构适量降低键的数量