Redis

一. Redis是什么,有什么优缺点

  1. Redis是什么
    Redis是一种基于内存,可持久化,单线程工作模型,采用非阻塞I/O多路复用机制的Key-Value数据库。
  2. Redis的优点:非常快
    • 纯内存操作
    • 单线程操作,避免了频繁的上下文切换
    • 采用了非阻塞I/O多路复用机制
  3. Redis的缺点:一致性,缓存的问题
    • 缓存和数据库双写一致性问题: 强一致性需求必然不能用Redis。其次,日常先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施,例如利用消息队列。
    • 缓存穿透问题: 即黑客故意请求缓存中不存在的数据,导致所有的请求都怼到数据库上,从而数据库连接异常。解决方案:
      • 采用互斥锁: 缓存失效时先去获得锁,然后才能请求数据库;
      • 采用异步更新策略: 无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。
      • 提供一个能迅速判断请求是否有效的拦截机制: 比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回。
    • 缓存雪崩问题: 即缓存同一时间大面积失效,这时又来了一波请求,都推向数据库,导致数据库连接异常。
      • 给缓存的失效时间加上随机值,避免集体失效;
      • 使用互斥锁,但是这样吞吐量明显下降;
      • 双缓存: 我们有两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设失效时间。读取A中没有时去B中读数据,且异步启动更新线程,更新线程同时更新缓存A和B。
    • 缓存的并发竞争问题: 同时有多个子系统去set一个key。
      • 解决方法: 事务机制。
      • 若做了Redis在集群环境下,且数据分片操作,那么应该:①使用分布式锁;②对set要求顺序的话,保存一个时间戳,或利用队列,将set方法变成串行操作。

二. Redis的数据类型及使用场景

  • string: 最常规的set/get操作,value可以是String也可以是数字,一般做一些复杂的计数功能的缓存。
  • hash: value存放的是结构化的对象,方便操作其中的某个字段。
  • list: 可以做简单的消息队列的功能。
  • set: 可以做全局去重的功能。
  • sorted set: 多了一个权重参数score,集合中的元素能够按score进行排列,可以做排行榜应用,取TOP N操作。

三. 过期策略及内存淘汰机制

  1. 过期策略:定期删除+懒惰删除策略
    • 定期删除: redis默认每个100ms进行随机抽取检查,是否有过期的key,有过期key则删除。
    • 惰性删除: 在获取某个key的时候检查,如果设置了过期时间且过期了则删除。
  2. 内存淘汰机制:
    在redis.conf中有一行配置# maxmemory-policy volatile-lru用于配置内存淘汰策略。具体策略如下:
    • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
    • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。(推荐使用)
    • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
    • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。(一般是既把redis既当缓存,又做持久化存储的时候用)
    • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
    • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。

参考: https://blog.csdn.net/hjm4702192/article/details/80518856