Redis知识点汇总

缓存雪崩、缓存穿透、缓存预热、缓存降级等问题

缓存雪崩

我们可以简单的理解为:由于原有缓存失效,新缓存未设置的期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有本应该访问缓存的请求都去查询数据库了,导致数据库的CPU和内存压力陡增,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。

解决办法:

  1. 不同种类的缓存数据设置不同长度的过期时间,将缓存失效时间分散开
  2. 采用加锁或者队列的方式来保证不会有大量线程对数据库一次性进行读写,从而避免缓存失效时大量的并发请求落到数据库上。

缓存穿透

缓存穿透是指用户查询请求的数据,在数据库中没有,自然在缓存中也没有。这样就导致用户查询的时候,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存,直接查询数据库,这也是经常提到的缓存命中率的问题。

解决办法:

最常见的是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层数据库的查询压力。

另外也有一个简单粗暴的办法,如果一个查询返回的数据为空,仍然把这个空结果进行缓存,但过期时间设置很短(两三分钟)。通过这个直接设置的默认值存放到缓存中,这样第二次缓存中就能获取到值,而不会继续访问数据库。

缓存预热

缓存预热这个应该是一个比较常见的概念。系统上线后,将相关缓存数据直接加载到缓存系统。这样就可以避免用户请求时先查询数据库,然后再将数据缓存的问题。

解决办法:

  1. 直接写个缓存刷新页面,上线时手工操作一下
  2. 数据量不大,可以在项目启动的时候自动进行加载
  3. 定时刷新缓存

缓存降级

缓存降级的目的,是为了防止Redis服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查询,而是直接返回默认值给用户。

Redis为什么这么快

  1. 纯内存操作
  2. 单进程单线程,避免了频繁的上下文切换
  3. 采用了非阻塞I/O多路复用机制

Redis是单进程单线程的,Redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。多线程处理会涉及到锁,而且多线程处理会涉及到线程切换而消耗CPU。因为CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存或者网络带宽。单线程无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来解决。

使用Redis的优势

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。Redis利用队列技术将并发访问变为串行访问

  1. 速度快,因为数据存在内存中,类似于HashMap,优势就是查找和操作时间复杂度都是O(1)
  2. 采用单线程,避免了不必要的上下文切换和竞争条件
  3. 支持丰富的数据类型,支持string,list,set,sorted set,hash
  4. 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
  5. 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

Redis过期策略以及淘汰策略

Redis采用的是定期删除+惰性删除策略。

为什么不用定时删除?

用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这种策略。

定期删除+惰性删除策略

定期删除,Redis默认每隔100ms检查,是否有过期的key,有过期的key则删除。需要说明的是,redis不是每隔100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,Redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。

于是惰性删除就派上用场了。也就是说你在获取某个key的时候,redis会检查一下,这个key如果设置了过期时间,那么是否过期。如果过期了此时就会删除。

采用定期删除+惰性删除的问题:如果定期删除没删除key,然后也没有及时去请求key,这样redis的内存会越来越高,需要设置相应的淘汰策略。

淘汰策略

在Redis中,允许用户设置最大使用内存大小server.maxmemory,当Redis内存数据集代销上升到一定大小的时候,就会施行数据淘汰策略。

  1. volatile-lru:从已设置过期的数据集中挑选最近最少使用的淘汰
  2. volatile-ttr:从已设置过期的数据集中挑选将要过期的数据淘汰
  3. volatile-random:从已设置过期的数据集中任意挑选数据淘汰
  4. allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
  5. allkeys-random:从数据集中任意挑选数据淘汰
  6. noenviction:禁止淘汰数据

Redis淘汰数据时还会同步到AOF

Redis常见性能问题和解决方案

  1. Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
  2. 如果数据比较重要,某个slave开启AOF备份数据,策略设置为每秒同步一次
  3. 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网
  4. 尽量避免在压力很大的主库上增加从库
  5. 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3
发布了8 篇原创文章 · 获赞 0 · 访问量 5664

猜你喜欢

转载自blog.csdn.net/fedorafrog/article/details/103157219