性能优化利器——缓存(附三种常见缓存设计)

写在前面

之前提到过作为典型的空间换时间的优化手段,除了预计算,就是缓存了。在开发工作中缓存恐怕无处不在,无论是Redis与Mysql的配合,或者是一个全局的MAP,哪怕是小小的CPU,也有不同等级的cache。缓存不同于预计算这种基于业务场景的一视同仁,而是充分的利用了空间局部性远离,每一次缓存命中,都是计算机的浪漫

缓存带来的提升

1、加快数据访问速度;

2、减轻后端应用和数据存储的负载压力。

缓存需要考虑的问题

引用下Phil Karlton大神的经典语录:

计算机科学中只有两件困难的事情:缓存失效和命名规范。

There are only two hard things in Computer Science: cache invalidation and naming things.

在数据更新的过程中,引入了缓存的系统不得不需要更改两个地方的数据,因此必然会不一致。根据业务的需要,如何更好的利用缓存的特性与尽可能避免不一致带来的问题,是缓存设计的唯一标准

缓存常见应用

高一致性设计

为了尽可能的保证高一致性,在写数据时,更新数据库的同时删除对应的缓存,这样在有读请求时,就会因为缓存miss而去数据库中读,防止出现不一致的问题

可能会有人问:写数据库和删除cache之间也是两个操作,是否会有不一致的可能呢?一般来说不一致指的是数据库和缓存不一致,所以只要我们先删除缓存后更新DB就能保证一致性。

高频写入场景

高频写场景如果也像上面一样,先删除cache再更新DB的话,性能就会受到影响,为了尽可能提高写入性能,我们可以在写时先更新缓存,并异步的修改DB中的数据。而在读取数据时,也优先读取缓存,如果缓存miss,则从数据库中读取数据后,再写入缓存。

冷热分区

相同的存储大小,缓存的价格一般大于磁盘的价格,因此使用缓存时我们必然希望可以尽可能提高缓存的命中率,而不是将所有数据都放入缓存(当数据比较大时,如果数据只有10M,自然也就无所谓了)。

因此我们会将数据进行冷热分区,当写入数据时,如果数据本身在缓存中,则都更新,如果数据不再缓存中,则只更新DB。而当我们读取时,如果缓存中没有数据,则读取数据后再写入缓存。

在读的部分和上面的很像,本质上都是利用空间局部性原理。

总结

其实缓存设计不只这几种,只不过其他的设计并没有围绕缓存的优势来做文章,因此不在本文中赘述。

相关推荐
鼠鼠我捏,要死了捏1 小时前
基于Spring WebFlux的高并发响应式系统性能优化实践指南
性能优化·reactive·spring webflux
paopaokaka_luck2 小时前
基于Spring Boot+Vue的吉他社团系统设计和实现(协同过滤算法)
java·vue.js·spring boot·后端·spring
Flobby5292 小时前
Go语言新手村:轻松理解变量、常量和枚举用法
开发语言·后端·golang
Warren983 小时前
Java Stream流的使用
java·开发语言·windows·spring boot·后端·python·硬件工程
程序视点4 小时前
IObit Uninstaller Pro专业卸载,免激活版本,卸载清理注册表,彻底告别软件残留
前端·windows·后端
xidianhuihui4 小时前
go install报错: should be v0 or v1, not v2问题解决
开发语言·后端·golang
十盒半价5 小时前
React 性能优化秘籍:从渲染顺序到组件粒度
react.js·性能优化·trae
进击的铁甲小宝6 小时前
Django-environ 入门教程
后端·python·django·django-environ
掘金码甲哥6 小时前
Go动态感知资源变更的技术实践,你指定用过!
后端
王柏龙7 小时前
ASP.NET Core MVC中taghelper的ModelExpression详解
后端·asp.net·mvc