当前位置: 首页 > news >正文

Redis与本地缓存组合使用(IT枫斗者)

Redis与本地缓存组合使用

前言

  • 我们开发中经常用到Redis作为缓存,将高频数据放在Redis中能够提高业务性能,降低MySQL等关系型数据库压力,甚至一些系统使用Redis进行数据持久化,Redis松散的文档结构非常适合业务系统开发,在精确查询,数据统计业务有着很大的优势。
  • 但是高频数据流处理系统中,Redis的压力也会很大,同时I/0开销才是耗时的主要原因,这时候为了降低Redis读写压力我们可以用到本地缓存,Guava为我们提供了优秀的本地缓存API,包含了过期策略等等,编码难度低,个人非常推荐。

设计示例

Redis懒加载缓存

  • 数据在新增到MySQL不进行缓存,在精确查找进行缓存,做到查询即缓存,不查询不缓存

流程图

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5mEXNQao-1680694576550)(C:%5CUsers%5Cquyanliang%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1680694359553.png)]

代码示例

  • // 伪代码示例 Xx代表你的的业务对象 如User Goods等等
    public class XxLazyCache {@Autowiredprivate RedisTemplate<String, Xx> redisTemplate;@Autowiredprivate XxService xxService;// 你的业务service/*** 查询 通过查询缓存是否存在驱动缓存加载 建议在前置业务保证id对应数据是绝对存在于数据库中的*/public Xx getXx(int id) {// 1.查询缓存里面有没有数据Xx xxCache = getXxFromCache(id);if(xxCache != null) {return xxCache;// 卫语句使代码更有利于阅读}// 2.查询数据库获取数据 我们假定到业务这一步,传过来的id都在数据库中有对应数据Xx xx = xxService.getXxById(id);// 3.设置缓存、这一步相当于Redis缓存懒加载,下次再查询此id,则会走缓存setXxFromCache(xx);return xx;}}/*** 对xx数据进行修改或者删除操作 操作数据库成功后 删除缓存* 删除请求 - 删除数据库数据 删除缓存* 修改请求 - 更新数据库数据 删除缓存 下次在查询时候就会从数据库拉取新的数据到缓存中*/public void deleteXxFromCache(long id) {String key = "Xx:" + xx.getId();redisTemplate.delete(key);}private void setXxFromCache(Xx xx) {String key = "Xx:" + xx.getId();redisTemplate.opsForValue().set(key, xx);}private Xx getXxFromCache(int id) {// 通过缓存前缀拼装唯一主键作为缓存Key 如Xxx信息 就是Xxx:idString key = "Xx:" + id;return redisTemplate.opsForValue().get(key);}}
    // 业务类
    public class XxServie {@Autowiredprivate XxLazyCache xxLazyCache;// 查询数据库public Xx getXxById(long id) {// 省略实现return xx;}public void updateXx(Xx xx) {// 更新MySQL数据 省略// 删除缓存xxLazyCache.deleteXxFromCache(xx.getId());}public void deleteXx(long id) {// 删除MySQL数据 省略// 删除缓存xxLazyCache.deleteXxFromCache(xx.getId());}
    }
    // 实体类
    @Data
    public class Xx {// 业务主键private Long id;// ...省略
    }
    

优点

  • 保证最小的缓存量满足精确查询业务,避免冷数据占用宝贵的内存空间
  • 对增删改查业务入侵小、删除即同步
  • 可插拔,对于老系统升级,历史数据无需在启动时初始化缓存

缺点

  • 数据量需可控,在无限增长业务场景不适用
  • 在微服务场景不利于全局缓存应用

总结

  • 空间最小化
  • 满足精确查询场景
  • 总数据量可控推荐使用
  • 微服务场景不适用

Redis结合本地缓存

  • 微服务场景下,多个微服务使用一个大缓存,流数据业务下,高频读取缓存对Redis压力很大,我们使用本地缓存结合Redis缓存使用,降低Redis压力,同时本地缓存没有连接开销,性能更优。

流程图

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ae9czJqv-1680694576551)(C:%5CUsers%5Cquyanliang%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1680694466289.png)]

业务场景

  • 在流处数处理过程中,微服务对多个设备上传的数据进行处理,每个设备有一个code,流数据的频率高,在消息队列发送过程中使用分区发送,我们需要为设备code生成对应的自增号,用自增号对kafka中topic分区数进行取模,这样如果有10000台设备,自增号就是0~9999,在取模后就进行分区发送就可以做到每个分区均匀分布。
  • 这个自增号我们使用redis的自增数生成,生成后放到redis的hash结构进行缓存,每次来一个设备,我们就去这个hash缓存中取,没有取到就使用自增数生成一个,然后放到redis的hash缓存中,这时候每个设备的自增数一经生成是不会再发生改变的,我们就想到使用本地缓存进行优化,避免高频的调用redis去获取,降低redis压力。

代码示例

  • /*** 此缓存演示如何结合redis自增数 hash 本地缓存使用进行设备自增数的生成、缓存、本地缓存* 本地缓存使用Guava Cache*/
    public class DeviceIncCache {/*** 本地缓存*/private Cache<String, Integer> localCache = CacheBuilder.newBuilder().concurrencyLevel(16) // 并发级别.initialCapacity(1000) // 初始容量.maximumSize(10000) // 缓存最大长度.expireAfterAccess(1, TimeUnit.HOURS) // 缓存1小时没被使用就过期.build();@Autowiredprivate RedisTemplate<String, Integer> redisTemplate;/*** redis自增数缓存的key*/private static final String DEVICE_INC_COUNT = "device_inc_count";/*** redis设备编码对应自增数的hash缓存key*/private static final String DEVICE_INC_VALUE = "device_inc_value";/*** 获取设备自增数*/public int getInc(String deviceCode){// 1.从本地缓存获取Integer inc = localCache.get(deviceCode);if(inc != null) {return inc;}// 2.本地缓存未命中,从redis的hash缓存获取inc = (Integer)redisTemplate.opsForHash().get(DEVICE_INC_VALUE, deviceCode);// 3. redis的hash缓存中没有,说明是新设备,先为设备生成一个自增号if(inc == null) {inc = redisTemplate.opsForValue().increment(DEVICE_INC_COUNT).intValue;// 添加到redis hash缓存redisTemplate.opsForHash().put(DEVICE_INC_VALUE, deviceCode, inc);}// 4.添加到本地缓存localCache.put(deviceCode, inc);// 4.返回自增数return inc;}}
    

优点

  • redis保证数据可持久,本地缓存保证超高的读取性能,微服务共用redis大缓存的场景能有效降低redis压力
  • guava作为本地缓存,提供了丰富的api,过期策略,最大容量,保证服务内存可控,冷数据不会长期占据内存空间
  • 服务重启导致的本地缓存清空不会影响业务进行
  • 微服务及分布式场景使用,分布式情况下每个服务实例只会缓存自己接入的那一部分设备的自增号,本地内存空间最优
  • 在示例业务中,自增数满足了分布区发送的均匀分布需求,也可以满足统计设备接入数目的业务场景,一举两得

缺点

  • 增加编码复杂度,不直接
  • 只适用于缓存内容只增不改的场景

总结

  • 本地缓存空间可控,过期策略优
  • 适用于微服务及分布式场景
  • 缓存内容不能发生改变
  • 性能优

相关文章:

Redis与本地缓存组合使用(IT枫斗者)

Redis与本地缓存组合使用 前言 我们开发中经常用到Redis作为缓存&#xff0c;将高频数据放在Redis中能够提高业务性能&#xff0c;降低MySQL等关系型数据库压力&#xff0c;甚至一些系统使用Redis进行数据持久化&#xff0c;Redis松散的文档结构非常适合业务系统开发&#xf…...

手把手教你学习IEC104协议和编程实现 十 故障事件与复位进程

故障事件 目的 在IEC104普遍应用之前,据我了解多个协议,再综合自动化协议中,有这么一个概念叫“事故追忆”,意思是当变电站出现事故的时候,不但要记录事故的时间,还需记录事故前后模拟量的数据,从而能从一定程度上分析事故产生的原因,这个模拟量就是和今天讲解的故障…...

浅析分布式理论的CAP

大家好&#xff0c;我是易安&#xff01; 今天让我们来聚焦于分布式系统架构中的重要理论——CAP理论。在分布式系统中&#xff0c;可用性和数据一致性是两个至关重要的因素&#xff0c;而CAP理论就是在这两者之间提供了一种权衡的原则&#xff0c;帮助我们在设计分布式系统时进…...

使用 TensorFlow 构建机器学习项目:6~10

原文&#xff1a;Building Machine Learning Projects with TensorFlow 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#x…...

使用 LXCFS 文件系统实现容器资源可见性

使用 LXCFS 文件系统实现容器资源可见性一、基本介绍二、LXCFS 安装与使用1.安装 LXCFS 文件系统2.基于 Docker 实现容器资源可见性3.基于 Kubernetes 实现容器资源可见性前言&#xff1a;Linux 利用 Cgroup 实现了对容器资源的限制&#xff0c;但是当在容器内运行 top 命令时就…...

SQL LIMIT

SQL LIMIT SQL LIMIT子句简介 要检索查询返回的行的一部分&#xff0c;请使用LIMIT和OFFSET子句。 以下说明了这些子句的语法&#xff1a; SELECT column_list FROMtable1 ORDER BY column_list LIMIT row_count OFFSET offset;在这个语法中&#xff0c; row_count确定将返…...

OpenCV实战之人脸美颜美型(六)——磨皮

1.需求分析 有个词叫做“肤若凝脂”,直译为皮肤像凝固的油脂,形容皮肤洁白且光润,这是对美女的一种通用评价。实际生活中我们的皮肤多少会有一些毛孔、斑点等表现,在观感上与上述的“光润感”相反,因此磨皮也成为美颜算法中的一项基础且重要的功能。让皮肤变得更加光润,就…...

Java技术栈—重装系统后不重新安装也能正常使用的设置方式

声明&#xff1a; 最近在重装电脑&#xff0c;重装完后&#xff0c;开发工具会有些功能使用不了&#xff0c;在这做个记录&#xff01;这里是 JAVA 技术栈 问题描述&#xff1a; git 右键无菜单 111 git git 右键无菜单 参考文章&#xff1a;注册表修复git右键无菜单 git …...

智驾升级!ADB+AFS「起势」

目前&#xff0c;乘用车前大灯已经完成从传统卤素、氙气到LED的转型升级&#xff0c;高工智能汽车研究院监测数据显示&#xff0c;2022年中国市场&#xff08;不含进出口&#xff09;乘用车前装标配LED前大灯搭载率达到75.99%&#xff0c;同比2021年提高约7个百分点。 而相比而…...

算法记录 | Day27 回溯算法

39.组合总和 思路&#xff1a; 1.确定回溯函数参数&#xff1a;定义全局遍历存放res集合和单个path&#xff0c;还需要 candidates数组 targetSum&#xff08;int&#xff09;目标和。 startIndex&#xff08;int&#xff09;为下一层for循环搜索的起始位置。 2.终止条件…...

性能测试总结-根据工作经验总结还比较全面

性能测试总结性能测试理论性能测试的策略基准测试负载测试稳定性测试压力测试并发测试性能测试的指标响应时间并发数吞吐量资源指标性能测试流程性能测试工具JMeter基本使用元件构成线程组jmeter的分布式使用jmeter测试报告常用插件性能测试的计算1.根据请求数明细数据计算满足…...

类型断言[as语法 | <> 语法

TypeScript中的类型断言[as语法 | &#xff1c;&#xff1e; 语法] https://huaweicloud.csdn.net/638f0fbbdacf622b8df8e283.html?spm1001.2101.3001.6650.1&utm_mediumdistribute.pc_relevant.none-task-blog-2~default~CTRLIST~activity-1-107633405-blog-122438115.2…...

barret reduction原理详解及硬件优化

背景介绍 约减算法&#xff0c;通常应用在硬件领域&#xff0c;因为模运算mod是一个除法运算&#xff0c;在硬件中实现速度会比乘法慢的多&#xff0c;并且还会占用大量资源&#xff0c;因此需要想办法用乘法及其它简单运算来替代模运算。模约减算法可以利用乘法、加法和移位等…...

NLP / LLMs中的Temperature 是什么?

ChatGPT, GPT-3, GPT-3.5, GPT-4, LLaMA, Bard等大型语言模型的一个重要的超参数 大型语言模型能够根据给定的上下文或提示生成新文本&#xff0c;由于神经网络等深度学习技术的进步&#xff0c;这些模型越来越受欢迎。可用于控制生成语言模型行为的关键参数之一是Temperature …...

c#快速入门~在java基础上,知道C#和JAVA 的不同即可

☺ 观看下文前提&#xff1a;如果你的主语言是java&#xff0c;现在想再学一门新语言C#&#xff0c;下文是在java基础上&#xff0c;对比和java的不同&#xff0c;快速上手C#&#xff0c;当然不是说学C#的前提是需要java&#xff0c;而是下文是从主语言是java的情况下&#xff…...

nginx--基本配置

目录 1.安装目录 2.文件详解 2.编译参数 3.Nginx基本配置语法 1./etc/nginx/nginx.conf 2./etc/nginx/conf.d/default.conf 3.启动重启命令 4.设置404跳转页面 1./etc/nginx/conf.d/default.conf修改 ​2. 重启 5.最前面内容模块 6.事件模块 1.安装目录 # etc cd …...

R语言中apply系列函数详解

文章目录applylapply, sapply, vapplyrapplytapplymapplyR语言系列&#xff1a; 编程基础&#x1f48e;循环语句&#x1f48e;向量、矩阵和数组&#x1f48e;列表、数据帧排序函数&#x1f48e;apply系列函数 R语言的循环效率并不高&#xff0c;所以并不推荐循环以及循环嵌套…...

红黑树探险:从理论到实践,一站式掌握C++红黑树

红黑树揭秘&#xff1a;从理论到实践&#xff0c;一站式掌握C红黑树引言为什么需要了解红黑树&#xff1f;红黑树在现代C编程中的应用场景树与平衡二叉搜索树树的基本概念&#xff1a;二叉搜索树的定义与性质&#xff1a;平衡二叉搜索树的特点与需求&#xff1a;红黑树基础红黑…...

CDH6.3.2大数据集群生产环境安装(七)之PHOENIX组件安装

添加phoenix组件 27.1. 准备安装资源包 27.2. 拷贝资源包到相应位置 拷贝PHOENIX-1.0.jar到/opt/cloudera/csd/ 拷贝PHOENIX-5.0.0-cdh6.2.0.p0.1308267-el7.parcel.sha、PHOENIX-5.0.0-cdh6.2.0.p0.1308267-el7.parcel到/opt/cloudera/parcel-repo 27.3. 进入cm页面进行分发、…...

【C++要笑着学】搜索二叉树 (SBTree) | K 模型 | KV 模型

C 表情包趣味教程 &#x1f449; 《C要笑着学》 &#x1f4ad; 写在前面&#xff1a;半年没更 C 专栏了&#xff0c;上一次更新还是去年九月份&#xff0c;被朋友催更很久了hhh 本章倒回数据结构专栏去讲解搜索二叉树&#xff0c;主要原因是讲解 map 和 set 的特性需要二叉搜索…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解

一、前言 在HarmonyOS 5的应用开发模型中&#xff0c;featureAbility是旧版FA模型&#xff08;Feature Ability&#xff09;的用法&#xff0c;Stage模型已采用全新的应用架构&#xff0c;推荐使用组件化的上下文获取方式&#xff0c;而非依赖featureAbility。 FA大概是API7之…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...