Redis基础知识点整理

缓存雪崩

缓存同一时间大面积失效(缓存服务器重启/缓存数据失效),后续请求直接打到数据库上,造成数据库短时间内承受大量请求而崩溃

解决办法

  1. 缓存数据的过期时间设置随机,防止同一时间大量数据过期
  2. 缓存预热,把热点数据预先写到缓存里
  3. 给每个缓存增加相应的缓存标记记录缓存是否失效,缺点是会增加系统消耗
  4. 互斥锁,对同一个缓存键上锁

缓存穿透

缓存和数据库中都没有的数据,每次请求都会打到数据库上

解决办法

  1. 在接口层增加校验
  2. 对于缓存和数据库中都没有的数据,可以将请求的键值设置为null,这样可以防止对同一个键值的重复请求
  3. 布隆过滤器

缓存击穿

缓存中没有(一般是缓存时间过期),数据库中有

解决办法

  1. 设置热点数据永不过期
  2. 加互斥锁,访问的缓存键加锁这样访问数据库只有一个请求,其他请求都在排队,可以减少请求打到数据库上的数量

setnx 和 set 的区别

setnx将key的值设定为value,当且仅当key不存在;若给定的key已存在,则setnx不做任何动作

redis的过期键删除策略

  1. 惰性过期:只有当访问key时才会判断该key是否过期,过期则清除,能大量节省cpu,对内存不友好
  2. 定期过期:每隔一定时间会扫描一定数量的expires字典中的key,并且清除过期的key,消耗cpu,对内存友好。

调优: 可以调整扫描时间间隔和每次扫描限定耗时

redis线程模型

  1. 纯内存操作
  2. IO多路复用
  3. 单线程避免了多线程的频繁上下文切换带来的性能问题
  4. 存储数据结构(全局哈希表)
    1. string类型:redis存储键值对的时候会先把值转换成整型,如果能转那么这个键就是整型
    2. hash结构:hset
    3. 列表list结构:
      1. lpush key value 从左边
      2. rpush key value 从右边
    4. set集合结构:
      1. SADD key { 集合 }
      2. SPOP key count
    5. 有序集合zset
      1. 跳表:有序单链表+索引,便利变成二分查找O(logN),空间换时间。将有序链表改造为支持二分查找,可以快速的插入、删除、查找操作。元素越多(超过128),zset自动调整为调表存储结构

redis事务实现

A:原子性,没有回滚机制
C: 一致性
I: 持久性
D: 隔离性,单线程

  1. 事务开始:multi命令会将客户端状态的flag属性中打开REDIS_MUTIL标识
  2. 命令入队:命令放到队列中并检查命令语法是否正确(redis只会检查语法是否正确不会对具体的操作命令做检查,如果操作出错不会回滚),等到客户端发送EXEC命令,执行事务
  3. 事务执行:客户端发送EXEC命令。遍历事务队列然后执行

WATCH:乐观锁
MUTIL:用于开启一个事务
EXEC:执行事务内的命令
DISCARD:客户端可以清空事务队列,并放弃执行事务,客户端从事务状态中退出
UNWATCH:取消watch对所有key的监控

redis集群方案

  1. 主从
    1. 哨兵模式:高可用,分布式。通常需要三个哨兵实例,保证集群健壮性。不保证数据零丢失,只保证高可用
  2. redis cluster(服务端分片)
    1. 通过哈希将数据分片,每个节点均分存储一定哈希槽(哈希值)区间的数据,默认分配了16384个槽位
    2. 互为主从,不保持强一致性。
    3. 需开放两个端口号,一个6379,另一个默认加10000的端口。6379用来数据访问,16379用来节点之间通讯。
    4. 无中心架构,支持动态扩容
  3. redis sharding(客户端分片)
    1. 每个redis实例像单服务实例,非常容易线性扩展

redis主从复制核心原理

  1. 全量复制:
    1. 主节点通过bgsave命令fork子进程进行RDB持久化,该过程非常消耗CPU,内存(页表复制),硬盘IO
    2. 主节点通过网络讲RDB文件发送给从节点,这对主节点的带宽有很大的消耗
    3. 从节点清空老数据,载入新的RDB文件的过程是阻塞的,无法响应客户端的命令,如果从节点执行bgrewriteaof也会带来额外的消耗
  2. 部分复制:
    1. 复制偏移量,执行复制的双方主从节点,分别会维护一个复制偏移量offset
    2. 复制积压缓冲区:主节点内部维护了一个固定的长度队列作为复制积压缓冲区,当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制只能执行全量复制
    3. 服务器运行ID(runid):每个redis节点都有运行ID,主节点将自己的运行ID发送给从节点,从节点讲主节点的运行ID存起来,从节点根据运行ID来判断同步的进度
      1. 如果从节点保存的runid和主节点的runid相同,说明之前主从同步过,主节点会继续尝试使用部分复制
      2. 如果从节点保存的runid和主节点的runid不同,说明节点在断线前同步的redis节点不是当前的主节点,只能进行全量复制

过程如下
avatar

CAP理论

  1. C(Consistency) 一致性
    所有节点在同一时间的数据完全一致
    对于客户端,并发访问时获取到的数据保持一致
    对于服务端,将更新复制分布到整个系统保持数据最终一致

  2. A(Availability):可用性
    服务一直可用并且正常响应时间

  3. P(Partition Tolerance):分区容错性
    分布式系统在遇到某个节点或网络故障,任能对外提供满足一致性和可用性的服务

CP和AP:当网络发生分区,如果要继续服务,那么一致性和可用性只能二选一,但是必须保证分区容错性

BASE理论

对于CAP理论一致性和可用性平衡的结果

  • 基本可用
    • 响应时间上:正常0.5s;异常3s
    • 系统功能上:正常全部功能可用;异常部分功能可用
  • 软状态:数据同步允许一定的延迟
  • 最终一致性:系统所有数据副本在一段时间的同步后最终达到一致性,不要求实时