【本地缓存篇】如何实现本地缓存?

在这里插入图片描述

如何实现本地缓存?

  • ✔️典型解析
    • ✔️数据结构
    • ✔️线程安全
    • ✔️对象上限
    • ✔️清除策略
    • ✔️过期时间
  • ✔️扩展知识仓
    • 基于Caffeine实现本地缓存


✔️典型解析


所谓本地缓存,就是和应用服务器在一起的缓存工具,将需要缓存的数据放到本地缓存中,可以大大的提升访问速度。


在设计本地缓存时,一般需要考虑以下几个方面的问题:


✔️数据结构


一般来讲,为了提升缓存的效率,通常采用Key-Value结构进行数据存储,也就是说,缓存中的数据保存和读取都需要有一个Key,通过Key来读取固定的缓存的Value。

✔️线程安全


本地缓存一定要考虑线程安全的问题,因为大多数情况下本地缓存都是一个全局可访问的变量,那么就会有多个线程同时访问,所以线程安全问题不容忽视。


✔️对象上限


因为是本地缓存,而本地内存中的数据是要占用JVM的堆内存的,所以内存是有上限要求的,如果无限存储,最终一定会导致OOM的问题。


✔️清除策略


为了避免OOM的问题,一般会考虑在缓存中增加清除策略,通过一定的手段定期的清理掉一些数据,来保证内存占用不会过大,常见清除策略主要有有LRU(最近最少使用)、FIFO(先进先出)、LFU(最近最不常用)、SOFT(软用)、WEAK(弱用)等;


✔️过期时间


有了清除策略并不能保证百分百的可以删除数据,极端情况会会使得某些数据一直无法删除。这时候就需要有一种机制能够保证某些K-V一定可以删除。通常采用的方案是给每一个缓存的kev设置过期时间,当达到过期时间之后直接删除,采用清除策略+过期时间双重保证;


考虑到以上这些问题之后,就可以考虑如何具体实现一个本地缓存了。


最简单的方式是通过HashMap来实现一个本地缓存,因为他本身就是一种Key-Value结构的,并且如果使用ConcurrentHashMap的话,也能保证线程安全,不过需要自己实现对象上限、过期策略以及清除策略。


除此之外,也有一些比较成熟的开源的本地缓存框架可以直接使用,比较常用的有:


  • Guava Cache
  • Caffeine (推荐)
  • Encache

推荐优先使用Caffeine作为本地缓存,在功能上,GuavaCache支持的功能,Caffeine都支持,另外Caffeine支持异步Cache和写入外部资源,这两个Guava Cache是不支持的。Caffeine也是Spring 5中默认支持的Cache。而Caffeine在性能上要比GuavaCache好很多,主要有以下几个原因:


1 . 剔除算法,GuavaCache采用的是 [LRU] 算法,而Caffeine采用的是[Window TinyLFU] 算法,这是两者之间最大,也是根本的区别。


2 . 立即失效,Guava会把立即失效(例如: expireAfterAccess(0) and expireAfterWrite(0)) 转成设置最大Size为0。这就会导致剔除提醒的原因是SIZE而不是EXPIRED。Caffiene能正确识别这种剔除原因。


3 . 取代提醒,Guava只要数据被替换,不管什么原因,都会触发剔除监听器。而Cafiene在取代值和先前值的引用完全一样时不会触发监听器。


4 . 异步化,Caffiene的很多工作都是交给线程池去做的(默认: ForkJoinPool.commonPool()),例如: 剔除监听器,刷新机制,维护工作等


回顾博文: 【本地缓存篇】LFU、LRU 等缓存失效算法


✔️扩展知识仓


基于Caffeine实现本地缓存


import com.github .benmanes .caffeine.cache.Cache;
import com.github.benmanes .caffeine.cache.Caffeine;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;/**
*    本地缓存工具
*     @author wwwwwwwwwwwwwwwwwwww
*/
@Component
public class LocalCacheManager implements InitializingBean {private Cache<String,String> localCache;/***    向缓存中保存数据,如果已经存在则不覆盖*/public void putIfNotExist(String key,String value)  {if (localCache.getIfPresent(key) == null)  {localCache.put(key, value);}}/****     根据key获取缓存数据*     @param key*/public String get(String key)  {return localCache.getIfPresent(key);}public void del(string key) {localCache.invalidate(key);}/***    在bean初始化时,初始化本地缓存*/@Overridepublic void afterPropertiesSet() {localCache = Caffeine.newBuilder().expireAfterWrite(10TimeUnit.SECONDS).expireAfterAccess(10TimeUnit.SECONDS).maximumsize(1000).build();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2659567.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

YOLOv5-Lite 树莓派4B 15帧教程

【前言】 由于v5Lite仓库遗漏了不少历史问题&#xff0c;最大的问题是毕业后卷起来了&#xff0c;找不到时间更新。 上面是这篇博客的背景&#xff0c;那么先说下结论&#xff0c;使用 v5lite-e 模型&#xff0c;在 树莓派4B&#xff08;4G内存&#xff09; 上&#xff0c;有三…

Unity 爱心血量效果

这里写自定义目录标题 1.准备爱心血条2.HeartUI 代码3.在Inspector窗口中绑定好对象4.在血量减少的地方&#xff0c;调用更新方法5.效果展示 1.准备爱心血条 准备好红色爱心和灰色爱心的图片 2.HeartUI 代码 using System.Collections; using System.Collections.Generic; u…

【AI】计算机视觉VIT文章(Transformer)源码解析

论文&#xff1a;Dosovitskiy A, Beyer L, Kolesnikov A, et al. An image is worth 16x16 words: Transformers for image recognition at scale[J]. arXiv preprint arXiv:2010.11929, 2020 源码的Pytorch版&#xff1a;https://github.com/lucidrains/vit-pytorch 0.前言 …

Erlang、RabbitMQ下载与安装教程(windows超详细)

目录 安装Erlang 1.首先安装RabbitMQ需要安装Erlang环境 2.点击下载好的.exe文件进行傻瓜式安装,一直next即可 3.配置Erlang环境变量 安装RabbitMQ 1.给出RabbitMQ官网下载址&#xff1a;Installing on Windows — RabbitMQ&#xff0c;找到 2.配置RabbitMQ环境变量&#xff0…

软件测试/测试开发丨Pytest学习笔记

Pytest 格式要求 文件: 以 test_ 开头或以 _test 结尾类: 以 Test 开头方法/函数: 以 _test 开头测试类中不可以添加构造函数, 若添加构造函数将导致Pytest无法识别类下的测试方法 断言 与Unittest不同, 在Pytest中我们需要使用python自带的 assert 关键字进行断言 assert…

【强化学习】基于蒙特卡洛MC与时序差分TD的简易21点游戏应用

1. 本文将强化学习方法&#xff08;MC、Sarsa、Q learning&#xff09;应用于“S21点的简单纸牌游戏”。 类似于Sutton和Barto的21点游戏示例&#xff0c;但请注意&#xff0c;纸牌游戏的规则是不同且非标准的。 2. 为方便描述&#xff0c;过程使用代码截图&#xff0c;文末附链…

【k8s源码分析-Apiserver-2】kube-apiserver 结构概览以及主体部分源码分析

参考 Kubernetes 源码剖析&#xff08;书籍&#xff09;kube-apiserver的设计与实现 - 自记小屋 kube-apiserver 核心思想 APIGroupInfo 记录 GVK 与 Storage 的对应关系 将 GVK 转换成&#xff0c;Restful HTTP Path将 Storage 封装成 HTTP Handler将上面两个形成映射&#…

CSP CCF 201409-2 画图 C++满分题解

解题思路&#xff1a; 1.使用二维数组标记每一个方块是否被涂色。 2.注意坐标代表的是点&#xff0c;不是方块&#xff0c;交界处的坐标只能算一个方块。 3.可以看成&#xff1a;每一个坐标都对应它左上角的一个小方块&#xff0c;这样可以避免重复计算方块数 #include<i…

3 个月前被裁员了,心情跌落谷底,直到我看到了这本神书…

3个月前的某一天&#xff0c;正在愉快的打工&#xff0c;突然被喊去谈话&#xff0c;然后就被辞退了。。 加入了找工作的大军 然而&#xff0c;因为疫情&#xff0c;因为大专学历的我&#xff0c;找工作比以往都艰难了许多 很多&#xff0c;纯粹就是因为学历&#xff0c;都不…

第十三届蓝桥杯大赛青少年国赛C++组编程题真题(2022年)

第十三届蓝桥杯大赛青少年国赛C组编程题真题&#xff08;2022年&#xff09; 编程题第 1 题 问答题 电线上的小鸟 题目描述&#xff1a; 在一根电线上落有N只小鸟&#xff0c;有的小鸟头向左看&#xff0c;有的小鸟头向右看&#xff0c;且每只小鸟只能看到它视线前的那一只小…

Java之ThreadLocal 详解

ThreadLocal 详解 原文地址&#xff1a;https://juejin.cn/post/6844904151567040519open in new window。 什么是ThreadLocal&#xff1f; ThreadLocal提供线程局部变量。这些变量与正常的变量不同&#xff0c;因为每一个线程在访问ThreadLocal实例的时候&#xff08;通过其…

机器学习之人工神经网络(Artificial Neural Networks,ANN)

人工神经网络(Artificial Neural Networks,ANN)是机器学习中的一种模型,灵感来源于人脑的神经网络结构。它由神经元(或称为节点)构成的层级结构组成,每个神经元接收输入并生成输出,这些输入和输出通过权重进行连接。 人工神经网络(ANN)是一种模仿生物神经系统构建的…

电气产品外壳常用材质PA、PC、PBT、ABS究竟是什么?

在如今工业制造领域&#xff0c;各种改性塑料、复合材料以及轻质合金材料的运用日趋成熟。在电气领域&#xff0c;不同电气产品的外壳、组件材质采用不同材料&#xff0c;以同为科技&#xff08;TOWE&#xff09;电气产品为例&#xff0c;工业连接器系列产品采用PA6外壳材质、机…

软件测试/测试开发丨Python常用数据结构学习笔记

Python常用数据结构 list 列表 列表定义 列表是有序的可变元素的集合&#xff0c;使用中括号[]包围&#xff0c;元素之间用逗号分隔列表是动态的&#xff0c;可以随时扩展和收缩列表是异构的&#xff0c;可以同时存放不同类型的对象列表中允许出现重复元素 列表使用&#x…

鸿蒙 DevEco Studio 3.1 入门指南

本文主要记录开发者入门&#xff0c;从软件安装到项目运行&#xff0c;以及后续的学习 1&#xff0c;配置开发环境 1.1 下载安装包 1.2 下载SDK及工具链 1.3 诊断开发环境 1.4 配置环境变量 配置HDC工具环境变量 配置Node环境变量 2.创建和运行 2.1 新建项目 2.2 页面…

掌握激活函数(一):深度学习的成功之源

文章目录 引言基本概念常用激活函数举例Sigmoid激活函数公式Sigmoid函数的数学特性示例基于NumPy和PyTorch实现Sigmoid函数将Sigmoid函数应用于二分类任务 Sigmoid激活函数的局限性举例 ReLU激活函数公式ReLU函数的数学特性ReLU函数的特点示例基于NumPy和PyTorch实现ReLU函数搭…

虚析构和纯虚析构

多态使用时&#xff0c;如果子类中有属性开辟到堆区&#xff0c;那么父类的指针在释放时无法调用到子类的析构代码 解决方式&#xff1a;将父类中的析构代码函数改为虚析构或者纯虚析构 虚析构和纯虚析构共性&#xff1a; 可以解决父类指针释放子类对象 都需要有具体的函数…

vu3-14

第一个需求是在用户登录成功之后&#xff0c;在主页显示用户的真实姓名和性别&#xff0c;这些信息要调用后端API获取数据库里面的信息&#xff0c;第二个需求是点击菜单1&#xff0c;在表单中修改用户信息之后&#xff0c;更新到后端数据库&#xff0c;然后在主页同步更新用户…

软件测试/测试开发丨接口测试学习笔记分享

一、Mock 测试 1、Mock 测试的场景 前后端数据交互第三方系统数据交互硬件设备解耦 2、Mock 测试的价值与意义 不依赖第三方数据节省工作量节省联调 3、Mock 核心要素 匹配规则&#xff1a;mock的接口&#xff0c;改哪些接口&#xff0c;接口哪里的数据模拟响应 4、mock实…

【基础篇】六、自定义类加载器打破双亲委派机制

文章目录 1、ClassLoader抽象类的方法源码2、打破双亲委派机制&#xff1a;自定义类加载器重写loadclass方法3、自定义类加载器默认的父类加载器4、两个自定义类加载器加载相同限定名的类&#xff0c;不会冲突吗&#xff1f;5、一点思考 1、ClassLoader抽象类的方法源码 ClassL…