缓存【分布式缓存高可用方案】
一、简介
上图所示,我们在服务层和数据库层之间增加一个缓存层,现在我们读取数据的时候,先从缓存里面读取,读不到的再去读数据库。
既然我们引入了缓存,那肯定是想更多的请求尽量落在缓存上,也就是说我们必须要关注缓存命中率,命中率越高就代表我们的后端存储就越不容易被拖垮成为性瓶颈,如果我们的缓存命中率下降一定要看是什么原因,因为对于高并发请求哪怕下降1% 都是灾难。
普通机器MySql也大概2000的并发。
二、方案
分布式缓存高可用方案有:应用端、中间代理层、服务端。
2.1、应用端方案
在应用端只配置缓存节点,通过缓存写入和读取算法策略来实现分布式,提高缓存可用性。
2.2、代理层方案
在应用代码和缓存节点之间增加一个独立的代理层,应用端就直接与代理层连接,代理层自己内置高可用策略,以提升缓存的可用性。
2.3、服务端方案
缓存服务自身提供的高可用,例如Redis Sentinel。
三、方案详情
3.1、应用端方案
应用端也就是代码层面上,需要自己管理缓存的读和写,也就是通过写代码方式来进行分布式缓存的写入和读取,主要是下面这两模块:
1、写缓存时,我们需要将数据分散到缓存的各个节点中,即要实现数据分片。
2、读缓存时,需考虑主从或者多副本粗略以及使用多组缓存进行容错。
3.1.1、缓存数据如何分片
我们知道单节点的缓存因受到各种原因如本身机器内存、网络带宽等,从而不能承受更高的并发,所以我们需要将数据进行分片存储,即将数据通过分片算法打散到各个缓存节点中。其实这块大家有没有注意到和我们前面的分库分表很类似,所以大部分架构思想都是相通的。
现在我们的数据就在各个缓存节点都有一部分,即使部分故障,也是不影响我们整个业务的。那这个时候,你可能在想,既然数据需要被均匀分散到各个节点,那我该怎么来写这个分片算法呢?别急,我们下面就来看怎么写这个分片算法
3.1.2、数据分片算法
Hash分片算法、一致性Hash分片算法。具体过程可以参考Hash算法章节。
注意的是。一致性Hash算法,一定要设置过期时间,不然很容易因为节点和服务器因为断网,导致数据脏读。
Memcached也可以做主从,保证高可用。
3.2、中间代理层
代理层自己管理缓存节点高可用,通过某种协议,如redis协议,来和各种语言业务端连接。业界也有很多中间代理层方案,比如 Facebook 的Mcrouter,Twitter 的Twemproxy,豌豆荚的Codis。基本架构如下:
中间层代理方案即所有缓存读写的操作都直接通过代理层完成,代理层自己完成上面应用端所有的操作。
3.3、服务端方案
服务端方案主要是缓存服务自己管理的,对于我们开发人员不用自己写代码管理也不用引入中间层,就是需要相关运维配置支持,比如redis的sentinel模式就是用来解决redis部署时高可用问题,它可以在主节点挂了以后自动将从节点提升为主节点,保证整体集群的可用。所以服务端对于我们开发影响不是太大,redis的sentinel我们还得需要知道的,可以参考相关章节。