13缓存如何高可用

133 阅读3分钟

1.概览

缓存命中率 = 命中缓存的请求数 / 总请求数(99%以上)

同时部署多个节点,让节点互为备份

  • 客户端方案
    • 客户端配置多个缓存节点,通过缓存写入和读取算法策略实现分布式
  • 中间代理层方案
    • 在应用代码和缓存节点间增加代理层,
  • 服务端方案
    • redis2.4以后的Redis Sentinel 方案

image.png

2.客户端(业务代码)方案(代码层面)

缓存的写和读两个方面

  • 写入数据,写入缓存节点分散到多个节点中
  • 读数据,利用多组缓存做容错,提升系统可用性
    • 主从和副本策略

2.1缓存数据如何分片

  • 要求
    • 单机存储有限
    • 同时保证一定的可用性
  • Hash分片算法
    • 算法思想:对缓存key进行hash计算,对总缓存节点个数取余
    • 优点:算法简单
    • 缺点:缓存节点发生变化,导致节点发生变化,造成缓存失效
    • 适用场景:对缓存命中率不敏感
  • 一致性Hash分片算法
    • 算法思想:hash值空间组成一个虚拟的圆环,将特征hash后在放置环中,每次找一个最近的节点
    • 优点:增加和删除节点,只有少量的key会漂移到其他节点
    • 缺点:
      • 分布不均匀会造成缓存节点压力较大
      • 一个节点发生故障,导致后面节点造成更大压力
      • 存在脏数据问题
    • 适用场景:分号解决增加和删减节点,命中率下降的问题

image.png 增加节点后

image.png

为了解决一个节点的crash导致后续一系列节点crash的情况:

可以在在hash环上引入虚拟节点,避免一个节点crash导致所有节点的crash

为了解决节点的脏数据问题:

一定要设置缓存的过期时间,通过过期时间减少脏数据的几率

image.png

批量获取,单个节点的访问量没有减少(遍历所有节点)(尽量不要使用批量查询)

因为根据木桶原则,SLA 取决于最慢、最坏的节点的情况,节点数过多也会增加出问题的概率,因此推荐 4 到 6 个节点为佳。

2.2Memcached的主从机制

  • 为每一组 Master 配置一组 Slave,更新数据时主从同步更新
  • 优先从 Slave 中读数据,如果读取不到数据就穿透到 Master 读取,并且将数据回种到 Slave 中以保持 Slave 数据的热度
  • 当某一个 Slave 宕机时,还会有 Master 作为兜底,不会有大量请求穿透到数据库的情况发生,提升了缓存系统的高可用性

image.png

2.3多副本

  • 在副本中存储最热的数据
  • 在 Master/Slave 之前增加一层副本层
  • 请求首先会先从多个副本组中选取一个副本组发起查询,如果查询失败,就继续查询 Master/Slave,并且将查询的结果回种到所有副本组中,避免副本组中脏数据的存在 image.png

3.中间代理层方案

  • 客户端方案会在切换语言后不可使用
  • 可以通过缓存代理层将客户端高可用逻辑封装在代码里面,不再需要依赖客户端代码
  • 业界方案
  • 所有读写请求经过代理层完成,代理层是无状态的
  • 主要负责读写请求的路由功能,高可用逻辑

image.png

4.服务端方案

  • Redis 在 2.4 版本中提出了 Redis Sentinel 模式来解决主从 Redis 部署时的高可用问题
  • 主节点挂了以后自动将从节点提升为主节点,保证整体集群的可用性
  • Sentinel也有主备,同时是无状态的
  • 所有的读写请求不会经过Sentinel

image.png

5.总结

需要根据实际情况进行自研