缓存如何做到高可用
分布式缓存的高可用方案有以下三类:
1、客户端方案:在客户端配置多个缓存的节点,通过缓存写入和读取算法策略来实现分布式,从而提高缓存的可用性。
2、中间代理层方案:在应用代码和缓存节点之间增加代理层,客户端所有的写入和读取的请求都通过代理层,而代理层中会内置高可用策略,帮助提升缓存系统的高可用。
3、服务端方案:Redis 2.4 版本后提出的 Redis Sentinel 。
客户端方案
在该方案中,需要注意缓存的读写。写需要将数据分片,而读可以用多组缓存做容错,提升系统的可用性。
缓存数据分片
当单一机器无法存储所有的数据时,我们就需要将缓存分配到不同的机器上,每个节点上存储部分数据。
一般来讲,分片算法常见的就是 Hash 分片算法和一致性 Hash 分片算法两种。
1、Hash分片
Hash分片就是对key做哈希计算,然后对总的缓存节点取余。该算法优点是简单,缺点是当增加或者减少分片节点数量时,计算的方式也要发生变化。该方案适合缓存命中率下降不敏感的业务。
2、一致性Hash
一致性 Hash 算法可以很好地解决增加和删减节点时,命中率下降的问题。
该算法中,我们将整个Hash值空间组织成一个虚拟的圆环,然后将每一个分片节点的ip或者主机名做hash后放在该圆环上。当需要确定某一个key在哪个节点上时,先对key做hash,确定在换上的位置(注意,这一步做完hash后,不一定会直接落到某一个节点的下标处,所以需要顺时针往下走),然后往下走,找到第一个是节点的位置,就将数据存储在该节点中。
在该算法中,删除节点会导致节点上的数据漂移到下一个节点上,对于hash命中率并不会造成特别大的影响。
存在的问题:
1、缓存节点在圆环上分布不均匀,会造成部分节点压力很大,而且当一个节点失效,会将数据全部转移到下一个节点。
2、一致性 Hash 算法的脏数据问题。
针对于第一个问题,在某个节点出问题时,要将节点平均分配到其他的几个节点上,而不能将它全部移交到下一个节点上。
对于第二个问题,如果节点3中有一个数据,现在要修改该数据,但是节点3此时无法连接,那么修改操作就会发生到节点4,那么当节点3恢复后,客户端就会从节点3中读取到脏数据。解决办法就是增加过期时间。
参考
《高并发系统设计》