本地缓存和分布式缓存的比较

分布式缓存一致性更好一点,本地缓存 每个实例都有自己的缓存,可能会存在不一致的情况。

本地缓存会占用堆内存,影响垃圾回收、影响系统性能。分布式缓存两大开销会导致其慢于本地缓存,网络延迟和对象序列化

进程内缓存适用于较小且频率可见的访问场景,尤其适用于不变对象,对于较大且不可预见的访问,最好采用分布式缓存。

我们在服务层和数据库层之间增加一个缓存层,现在我们读取数据的时候,先从缓存里面读取,读不到的再去读数据库。

现在我们的数据就在各个缓存节点都有一部分,即使部分故障,也是不影响我们整个业务的。那这个时候,你可能在想,既然数据需要被均匀分散到各个节点,那我该怎么来写这个分片算法呢?别急,我们下面就来看怎么写这个分片算法。

数据分片算法

一般做数据分片算法的有两种,大家应该都清楚吧,分库分表就有用到的

  • Hash分片算法
  • 一致性Hash分片算法

Hash分片算法

Hash分片算法就是我们拿到缓存的key,然后对其做hash运算,最后将hash运算的结果对缓存总节点数取余,得到的数字则为具体的分片节点。比如,现在我们缓存节点一共有 3 个,当我们写入数据的时候,将key进行hash运算hash(key),然后将结果对3取余就行了。

这种分片算法优点就是开发简单且容易理解,缺点就是当我们的缓存总节点数改变的时候,就会导致数据不均匀,则会造成大量缓存失效不可用的情况。但是这种算法我们开发中也是会使用的,比如我们的业务对于缓存的命中率不是那么太在意的,就可以使用这种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。

 

既然我们引入了缓存,那肯定是想更多的请求尽量落在缓存上,也就是说我们必须要关注缓存命中率,命中率越高就代表我们的后端存储就越不容易被拖垮成为性瓶颈,如果我们的缓存命中率下降一定要看是什么原因,因为对于高并发请求哪怕下降1% 都是灾难。

比如,现在的系统QPS是10000,每次请求会查询10次的缓存,现在命中率突然下降了1%,也就是我有 10000 * 10 * 1% =1000次的请求落到了我们后端数据库MySql上了。这就代表了MySQL数据库面临突然增加的1000的并发,这是很危险的,基本普通机器mysql也只能抗大概2000的并发。所以,缓存命中率是要我们关注的。

 

分布式缓存的优缺点
1. 支持大数据量存储,不受应用进程重启影响
分布式缓存由于是独立部署的进程,拥有自身独立的内存空间,不会受到应用进程重启的影响,在应用进程重启时,分布式缓存的数据依然存在。同时对于数据量而言,由于不需要占用应用进程的内存空间,并且一般支持以集群的方式拓展,故可以进行大数据量的数据缓存。
2. 数据集中存储,保证数据一致性
当应用进程采用集群方式部署时,集群的每个部署节点都通过一个统一的分布式缓存进行数据存取操作,故不存在本地缓存中的数据更新问题,保证了不同节点的应用进程的数据一致性问题。

posted @ 2014-12-10 16:32  南哥的天下  阅读(3155)  评论(0编辑  收藏  举报