使用缓存承担大部分的读压力,可以缓解数据库的查询压力,提升了保证系统稳定性。
分布式高可用方案分布式缓存高可用方案有三种:
- 客户端方案,一般称为 Smart Client 。通过指定一些数据分片和数据读写策略,实现缓存高可用。在客户端配置多个缓存节点,通过缓存写入和读取算法策略实现分布式,从而提高缓存的可用性。
- 中间代理方案,在客户端和缓存节点之间中间层,在性能上会有一定损耗,在代理层,代理层采用内置的高可用方案,帮助提升缓存系统的高可用,比如 Codis 使用 Sentinel 。
- 服务端方案,依赖组件实现, Memcached 只支持单机版,没有分布式 和 HA 方案,Redis 在 2.4 版本提供了 sentinel 方案可用自动主从切换。
实现方案主要有三种:
- 缓存分片
- 主从
- 多副本
通过分片算法常见的算法有 Hash 分片算法和一致性 Hash 分片算法。
缓存分片Hash 分片算法:
三个缓存节点组成一个缓存集群,当有新的数据写入时,这个缓存 key 做 crc32 等 Hash 算法生成 Hash 值,得出存入缓存节点的序号。
算法缺点是,增删节点,如果缓存节点个数变化,这样计算出来的节点会发生变化,从而造成缓存失效。
一致性 Hash使用一致性 Hash 算法可以很好的解决增删节点 ,导致命中率下降的问题。
- 缺点
- 缓存节点在环上分布不均匀的问题,造成部分节点压力大。
- 一致性 Hash 脏数据问题
其次,就是一致性Hash算法的脏数据问题。为什么会产生脏数据呢?比方说,在集群中有两个节点A和B,客户端初始写入一个Key为k,值为3的缓存数据到 Cache a中。 这时如果要更新k的值为4,但是缓存A恰好和客户端连接出现了问题,那这次写入请求会写入到 Cache B中。接下来缓存A和客户端的连接恢复,当客户端要获取k的值时,就会获取到存在 Cache a中的脏数据3,而不是 Cache B中的4。
Memmcacjed 主从它是一个单 master 单 slave的方案,但它的 master/slave都是可读写的,而且可以相互同步,如果 master坏掉, slave 侦测到连接断了,它会自动 listen而成为 master;而如果 slave 坏掉, master也会侦测到连接断,它就会重新 listen等待新的 slave加入.
Redis 支持主从部署,但是 Memcached 并不支持。主从及机制最大的问题是,当一个 Slave 宕机,有 Master 继续处理,提升了缓存的高可用性。
多副本主从方式能够解决大部分场景,但是在极端流量情况下,不能承担所有流量, Slave 网卡带宽会是瓶颈。为解决这个问题,可以在 Master / Slave 直接增加一层副本。这样当有读请求时,先从副本中选取一个副本查询, 查询失败,查询 Master/Slave.
中间代理层方案客户端能够给解决很多问题,但是不同语言间不通用,比如 Java, C, PHP 各需要一套客户端方案。 十分麻烦。
代理层无状态,主要负责读写请求路由功能,并且内置高可用逻辑。
服务端方案Redis Sentinel 模式解决了主从 Redis 部署时的高可用问题,可在主节点宕机后自动将从节点提升为主节点。保证整体集群可用性。
欢迎关注公众号:程序员开发者社区