高并发系统缓存设计
1 为什么要缓存
1.1 成本&效果
- 不考虑硬件成本(公共组建), 底层存储优化, 算法优化所带来的效果可能远远不如缓存带来的优化效果。
- 缓存操作。又分为缓存写操作和缓存读操作。如写操作频繁切实时性要求不是很高的,可以先缓存起来,定期、批量写。
看一问答:
问:为什么有些对数据实时性,准确性要求极高的系统,不能使用缓存?
答:数据实时性,准确性要求极高的系统 , 举个例子的话,就想到了银行的存取款系统,这系统如果使用读缓存, 用户会疯掉。 因为钱转过来了却需要一段时间以后看到,如果使用写缓存,银行会疯掉,因为多存储的不一致性会让很多数据丢失。所以对于实时性准确性要求极高的系统,无论访问量多大,最多采用排队的异步方式,而不能使用缓存提高效率。[关于缓存上-淘宝]
1.2
穷举不尽。。
2 缓存适用的情景
- 更新频率不高的。 。。。
3 缓存带来的问题
- 可能出现数据不一致。
- 增加系统的复杂度(但换来的性能以及容灾上的改进)。
4 缓存分类
“大型web系统缓存设计-腾讯”
- 分布式缓存。
- 分布式环境下的本地缓存。
5 缓存设计思路
5.1 考虑点
- 命中率。首当其冲。没有命中率,缓存空空增加系统复杂度。
- 占用空间小。考虑过期时间。
- 数据一致性保证。
- 读频繁的数据应该在缓存中。(命中率的问题)
- 缓存粒度。每次缓存中拿到的数据都是所有数据,需要解析出期望字段。见[大型web系统缓存设计-腾讯]。
- 分析系统中变化与变化频率不高的数据
5.1.1 业务缓存
根据业务情景缓存。如只根据某种状态查询,那么 i) 根据查询参数判断这属于同一类查询。 ii) hashcode后判断。
5.2 缓存更新
突然想到个ES实时更新的问题:
由于只对特定状态敏感,所以对更新特定状态的index请求直接index,其余的保持1s。
5.2.1更新策略
- 主动更新。使用定时Job,定期向缓存中刷/更新数据。这种对实时性要求不高的才使用。
- 被动更新。存在改变缓存的接口调用,在调用时,更新缓存。
- 主动+被动更新。这种是在接口调用同时查看缓存是否到了更新时期,实现方法是在缓存的model中内置定时器。实现可以参考:[关于缓存上-淘宝]。
5.2.2更新方法
- 过期。
- 主动更新。
其中主动更新为保证数据丢失和覆盖,一般有以下几种方案: 类似乐观锁和悲观锁。
- 客户端对操作加锁。
- 版本控制。为每份数据保存一个版本号,当缓存数据写入时,需要传入这个版本号,然后服务端将传入的版本号和数据当前的版本号进行比对,如果大于当前版本,则成功写入,否则返回失败;这样解决方式比较简单;但是增加了高并发下客户端的写失败概率;
除此之外,还有多数据源一致性问题,这个不在此次考虑范围
5.3设计策略
以下四点引自“大型网站架构系列之五-缓存策略设计概要]”,非常好。
1) 数据缓存应该被有效的分组并索引
目标是实现数据耦合的成都降到最低,甚至没有耦合。比如以用户ID为分割的数据缓存分布,或者以文章分类为分割的缓存分布
2) 数据缓存应该被有效的更新
如果数据被有效的分 组完成后,这个就是问题C.2的方案了,和C.2不同的是,因为缓存组可能未必在一组服务器中,可能涉及缓存和DATABASE数据通讯延迟的问题。这个 时候要保证缓存服务器被即时的传递到databse,那么需要另外的一个缓存检测进程来完成这项工作(数据完整性检查,并备份两个缓存段的数据)
3) 缓存服务器间的数据完整性)
对于无法分组的数据,比如时间段内的用户认证数据和资料数据,我们需要保证两组数据同步,最好的处理方法就是清除相应的缓存段,让它在下次使用的时候初始化
4) 缓存服务器间的连通性
这个取决于物理线路,如果缓存服务器在天南地北的话,我们还需要一个队列进程来进行同步和数据矫正,我们称之为缓存路由。
5.4 基本编码
- getFromCache
- 1 suc or 1 fail(exception)。
- suc -> return.
- fail的话有两种方式:把请求打到下一层;为了下一层的安全,返回默认值。要看希望怎样做降级。(错误处理策略不同)
还有一种是这样的(多了一步计数规则)(更新缓存策略不同): 当用户查询数据,首先在缓存中寻找,缓存中不存在,则去数据库中查找,并更新数据库的访问时间和访问次数,当访问次数达到缓存要求则将其放进缓存中。
6 业界实践
- ORM缓存。 单表拆为n+1个表。然后缓存n个表,用1个表的查询带动其他n各表的缓存。其中还有一点是“写一致性缓存”,及利用1表的时间戳作为key的一部分,下次查询其他n表的缓存时用1表的时间戳key去查。不但省去了缓存更新的逻辑,还做到了数据一致性。
上面的前提是动态数据和静态数据尽可能的拆开,这样对缓存的设计也有极大的帮助。
7 参考资料
- web应用的缓存设计模式
- 大型web系统缓存设计-腾讯
- 如何使用缓存 其中数据库访问优化法则不错,应该按照这个画一个es的。
- 大型网站架构系列之五-缓存策略设计概要
- 缓存策略-腾讯