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

写在前面

之前提到过作为典型的空间换时间的优化手段,除了预计算,就是缓存了。在开发工作中缓存恐怕无处不在,无论是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。而当我们读取时,如果缓存中没有数据,则读取数据后再写入缓存。

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

总结

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

相关推荐
Rust研习社2 小时前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
IT_陈寒2 小时前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
CaffeinePro3 小时前
Pydantic深度使用:数据校验、枚举、ORM映射
后端·fastapi
Chenyiax3 小时前
从 Chat 到 Responses:OpenAI API 抽象为什么变了?
后端
MariaH3 小时前
Koa和Express的区别
后端
MariaH3 小时前
Koa框架的使用
后端
luckdewei5 小时前
那个用 passlib 做认证的新同事,上线第一天就把用户密码写进了日志
后端
ping某6 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
JustHappy6 小时前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
uhakadotcom6 小时前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github