缓存设计

缓存,是一种存储数据的组件,它的作用是让对数据的请求更快地返回。实际上,凡是位于速度相差较大的两种硬件之间,用于协调两者数据传输速度差异的结构,均可称之为缓存。

在做缓存设计时,有一些误区要避开:

  1. 把缓存作为服务间传递数据的通道,这个要避免

  2. 使用缓存没有考虑雪崩的情况,这个要考虑

  3. 多服务共享一个缓存实例,这个最好要避免,多个服务之间缓存做垂直拆分

常见缓存的应用场景

缓存和缓冲区的比较

缓存的分类

进程内缓存

缓存可以放在进程外,如redis/memcached,也可以放在进程内,如Guava Cache、加锁的Map、Leveldb等,就叫做进程内缓存(一般是缓存架构设计中的二级缓存或者三级缓存)

进程内缓存可以缓存多种多样的数据类型,如对象、JSON数据、文本数据、HTML等等,它带来的直接好处是不需要再次访问后端存储来获取数据,可以提高查询效率,相较于进程外缓存,一是节省了内部带宽,二是响应延时会更低。

进程内缓存虽然有很多好处(节省带宽、响应延时更低等),但是它更存在一些不可逾越的问题:

服务实例一般是多实例部署的,每个实例都有自己的进程内缓存,怎么保持实时一致性?这样就把状态带进了服务中,违反了分层架构中的服务无状态设计,为水平扩展带来了一些隐患。(服务无状态设计的原则:尽量把数据的状态和存储放在专门的数据存储服务中,实例节点本身只做计算,不把数据状态和某个实例做耦合,这样在水平扩展时才能收放自如)那什么时候适合用进程内缓存呢?

  1. 只读数据。这类数据在整个服务生命周期中不发生变化,就可以预先把数据加载放在内存中

  2. 允许数据短暂不一致的业务场景。比如一些运营页面、某些场景的计数等

所以,进程内缓存要慎用,大部分情况下,进程外缓存基本就可以搞定了;真的要使用进程内缓存时,一定要想好是否需要实时的缓存数据一致性?缓存怎么在多实例之间做更新?业务场景是否允许数据不一致等等,其他可以参考这里

缓存淘汰还是修改

参考:缓存,是淘汰还是修改

结论:通用做法,缓存要选择淘汰,而不是修改;特殊场景,缓存可以修改。

在大部分场景中,缓存修改的代价比缓存淘汰要大的多。

资源

最后更新于