问题来源
项目中为了加快响应时间以及减轻数据库压力,使用了redis
缓存,同时缓存设置了过期时间(1天)
|
|
为什么要用缓存
一般数据都存放在关系型数据库中,以常用的MySQL数据库为例,正常情况下响应时间在10ms以内甚至更短;但是当数据上亿条,任何一款关系型数据库的响应时间都不可能控制在10ms以内
同时高并发情况下,比如同时来1万次请求,MySQL单库TPS(每秒事务量)大概只有1500左右,其它的请求只能处于等待状态,严重情况下数据库崩溃
使用缓存的场景
对于缓存来说,数据变更少且查询比较频繁是最好的场景,如果查询量不够大或者数据变动太频繁,缓存也就是失去了意义。
缓存类型
本地缓存
有些数据量不常变化,但是访问十分频繁,例如省、市地区数据。针对这种场景,可以将数据加载到应用的内存中,以提升系统的访问效率,减少数据库访问同时加快响应时间。
- Guava Cache
比较常见的本地缓存有Guava Cache
,使用方式如下:
|
|
- 本地缓存的缺点
- 数据保存在当前
JVM
中,无法共享 - 重启应用缓存丢失
- 数据保存在当前
分布式缓存
提到分布式缓存基本上都会说到 Redis
,Redis
使用内存作为存储,所以性能上要比数据库要好很多,再加上Redis
还支持很多种数据结构,使用起来比较方便;但是,Redis
需要通过网络来访问,所以网络的性能决定了 Reids
的瓶颈
缓存更新策略
更多策略见缓存更新的套路,这里具体分析喜马拉雅的缓存更新策略:先更新数据库,再失效缓存
Cache Aside Pattern
|
|
这种策略也会产生问题,比如:
|
|
但是,这种情况出现的概率非常低。这个场景需要发生在读缓存时缓存失效,并发着有一个写操作。而实际上数据库的写操作比读操作慢得多,而且还要锁表,而读操作需要在写操作之前进入数据库操作,又要在写操作完成后更新缓存,所有的这些条件都具备的概率并不大。所以,Cache Aside Pattern 还是相对靠谱的方式。