高并发系统缓存设计

1 为什么要缓存

1.1 成本&效果

看一问答:

问:为什么有些对数据实时性,准确性要求极高的系统,不能使用缓存?
答:数据实时性,准确性要求极高的系统 , 举个例子的话,就想到了银行的存取款系统,这系统如果使用读缓存, 用户会疯掉。 因为钱转过来了却需要一段时间以后看到,如果使用写缓存,银行会疯掉,因为多存储的不一致性会让很多数据丢失。所以对于实时性准确性要求极高的系统,无论访问量多大,最多采用排队的异步方式,而不能使用缓存提高效率。[关于缓存上-淘宝]

1.2

穷举不尽。。

2 缓存适用的情景

3 缓存带来的问题

4 缓存分类

“大型web系统缓存设计-腾讯”

5 缓存设计思路

5.1 考虑点

5.1.1 业务缓存

根据业务情景缓存。如只根据某种状态查询,那么 i) 根据查询参数判断这属于同一类查询。 ii) hashcode后判断。

5.2 缓存更新

突然想到个ES实时更新的问题:

由于只对特定状态敏感,所以对更新特定状态的index请求直接index,其余的保持1s。

5.2.1更新策略

5.2.2更新方法

其中主动更新为保证数据丢失和覆盖,一般有以下几种方案: 类似乐观锁和悲观锁。

除此之外,还有多数据源一致性问题,这个不在此次考虑范围

5.3设计策略

以下四点引自“大型网站架构系列之五-缓存策略设计概要]”,非常好。

1) 数据缓存应该被有效的分组并索引
目标是实现数据耦合的成都降到最低,甚至没有耦合。比如以用户ID为分割的数据缓存分布,或者以文章分类为分割的缓存分布
2) 数据缓存应该被有效的更新
如果数据被有效的分 组完成后,这个就是问题C.2的方案了,和C.2不同的是,因为缓存组可能未必在一组服务器中,可能涉及缓存和DATABASE数据通讯延迟的问题。这个 时候要保证缓存服务器被即时的传递到databse,那么需要另外的一个缓存检测进程来完成这项工作(数据完整性检查,并备份两个缓存段的数据)
3) 缓存服务器间的数据完整性)
对于无法分组的数据,比如时间段内的用户认证数据和资料数据,我们需要保证两组数据同步,最好的处理方法就是清除相应的缓存段,让它在下次使用的时候初始化
4) 缓存服务器间的连通性
这个取决于物理线路,如果缓存服务器在天南地北的话,我们还需要一个队列进程来进行同步和数据矫正,我们称之为缓存路由。

5.4 基本编码

  1. getFromCache
  2. 1 suc or 1 fail(exception)。
  3. suc -> return.
  4. fail的话有两种方式:把请求打到下一层;为了下一层的安全,返回默认值。要看希望怎样做降级。(错误处理策略不同)

还有一种是这样的(多了一步计数规则)(更新缓存策略不同): 当用户查询数据,首先在缓存中寻找,缓存中不存在,则去数据库中查找,并更新数据库的访问时间和访问次数,当访问次数达到缓存要求则将其放进缓存中。

6 业界实践

  1. ORM缓存。 单表拆为n+1个表。然后缓存n个表,用1个表的查询带动其他n各表的缓存。其中还有一点是“写一致性缓存”,及利用1表的时间戳作为key的一部分,下次查询其他n表的缓存时用1表的时间戳key去查。不但省去了缓存更新的逻辑,还做到了数据一致性。

上面的前提是动态数据和静态数据尽可能的拆开,这样对缓存的设计也有极大的帮助。

7 参考资料