• 关于 Redis 的这些知识 你知道哪些


    关于 Redis 的这些知识 你知道哪些


    1、Redis 高可用的实现

    ​  实现 Redis 的高可用,主要有 哨兵 和 集群 两种方式。


    1.1、哨兵

    ​  Redis Sentinel(哨兵)是一个 分布式架构,它包含 若干 哨兵节点 和 数据节点,每个哨兵节点 会对 数据节点 和 其余的哨兵节点 进行监控,当发现节点不可达(节点发生宕机)时,会对节点做 下线标识。

    ​  如果 被标识的 是 主节点,它就会与 其它的哨兵节点 进行协商,当 多数哨兵节点 都认为 主节点 不可达时,它们便会选举出一个 哨兵节点 来完成 自动故障转移 的工作,同时还会将这个变化实时地通知给 应用方(整个过程是自动完成,不需要人工介入)。

    ​  注:一组哨兵 可以监控 一个(或多个)主节点。

    在这里插入图片描述


    补充:哨兵节点的特征

    • 哨兵节点 会 定期 监控数据节点、其它哨兵节点 是否可达;
    • 哨兵节点 会 将 故障转移的结果 通知给应用方;
    • 哨兵节点 可以 将 从节点 晋升为 主节点,并维护后续正确的主从关系;
    • 哨兵模式下,客户端 连接的是 哨兵节点集合,并从中获取主节点信息;
    • 节点的故障判断 是由 多个哨兵节点 共同完成的,可以有效防止误判;
    • 哨兵节点集合 是由 多个哨兵节点 组成,即使 个别哨兵节点 不可用,整个集合依然可以正常工作;
    • 哨兵节点 是 独立的、特殊的 Redis 节点,它们 不存储数据,只支持部分命令。


    1.2、集群

    ​  Redis 集群 采用 虚拟槽分区 来实现 数据分片,它把 所有的键 根据 哈希函数映射 到 0 - 16383 整数槽内(计算公式为 slot = CRC16(key)&16383 ),每一个节点 负责维护一部分 槽和槽所映射的键值数据。

    ​  虚拟槽分区的特点:

    • 解耦 数据 和 节点 之间的关系,简化了 节点 扩容 和 收缩 的难度;
    • 节点自身 维护 槽的映射关系,不需要 客户端(或代理服务)维护 曹分区的元数据;
    • 支持 节点、槽、键 之间的 映射查询,用于 数据路由、在线伸缩 等场景。

    在这里插入图片描述



    2、Redis 的主从同步

    ​  主从同步,是指将一台 Redis 服务器的数据,复制到其它的 Redis 服务器上,前者称为主节点(Master),后者称为从节点(Slave)。数据的复制是单向的,只能由主节点复制到从节点(主节点以写为主、从节点以读为主)。

    ​  注:默认情况下,每台 Redis 服务器 都是主节点,一个主节点可以有 0 个或者多个从节点,但每个从节点只能有一个主节点。

    ​  Redis 使用 psync 命令 完成主从同步,同步过程分为 全量复制 和 部分复制,全量复制 一般用于 初次复制的场景,部分复制 则用于 处理因网络中断 等原因 造成数据丢失的场景。

    ​ psync 命令 所需要的 参数:

    • 复制偏移量
      • 主节点处理写命令后,会把命令长度做累加记录;从节点在接收到写命令后,也会做累加记录;
      • 从节点会每秒上报一次自身的复制偏移量给主节点,而主节点则会保存从节点的复制偏移量。
    • 积压缓存区
      • 保存在主节点上的一个固定长度的队列,默认大小为 1M,当主节点有连接的从节点时被创建出来;
      • 主节点在处理命令时,不但会把命令发送给从节点,还会写入积压缓冲区;
      • 缓存区是先进先出的队列,可以保存最近已复制的数据,用于部分复制和命令丢失的数据补救。
    • 主节点运行 ID
      • 每个 Redis 节点启动后,都会动态分配一个 40 位的十六进制字符串作为运行 ID;
      • 如果使用 IP 和 端口 的方式标识主节点,那么主节点重启变更了数据集(RDB/AOP),从节点再基于复制偏移量复制数据将是不安全的,因此当主节点的运行 ID 变化后,从节点将做全量复制。

    在这里插入图片描述
    在这里插入图片描述



    3、Redis 的淘汰策略

    ​  当写入数据将导致超出 maxmemory 限制时,Redis 会采用 maxmemory-policy 所指定的策略进行数据淘汰。

    ​  8 种淘汰策略:

    策略说明
    noeviction直接返回错误
    volatile-ttl从设置了过期时间的键中,选择过期时间最小的键,进行淘汰
    volatile-random从设置了过期时间的键中,随机选择键,进行淘汰
    volatile-lru从设置了过期时间的键中,使用 LRU 算法选择键,进行淘汰
    volatile-lfu从设置了过期时间的键中,使用 LFU 算法选择键,进行淘汰
    allkeys-random从所有的键中,随机选择键,进行淘汰
    allkeys-lru从所有的键中,使用 LRU 算法选择键,进行淘汰
    allkeys-lfu从所有的键中,使用 LFU 算法选择键,进行淘汰

    补充:

    1、LRU(Least Recently Used,最近最少使用)

    • 标准 LRU

      ​  把所有的数据组成一个链表,表头和表尾分别表示 MRU端 和 LRU 端(即 最常使用端 和 最少使用端),新增的数据(或 刚被访问的数据)会被移动到 MRU 端,当链表的空间被占满时,它会删除 LRU 端的数据。

    • 近似 LRU

      ​  记录每个数据的最近一次访问的时间戳,当 内存超出限制 时,随机采样 N 个 key,淘汰最旧的 key。(可以通过 maxmemory_samples 设置采样个数,默认值为 5)

    2、LFU(Least Frequently Used,最少频率使用)

    ​  在 LRU 的基础上,为每个数据增加了一个计数器,来统计该数据的访问次数,当 内存超出限制 时,首先会将 访问次数最低 的数据淘汰出去,如果两个数据的访问次数相同,则将 访问时间更早 的数据淘汰出去。




    4、Redis 的过期策略

    • 惰性删除

      ​  客户端访问一个 key 的时候,Redis 会先检查它的过期时间,如果发现过期就立刻删除这个 key 。

    • 定期删除

      ​  Redis 会将设置了过期时间的 key 放到一个独立的字典中,并对该字典进行每秒 10 次的过期扫描,过期扫描不会遍历字典中所有的 key,而是采用了一个种简单的贪心策略:

      1. 从过期字典中随机选择 20 个 key;
      2. 删除这 20 个 key 中已过期的 key;
      3. 如果过期 key 的比例超过 25%,则重复步骤 1 。


    5、缓存穿透、击穿、雪崩

    5.1、缓存穿透

    问题描述:

    ​  客户端查询根本不存在的数据,使得请求知道存储层,导致其负载过大,甚至宕机。出现这个情况的原因,可能是业务层误将缓存和库中的数据删除了,也可能是有人恶意攻击,专门访问库中不存在的数据。

    解决方案:

    1. 缓存空对象

      ​  存储层未命中后,仍然将空值存入缓存层,客户端再次访问数据时,缓存层会直接返回空值。

    2. 布隆过滤器

      ​  将数据存入布隆过滤器,访问缓存之前以过滤器拦截,若请求的数据不存在,则直接返回空值。


    扩展:布隆过滤器

    • 核心组成
      • 一个大型的位数组
      • 若干个不一样的哈希函数,每个哈希函数都能将哈希值算的比较均匀
    • 工作原理
      • 添加 key 时,每个哈希函数都利用这个 key 计算出一个哈希值,再根据哈希值计算一个位置,并将位数组中这个位置的值设置为 1;
      • 询问 key 时,每个哈希函数都利用这个 key 计算出一个哈希值,再根据哈希值计算一个位置,并对比这些哈希函数在位数组中对应位置的数值。
        • 如果这几个位置中,有一个位置的值都是 0,就说明这个布隆过滤器中,不存在这个 key;
        • 如果这几个位置中,所有位置的值都是 1,就说明这个布隆过滤器中,极有可能存在这个 key(存在一定的错误率)。


    5.2、缓存击穿

    问题描述:

    ​  一份热点数据,它的访问量非常大,在其缓存失效的瞬间,大量请求知道存储层,导致服务奔溃。

    解决方案:

    1. 永不过期

      ​  热点数据不设置过期时间,或者 为每个数据设置逻辑过期时间,当发现该数据逻辑过期时,使用单独的线程重建缓存。

    2. 加互斥锁

      ​ 对数据的访问加互斥锁,当一个线程访问数据时,其它线程只能等待,这个线程访问过后,缓存中的数据将被重建,届时其它线程就可以直接从缓存中取值。


    5.3、缓存雪崩

    问题描述:

    ​  在某一时刻,缓存层无法继续提供服务,导致所有的请求知道存储层,造成数据库宕机,可能是缓存中有大量数据同时过期,也可能是 Redis 节点发生故障,导致大量请求无法得到处理。

    解决方案:

    1. 避免数据同时过期

      ​  设置过期时间时,附加一个随机数,避免大量的 key 同时过期。

    2. 启动降级和熔断措施

      ​  在发生雪崩时,若应用访问的不是核心数据,则直接返回预定义信息 / 空值 / 错误信息,或者 在发生雪崩时,对于访问缓存接口的请求,客户端并不会把请求发给 Redis,而是直接返回。

    3. 构建高可用的 Redis 服务

      ​  采用哨兵或集群模式,部署多个 Redis 实例,个别节点宕机,依然可以保持服务的整体可用。



    6、缓存与数据库的双写一致性

    4 种同步策略:

    1. 先更新缓存,再更新数据库;
    2. 先更新数据库,再更新缓存;
    3. 先删除缓存,再更新数据库;
    4. 先更新数据库,再删除缓存(常用)。

    扩展:延时双删

    1. 删除缓存;
    2. 更新数据库;
    3. sleep N 毫秒;
    4. 再次删除缓存。

  • 相关阅读:
    Verilog 过程结构(initial, always)
    代码随想录贪心算法——买卖股票的最佳时机含手续费
    grpc 编译
    机器学习笔记 - 图解对象检测任务(2)
    【Spring Cloud】CentOS 安装 DockerCE
    CAS解决原子性问题的另一种方案
    变量承接函数类型的方法
    讲讲springboot的@Async
    UDP 报文结构与注意事项全解析
    iOS学习 --- Xcode 15 下载iOS_17.0.1_Simulator失败解决方法
  • 原文地址:https://blog.csdn.net/weixin_51123079/article/details/126455188