重学redis系列之redis缓存淘汰策略及常见问题

redis常备用来做缓存,那么什么是缓存?既然都是存储数据,与数据库相比又有什么不同?
redis是可以用来做数据库的!相较于传统关系型数据库,redis还具有查询效率更高的特点(数据存于内存,内存的寻址速度要远远高于磁盘寻址速度)。既然redis具有查询速度快的特点,那么能不能使用redis代替传统关系型数据库呢?只能说少部分情况下是可以的,但是大部分情况下传统关系型数据库还是具有不可替代的地位。原因如下:相较于磁盘,内存数据计算机中的稀缺资源,内存大小总是有限的,因此redis通常被用来做缓存(maxmemory配置指令用于配置Redis存储数据时指定限制的内存大小。通过redis.conf可以设置该指令,或者之后使用CONFIG SET命令来进行运行时配置。设置maxmemory为0代表没有内存限制。对于64位的系统这是个默认值,对于32位的系统默认内存限制为3GB。),缓存中存放的是热点数据。因为缓存空间是有限的,如果数据较多,已有的缓存空间已经占满了,在有新的数据要放入到缓存,这就涉及到了redis的缓存淘汰策略。
redis缓存淘汰策略主要为noeviction、allkeys-lru、volatile-lru、allkeys-random、volatile-random、volatile-ttl。

  1. noeviction 返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)。使用redis作为数据库时可以考虑使用这种淘汰策略,宁愿不可写入数据,也不能丢失数据(已经写入的数据被淘汰)。
  2. allkeys-lru 尝试回收最少使用的键(LRU The Least Recently Used,最近最久未使用算法),使得新添加的数据有空间存放。
  3. volatile-lru 尝试回收最少使用的键(LRU The Least Recently Used,最近最久未使用算法),但仅限于在过期集合的键,使得新添加的数据有空间存放。
    针对allkeys-lru、volatile-lru两种淘汰策略的选择则需要依据redis是怎么使用的,如果大部分key都设置了有效期,则适合使用volatile-lru,反之则使用allkeys-lru,总之一句话,使用合适的淘汰策略可以使redis的内存回收达到效率最大化。
  4. allkeys-lfu 尝试回收最少使用的键(LRU Least Frequently Used ,最近最少使用算法),使得新添加的数据有空间存放。
  5. volatile-lfu 尝试回收最少使用的键(LRU Least Frequently Used ,最近最少使用算法),但仅限于在过期集合的键,使得新添加的数据有空间存放。
  6. allkeys-random 回收随机的键使得新添加的数据有空间存放。
  7. volatile-random 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
  8. volatile-ttl 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。
    redis的key可以设置有效期,redis key过期策略主要有两种:
    惰性删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key(无法保证冷数据被及时删掉)。
    定期删除:Redis会定期主动淘汰一批已过期的key(随机抽取一批key检查)
    当前已用内存超过maxmemory限定时,触发主动清理策略。
    缓存常见问题及解决思路:
  9. 缓存击穿:key过期(或LRU、LFU算法)造成请求并发访问数据库的现象。 思路:阻值大量请求透穿到达数据库。处理方法:1)获取数据 --> 2) 失败后加锁(setnx)–> 3) 加锁成功请求数据库获取数据并存储到redis(成功后删除setnx加的锁) --> 4) setnx失败则随机等待一定时间然后重新开始从1获取数据。
  10. 缓存穿透:请求一个不存在的数据(key),请求每次都穿透到数据库库。解决方案:布隆过滤器(客户端实现或利用redis的布隆模块)
  11. 缓存雪崩:大量key同时失效造成请求并发访问数据库的现象。解决方式:分散key的有效期(随机过期时间),如果是时点性相关的数据(必须是某一时间更新数据)则采用缓存击穿的方式进行,也可以业务端针对特定时间段内的请求随机等待,缓解请求同一时间到达数据库造成的数据库压力。

猜你喜欢

转载自blog.csdn.net/hxj413977035/article/details/112269933
今日推荐