Redis|青训营

94 阅读3分钟

Redis是什么

redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库。

特点

  • 优秀的性能,数据是存储在内存中,读写速度非常快,可支持并发10W QPS
  • 单线程但进程,是线程安全的,采用IO 多路复用制
  • 可作为分布式锁
  • 支持五种数据类型
  • 支持数据持久化到磁盘
  • 可以作为消息中间件使用,支持消息发布及订阅

数据类型

image.png

可能遇到的问题

大key

key往往是程序可以自行设置的,value往往不受程序控制,因此可能导致value很大。
redis中这些Big Key对应的value值很大,在序列化/反序列化过程中花费的时间很大,因此当我们操作Big Key时,通常比较耗时,这就可能导致redis发生阻塞,从而降低redis性能。 用几个实际的例子对大Key的特征进行描述:
一个String类型的Key,它的值为10k(数据过大);
一个List类型的Key,它的列表数量为20000个(列表数量过多);
一个ZSet类型的Key,它的成员数量为10000个(成员数量过多);
一个Hash格式的Key,它的成员数量虽然只有1000个但这些成员的value总大小为100MB(成员体积过大)

热key

在Redis中,我们把访问频率高的Key,称为热Key。比如突然又几十万的请求去访问redis中某个特定的Key,那么这样会造成redis服务器短时间流量过于集中,很可能导致redis的服务器宕机。那么接下来对这个Key的请求,都会直接请求到我们的后端数据库中,数据库性能本来就不高,这样就可能直接压垮数据库,进而导致后端服务不可用。

缓存穿透

key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
有很多种方法可以有效地解决缓存穿透问题最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法(我们采用的就是这种),如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

缓存雪崩

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。
有一个简单方案就时将缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。或者Redis查DB数据的时候将请求加一个随机延迟时间,让请求不要集中。