Redis可以通过修改配置文件maxmemory为Redis设置最大内存空间占用当内存存储达到上限时就无法存储更多数据了。Redis提供了过期策略和淘汰策略来避免内存存储达到上限。一、过期策略过期策略就是通过expire命令给key设置TTLkey过期时key对应的内存会被释放。redisDB维护两个Dictdict、expiresdict记录所有redisObject-内存首址键值对、expires记录设置了过期时间的redisObject-过期时间键值对。1.惰性删除惰性删除在访问CRUDkey时执行首先根据key从dict中找到对应的redisObject然后检查key记录在expires中的TTL如果过期那么释放key的内存空间。存在的问题如果key过期了但是永远不会被访问那么惰性删除策略下该key的内存空间永远不会被释放。2.周期删除为所有key设置同一个定时任务周期性的抽样部分key检查是否过期如果过期执行删除操作SLOW模式redis单线程初始化时初始化epoll阶段设置server.hz频率默认100ms定期检查并清理过期key不在主线程main函数中。执行周期为100ms执行清理耗时不能超过25%即25ms首先逐个遍历db每次取20个key检查并清理过期key如果时间未达到25ms且刚才检查的过期key比例超过10%再取20个key检查并清理。感觉这个任务每100ms执行一次的话如果不是异步的应该要抢占主单线程的CPUFAST模式每次redis单线程调用epoll_wait阻塞前都会先检查并清理部分过期key2ms左右因为位于主线程的main代码中所以执行周期为两次调用epoll_wait的间隔但如果间隔低于2ms那么不会执行FAST清理直到两次FAST间隔大于2ms。每次清理耗时不能超过1ms首先逐个遍历db每次取20个key检查并清理过期key如果时间未达到25ms且刚才检查的过期key比例超过10%再取20个key检查并清理。二、淘汰策略淘汰策略就是Redis内存使用达到阈值时主动挑选部分key删除以释放内存。淘汰策略在主线程解析命令后处理命令前执行配置maxmemory-policynoeviction不淘汰任何key内存满时不允许写入新数据默认策略。volatile-ttl对设置了TTL的key淘汰TTL越小越先被淘汰allkeys-random对全体keydict哈希表随机淘汰。volatile-random对设置了TTL的keyexpires哈希表随机淘汰。allkeys-lru对全体keydict哈希表使用LRU算法进行淘汰。volatile-lru对设置了TTL的keyexpires哈希表使用LRU算法进行淘汰。allkeys-lfu对全体keydict哈希表使用LFU算法进行淘汰。volatile-lfu对设置了TTL的keyexpires哈希表使用LFU算法进行淘汰。LRU当前时间减最近一次访问时间值越大优先淘汰。LFU访问次数越少优先淘汰。key的访问次数和访问时间都会封装在redisObject对象中ptr指向key-value具体值逻辑访问次数由于8bit只能记录实际访问次数0~255对于热key来说远远不够所以使用逻辑访问次数当key被访问时生成一个0~1之间的随机数R计算P1/(旧访问次数*101)如果RP计数器1最大不超过255为了防止key长时间不访问但访问次数一直不变访问次数随时间衰减距离上一次访问间隔每隔1分钟计数器-1也就是说逻辑访问次数越大P越小RP的概率越小计数器越难1。