随手记点笔记,不全,自用

删除策略

定时删除

  • 定时删除,CPU 占用大

惰性删除

  • 过期数据二次访问后才删除,内存占用大

定期删除

  • 随机抽查删除,hz 值决定了 CPU 和内存哪个占用大

淘汰策略

  • 内存不足时按策略删除

    • maxmemory ?mb 最大可用内存,默认为 0 不限制,一般设置物理机的 50%以上

    • maxmemory-samples count 每次随机删除的数据个数

    • maxmemory-policy policy 删除策略

      • volatile 易失数据

        • volatile-lru 按最后一次使用时间
        • volatile-lfu 按最近使用次数
        • volatile-ttl 按即将过期的数据
        • volatile-random 随机
      • allkeys 全库数据

        • allkeys-lru 按最后一次使用时间
        • allkeys-lfu 按最近使用次数
        • allkeys-random 随机
      • no-enviction 放弃数据驱逐

主从复制

建立连接的流程

  • 设置 master 地址和端口并保存
  • 建立 socket 连接
  • 发送 ping 命令(定时器任务)
  • 身份验证
  • 发送 slave 端口信息

数据同步

  • 全量复制

    • 发送指令 psync2
    • 执行 bgsave
    • 第一个 slave 连接时创建命令缓冲区
    • 生成 RDB 文件通过 socket 发给 slave
    • 接收 RDB,清空数据,执行恢复过程
  • 部分复制

    • 发送命令告知 RDB 已经恢复完成
    • 发送复制缓冲区信息
    • 接收信息,执行 bgrewriteaof,恢复数据
  • 心跳机制

    • master 心跳

      • 内部指令 PING
      • 周期 repl-ping-slave-period 默认 10 秒
      • INFO replication 获取 slave 最后一次连接时间间隔,lag 项维持在 0 或 1 视为正常
    • slave 心跳

      • 内部指令 REPLCONF ACK {offset}
      • 周期 1 秒
      • 汇报 slave 自己的复制偏移量,获取最新的数据变更指令
      • 判断 master 是否在线
  • 注意事项

    • master 数据同步应避开流量高峰期
    • 复制缓冲区太小会导致数据溢出,出现数据丢失并自动进行二次全量复制,死循环 repl=backlog-size ?mb 建议留下 30%~50%的内存用于执行 bgsave 命令和创建复制缓冲区
    • 避免 slave 同步过程服务器响应阻塞或者数据不同步,建议关闭此期间的对外服务 slave-serve-stale-data yes | no
    • 数据同步阶段,master 主动发送命令给 slave,可以理解为是一个客户端
    • 多个 slave 同时对 master 请求同步,RDB 只会有一份,但是带宽压力变大,可以适量错峰但是 RDB 会有多份
    • slave 过多可以采用树状结构,但是数据一致性差

哨兵模式

检测 master 是否宕机,master 宕机后选举 slave 为 master

建立过程配置

  • sentinel monitor master_name master_host master_port sentinel_number 设置监听的主服务器信息,sentinel_number 表示参与投票的哨兵数量
  • sentinel down-after-milliseconds master_name million_seconds 设置宕机时长,控制是否进行主从切换
  • sentinel failover-timeout master_name million_seconds 设置故障切换操作的最大超时时长
  • sentinel parallel-syncs master_name sync_slave_number 设置主从切换后,同时进行数据同步的 slave 数量,越大网络资源要求越高,越小同步时间越长

监控阶段

  • 检查各个哨兵是否在线
  • 先向 master 发 info 查询其信息和名下 slave
  • 再向 slave 发 info 查询 slave 具体信息

故障转移阶段

  • 单个哨兵监测到 master 无响应(主观下线) SRI_S_DOWN

  • 半数哨兵监测到 master 无响应(客观下线) SRI_O_DOWN

  • 哨兵选举

  • 选举 master 优先级

    • 不在线的

    • 响应慢的

    • 与原来 master 断开连接时间长的

    • 优先原则

      • 优先级
      • offset 偏移量大
      • runid

Cluster 集群

数据存储结构

  • 保存流程

    • CRC(key)%16384 计算结果为某台服务器中的槽位地址,该槽位不止存储一个 key,而是大量 key
  • 查询流程

    • 各个数据库相互通信,保存各个库中槽位的编号数据
    • 一次查询命中直接返回
    • 一次未命中,告知具体的位置

配置

  • cluster-enabled yes|no 是否启用 cluster,加入 cluster 节点
  • cluster-config-file filename cluster 配置文件名,该文件会自动生成,尽量手动命名否则会共用
  • cluster-node-timeout milliseconds 节点服务响应超时时间
  • cluster-migration-barrier min_slave_number master 连接的 slave 最小数量

企业级解决方案

缓存预热

  • 现象:启动服务器后立刻宕机
  • 解决思路:系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

缓存雪崩

  • 现象:短时间范围内,大量 key 集中过期导致一系列宕机

  • 解决思路

    • 更多的页面静态化处理
    • 构建多级缓存架构
      Nginx 缓存+redis 缓存+ehcache 缓存
    • 检测 Mysql 严重耗时业务进行优化
      对数据库的瓶颈排查:例如超时查询、耗时较高事务等
    • 预警机制
    • 限流、降级
  • 具体解决方案

    • 切换为 LFU 淘汰策略
    • 调整过期的时间,使其错峰
    • 超热数据暂时使用永久 key
    • 定期维护(自动+人工)
      对即将过期数据做访问量分析,确认是否延时,配合访问量统计,做热点数据的延时
    • 加锁:慎用!

缓存击穿

  • 现象:Redis 中某个高热点 key 过期,该 key 访问量巨大

  • 解决方案

    • 增加热点 key 的时间
    • 设置热点 key 为永久
    • 高峰期来临前自动刷新有效期
    • 二级缓存,设置不同的过期时间错峰
    • 分布式锁

缓存穿透

  • 现象:黑客大量访问不存在的数据,跳过 redis 直接攻击数据库

  • 解决方案

    • 1、对查询结果为 null 的数据进行缓存(长期使用,定期清理),设定短时限,例如 30-60 秒,最高 5 分钟
    • 2、白名单策略
      提前预热各种分类数据 id 对应的 bitmaps,id 作为 bitmaps 的 offset,相当于设置了数据白名单。当加载正常数据时放行,加载异常数据时直接拦截(效率偏低)
      使用布隆过滤器(有关布隆过滤器的命中问题对当前状况可以忽略)
    • 3、实时监控 redis 命中率,提前预防,使用黑名单进行防控
    • 4、key 加密
      问题出现后,临时启动防灾业务 key,对 key 进行业务层传输加密服务,设定校验程序,过来的 key 校验
      ​ 例如每天随机分配 60 个加密串,挑选 2 到 3 个,混淆到页面数据 id 中,发现访问 key 不满足规则,驳回数据访问