缓存穿透、击穿、雪崩

缓存穿透#

定义: 访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB会挂掉。

解决方案:

  1. 缓存空值 (值少时)
  2. 布隆过滤器, 特性: 没有的肯定没有,有的不一定有

缓存击穿#

定义:并发性,一个存在的key,在缓存过期的一刻,同时有大量的并发请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。

解决方案:

  1. 分布式锁,在访问key之前,采用分布式锁SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key

缓存雪崩#

定义:大量的key设置了相同的过期时间,或者某台服务器宕机,导致大量缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。

解决方案:

  1. 将key的过期时间设置时添加一个随机时间,分散过期时间
  2. 如果是热点key,可以加分布式锁,减少并发量
  3. 二级缓存(本地缓存),减少db压力

tair & redis 的选择

tair & redis 的选择#

  1. 延迟敏感程度, 延迟敏感,说什么也得redis
  2. 数据量大的话,数据量超过100GB全内存太浪费资源,延迟没有那么敏感,使用tair
  3. 使用复杂数据结构 redis
  4. 容忍数据丢失

redis单线程还这么快

为什么Redis使用单线程模型会达到每秒万级别的处理能力呢?可以将其归结为三点使Redis具有很高的吞吐量?#

1. 纯内存访问#

Redis将所有数据放在内存中,内存的响应时长大约为100纳秒,这是Redis达到每秒万级别访问的重要基础。

纯内存数据库,如果只是简单的 key-value,内存不是瓶颈。一般情况下,hash 查找可以达到每秒数百万次的数量级。瓶颈在于网络 IO 上。每次请求需要通过网络把请求发送到 redis 所在的机器,然后等待 redis 返回数据。时间大部分消耗在网络传输中。如果把 redis 和客户端放在同一台机器,网络延迟会更小,一般情况下可以打到 60000 次每秒甚至更高,取决于机器性能。

2. I/O多路复用、事件驱动模型#

旨在解决IO的问题。多路I/O复用模型是非阻塞IO,内部实现采用epoll和自己实现的事件分离框架。

其利用select、poll、epoll 可以同时检测多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。

“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗)。

总结就是Redis使用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间,如下图所示。

3. 单线程避免了线程切换和竞态产生的消耗。#

线程模型#

主线程#

其它#

  1. Redis会fork得到的子进程,用来处理RDB持久化以及AOF持久化等任务

  2. 一组异步任务处理线程,即Redis异步化组件——BIO组件

BIO组件目前包括三个线程,分别处理三种类型的任务:
1)文件句柄关闭任务
2)AOF持久化任务
3)空间懒释放

持久化#

Redis 提供了两种持久化策略

RDB 持久化机制,会在一段时间内生成指定时间点的数据集快照(snapshot)

AOF 持久化机制,记录 server 端收到的每一条写命令,当 server 重启时会进行重放以此来重建之前的数据集。AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加(append)到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite) ,使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。

如果你仅使用 Redis 作为缓存加速访问,你可以关闭这两个持久化设置

你也可以同时开启这两个持久化设置,但是在这种情况下,Redis 重启时会使用 AOF 文件来重建数据集,因为 AOF 文件保存的数据往往更加完整

单线程利弊#

单线程模型能带来几个好处:
第一,单线程可以简化数据结构和算法的实现。并发数据结构实现不但困难而且开发测试比较麻烦。
第二,单线程避免了线程切换和竞态产生的消耗,对于服务端开发来说,锁和线程切换通常是性能杀手。

但是单线程会有一个问题:
对于每个命令的执行时间是有要求的。如果某个命令执行过长,会造成其他命令的阻塞,对于Redis这种高性能的服务来说是致命的,所以Redis是面向快速执行场景的数据库。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×