缓存设计
互联网服务中,缓存是提高系统性能的重要手段。缓存的设计需要考虑的因素很多,包括缓存的类型、缓存的位置、缓存的更新策略、缓存的一致性等等。本文将从这些方面来介绍缓存的设计。
缓存
缓存,是一种存储数据的组件,它的作用是让对数据的请求更快地返回。实际上,凡是位于速度相差较大的两种硬件之间,用于协调两者数据传输速度差异的结构,均可称之为缓存。
技术为业务服务,缓存也不例外;在业务系统中,主要会用到以下几种缓存:
- 本地缓存 (aka 进程内缓存)
- 分布式缓存
- 类似于 CDN 的静态数据缓存
进程内缓存
一般也叫 Local Cache
, 是指缓存在应用进程内部的缓存,比如 Java 中的 HashMap
、ConcurrentHashMap
等。这种缓存的特点是速度快,但是缓存的数据量有限,一般只能缓存一些热点数据;此外,这类缓存会引入多实例下数据短暂不一致的问题,所以在使用的时候要格外小心。
经常使用的 Local cache
有:Google Guava Cache
、Caffeine
、ConcurrentHashMap
、Ehcache
等。目前 Caffeine
是性能最好的 Local Cache
。此外,leveldb
也是一种本地缓存的实现,但是它是基于磁盘的,所以性能不如上面几种。
什么时候需要用本地缓存?什么场景不适合用?
举几个场景
- 黑名单用户 ID / 白名单用户 ID;这种数据量不大,但是访问频率很高,所以可以用本地缓存,在启动时加载,运行过程中随着 Admin 的添加或者删除而更新
- 用户 ID 和 用户名、头像、昵称等的对应关系,由于某些原因我们一般指存储用户的 ID,当需要用户的其他信息时就需要从数据库中查询这些数据回来,如果每次都从 DB 中获取,显然对 DB 的压力很大,并且每次访问 DB 不是很有必要
- 分布式配置中心,为了降低业务服务对配置中心的压力,一般都是将数据缓存在本地,当有新的配置发布后,会通知业务服务中配置中心的 client,然后拉取新的配置,或者推送新的配置
总结一下
- 数据读多写少且对一致性要求不高的场景;如果一致性要求非常高,需要考虑使用分布式缓存,并且还要考虑数据库与分布式缓存的一致性问题
- 对性能要求极其严苛的场景,比如秒杀、抢购等
- 只读数据的场景
- 分布式缓存的普适性更强一些,很多场景都可以用分布式缓存来解决,如非必要,不建议使用本地缓存 (也就是说用了也要慎重)
优势是什么?劣势是什么?
Local Cache
和应用服务处于同一个进程内,且存储在内存中,一个字:快;无论对于 RT、QPS 还是吞吐量,都有极大增益。此外,也节省了内网带宽。
依据服务无状态设计的原则:尽量把数据的状态和存储放在专门的数据存储服务中,实例节点本身只做计算,不把数据状态和某个实例做耦合,这样在水平扩展时才能收放自如。本地缓存其实在一定程度上引入了状态,所以一个最需要关心的问题就是数据一致性,这一点有别于分布式缓存。
- 本地缓存:每个实例都有一份缓存,需要协调数据一致性问题
- 分布式缓存:缓存数据集中存放在独立的缓存服务中,每个实例是不存在缓存数据的,但是需要考虑缓存和 SOR (Source of Record) 的一致性问题
目前有哪些本地缓存的实现方案,各自的优缺点?
- 编程语言的内置数据结构,比如 Java 中的
HashMap
、ConcurrentHashMap
等 - Google guava
- Caffeine
- Encache
- Leveldb / Rocksdb
本地缓存关注的技术点是什么?
- 缓存命中率
- 缓存容量
- 缓存淘汰策略
- 缓存一致性
分布式缓存
TODO
缓存规范
- JSR107
- Spring Cache
缓存实践
缓存可以应对高并发大流量的场景。
在做缓存设计时,有一些误区要避开:
- 把缓存作为服务间传递数据的通道,这个要避免
- 使用缓存没有考虑雪崩的情况,这个要考虑
- 多服务共享一个缓存实例,这个最好要避免,多个服务之间缓存做垂直拆分
找几个例子分析一下
References
Frameworks
https://bbs.huaweicloud.com/blogs/365239 https://mp.weixin.qq.com/s/36kVm4pfiy2vQEMToZ9--g https://cloud.tencent.com/developer/article/1546995 https://juejin.cn/post/6844903961078530062 https://mp.weixin.qq.com/s/YBpOz1dQ0sG15vGL7N0PeQ https://shniu.gitbook.io/cs/middleware/redis https://shniu.gitbook.io/cs/system-design/backend-store/cache-design https://tech.meituan.com/2017/03/17/cache-about.html http://highscalability.com/blog/2016/1/25/design-of-a-modern-cache.html https://juejin.cn/post/7151937376578142216 https://juejin.cn/column/7140852038258147358