一、4种内存使用分类

1、自身内存:redis空进程自身内存消耗

2、对象内存:存储所有的数据。key-value数据类型。储存五种数据类型,str、list、hash、set、zset。

3、缓冲内存:包括客户端缓冲区、复制积压缓冲区、AOF缓冲区

客户端缓冲区:tcp连接输入输出的缓冲。

复制积压缓冲区:在主从复制时,主服务将数据以先进先出方式,提供给从服务,来避免全量复制,实现增量复制和复制断连的数据补偿。

AOF缓冲:AOF持久化时,命令不是直接存入磁盘,而是先将命令写入缓冲区,再按规则存入磁盘。

4、内存碎片:因为使用jemalloc等c自带内存分配管理,有固定规格的内存块,大多数据无法填满整个内存块。频繁的更新、删除都会使内存碎片增多。

二、内存回收策略

1、数据到达过期时间删除。

因为实时从内存中删除数据,会消耗大量的cpu性能。大多语言都没有采用实时删除内存的策略。redis有惰性删除和定时删除两种删除模式。

惰性删除:当数据已经过期后,不会对其操作。当客户端再次读取超时数据后,执行删除操作,并返回空数据。但是如果客户端没有再次访问数据,内存一直占用,有内存泄露问题。所以需要定时删除

定时删除模式:redis内部的一个定时任务,通过配置,每秒运行10次删除任务。

删除流程分一下几部

1)随即检查每个数据库中20个键。(现在基本都用一个数据库,官方也不推荐多个数据库使用)

2)删除过期键,并且如果检查出超过25%的过期键,重复执行这个流程,知道不足25%或者运行超时

3)如果超时,立刻再次执行流程。超时执行,2s内仅能执行一次。超时时间为1s。

2、内存超出可使用配置值,内存溢出

当内存达到maxmemory上限时触发。通过配置maxmemory-policy控制,有六种控制策略

1)noeviction:默认策略,数据永不过期,不会删除任何数据,当内存不足以容纳新写入数据时,新写入操作会报错,一般不推荐使用。

2)volatile-lru:根据LRU算法删除设置了超时属性(expire)的键,直到腾出足够空间为止。如果没有可删除的键对象,回退到noeviction策略。这种情况一般是把 Redis 既当缓存,又做持久化存储的时候才用。

3)allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止。一般推荐使用该策略

4)allkeys-random:内存不足以容纳新写入数据时,在键空间中,随机移除某个 Key。

5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 Key。

6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 Key 优先移除。如果没有,回退到noeviction策略。

需要注意使用lru算法时,无法配置共享内存池,因为公用一个最后访问时间字段。