缓存是我们用来减少数据库访问的常见操作,里面的一些常见思路及问题这里总结下。下面以redis举例。
使用方式分类:
一,只读缓存。
只读缓存时,会先看redis里有无数据,有则直接返回。没有则走数据库查询一次,将查询到的数据放入redis并给个过期时间,然后将数据返回给前端。对于数据变更来说,直接更新或删除数据库,然后调下redis的删除接口。这样下次请求发现没数据则会从新加载数据。
1,这里删除可能失败,但是失败概率极低。如果要处理的话,想办法重试就可以了。
2,如果并发发现缓存中数据没有,则会将并发请求打到数据库中。这会造成数据库压力。这里可以将数据加载接口加锁,拿到锁后再检查下是否有数据。(缓存击穿场景)
3,如果并发量极大。通过这种被动加载数据方式其实效率不行的。可以考虑主动加载方式。外部请求只到缓存,永远到不的到数据库层。数据的加载与更新都是通过其他任务来执行的。(缓存击穿场景)
二,读写缓存。
读写缓存的意思是不仅读直接到缓存层,写也会直接更新缓存层。一般不用这种方案,除非你对写入性能极其看中。
1,写入redis的操作不是很可靠,存在丢失数据风险,所以考虑同步写入缓存和数据库,等都成功时才叫成功。不过这个方案性能肯定不行,毕竟数据库容易是瓶颈。
2,写入redis后给数据打个标记,其他任务根据标记批量获取存到数据库中。这种方案性能很好,但是数据存在延迟同步的问题,而且数据容易丢失部分,这取决于你同步的频率。
三,缓存分级。
缓存分级其实是对上面使用的延续,将缓存使用在不同地方叫不同级别。比如本地hashMap缓存叫一级缓存,redis叫二级缓存,存放在远程客户端的叫三级缓存。用的地方越多,维护越麻烦,数据同步更是越复杂。不是极端优化,没必要用这么多。
常见问题:
一,缓存雪崩
缓存雪崩的意思是突然缓存没了,导致大量请求到数据库中。
1,比如缓存同时过期,导致用户同时要去查数据库,负载突然拉高。这个问题我生产遇到过。这种问题在设置过期时间时随机下就不会同时过期了。
2,缓存服务挂了,导致请求到达数据库。这种问题要分场景,大并发场景下肯定不能失败时打到数据库中。应该从缓存高可用和降级上考虑。如果小业务下,倒是可以到达数据库。
二,缓存击穿
缓存击穿上面提到过(缓存击穿),一种是加锁处理,一种是直接限制无法穿透到数据库层。
三,缓存穿透
缓存穿透的意思是数据库本来就没有的数据,缓存中肯定也就没有,那么每次查询势必会再次走到数据库层。
1,直接在缓存中保存没查到的值,但是要看业务场景而给一个过期时间,不然就永远曾的不存在了。
2,使用布隆过滤器来判断是否存在。文章来源:https://www.toymoban.com/news/detail-830822.html
四,缓存预热
缓存预热的意思是我们预先知道了哪些数据是热点数据,如果等用户请求来了再加载数据的话,也可能把数据库负载拉起来。那么我们何不预先就先把数据加载到缓存中呢?这就是预热的意思。文章来源地址https://www.toymoban.com/news/detail-830822.html
到了这里,关于缓存使用常见思路及问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!