惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The GitHub Blog
The GitHub Blog
MyScale Blog
MyScale Blog
爱范儿
爱范儿
GbyAI
GbyAI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
美团技术团队
Y
Y Combinator Blog
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
Martin Fowler
Martin Fowler
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
M
MIT News - Artificial intelligence
博客园 - Franky
V
Visual Studio Blog
I
InfoQ
V
V2EX
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
博客园 - 司徒正美
L
LangChain Blog

博客园 - 瘦鱼

读《下一个倒下的会不会是华为》 读《大明王朝1566》有感 读《骆驼祥子》有感 轻松学-题库 git提交记录合并 个人项目开发规划 eblog镜像的制作 shell脚本的使用 eblog简介 容器化技术的使用和优缺点 爱收藏网站关闭 0.爱收藏——开篇 “爱收藏”网站再次重启 Linux服务器设置虚拟内存 Linux常用命令 3.爱收藏——系统架构 4.爱收藏——首页搜索功能实现 2.爱收藏——需求说明 1.爱收藏——云端收藏夹发布 GIt帮助文档之忽略某些文件——忽略python虚拟环境文件夹(转)
缓存
瘦鱼 · 2023-07-16 · via 博客园 - 瘦鱼

缓存

缓存,是一种减少I/O读写和CPU计算,以提升性能的手段。

缓存的使用

主要用在需要频繁读某些不变动,或者变动较少的数据的场景。一般使用场景是:应用中使用缓存,需要读数据时,先去缓存中查询。缓存中没有的话,再查数据库,查到数据后返回结果,并将结果写到缓存中。

缓存分类

本地缓存

指应用中的缓存,缓存与应用在同一个进程内部,请求快,无网络开销。缺点是多个应用间无法共享。

实现方式:

  • 使用成员变量,或者局部变量
  • 使用静态变量,进程间可共享

一般使用Map实现,考虑多线程安全,则使用ConcurrentHashMap。ID作为key,每次使用id去查缓存。

分布式缓存

缓存是一个独立的应用,多个应用可以共享缓存,可实现持久化。一般使用redis实现

缓存更新问题

如果数据库中的数据有更新,如何更新缓存?

可以采用缓存过期策略,或者定期将数据从数据库中更新到缓存中。

有几种缓存过期策略:

  1. 先进先出。先缓存的数据,先清理。
  2. 最少使用。统计缓存的使用情况,最少使用的数据说明不是热点数据,可以清理掉。
  3. 最近最少使用。最近最少使用的数据,说明数据已经不再是热点数据了,可以清理掉。

满足上述策略的数据会被清理掉,下次访问缓存时再从数据库中读取并更新到缓存中。当然上述策略也是为了释放内存。

另外一种策略是,使用定时任务,在系统负载较低的时候,比如说晚上系统使用人数较少时,从数据库中读取数据,更新到缓存。

如果是应用内的缓存,或者缓存使用并不是很多的情况,并不需要考虑这么复杂的操作。

可以缩小缓存的使用范围,例如缩小到某个方法中,每次请求都清空缓存,再从数据库中读取或者从缓存中读取。这种针对需要在方法中循环处理大量数据,且这批数据中有需要大量读取某个相同值的情况。

例如需要处理一批数据,这批数据中有个字段需要从数据库中获取值,这个字段的值可能相同,不必要处理每条数据时都从数据库中读取,可以每次读取数据后,将值缓存起来,下一条数据先从缓存中读取。

这里定义一个成员变量map作为缓存

private Map<String,String> map;

这个map在什么时候初始化呢?如果在类初始化的时候进行初始化,则存储在map中的数据只有在重启服务后才能清空,重启才能从数据库中获取最新的数据,在此之前读取的数据都是旧。这对数据有变化的情况是不能接受的。

只能在每次处理数据前,初始化map,即是清空map,使得缓存只在这次的请求中生效,这样能保证这次的请求获取的是最新的数据。当然,性能的提升也只是在这次的请求中,下次请求还是先从数据库中读取数据。