JAVA中使用最广泛的本地缓存?Ehcache的自信从何而来3 —— 解析Ehcache的各种集群方案,本地缓存如何变身分布式缓存

news2024/11/29 14:50:24

大家好,又见面了。

上一篇文章中,我们知晓了如何在项目中通过不同的方式来集成Ehcache并在业务逻辑中进行使用。作为JAVA本地缓存框架综合实力天花板级别的Ehcache,除了在本地缓存方面具有强悍的实力外,还具有一个其它对手所不具备的特色功能,即Ehcache提供了对于集群能力的支持,这也使得Ehcache不仅仅是个本地单机缓存,更是一个分布式缓存。

分布式缓存的意义是什么?集群方案又可以解决哪些问题?它与单机缓存有啥区别?与Redis等集中式缓存有啥不同?如何去选择、又该如何使用?带着这一连串的疑问,让我们一起探讨下Ehcache的各种不同集群方案,找出上述问题的答案。

本地缓存或者集中缓存的问题

在正式开始阐述Ehcache的集群解决方案前,先来做个铺垫,了解下单机缓存与集中式缓存各自存在的问题。

单机缓存不可言说的痛

对于单机缓存而言,缓存数据维护在进程中,应用系统部署完成之后,各个节点进程就会自己维护自己内存中的数据。在集群化部署的业务场景中,各个进程独自维护自己内存中的数据,而经由负载均衡器分发到各个节点进行处理的请求各不相同,这就导致了进程内缓存数据不一致,进而出现各种问题 —— 比较典型的就是缓存漂移问题。

缓存漂移,是单机缓存在分布式系统下无法忽视的一个问题。在这种情况下,大部分的项目使用中会选择避其锋芒、或者自行实现同步策略进行应对。常见的策略有:

  • 本地缓存中仅存储一些固定不变、或者不常变化的数据。

  • 通过过期重新加载、定时refresh等策略定时更新本地的缓存,忍受数据有一定时间内的不一致

  • 对于少量更新的场景,借助MQ构建更新机制,有变更就发到MQ中然后所有节点消费变更事件然后更新自身数据。

集中式缓存也并非万能银弹

在集群部署的场景下,为了简化缓存数据一致性方面的处理逻辑,大部分的场景会直接选择使用Redis等集中式缓存。集中式缓存的确是为分布式集群场景而生的,通过将缓存数据集中存放,使得每个业务节点读取与操作的都是同一份缓存记录。这样只需要由缓存服务保证并发原子性即可。

但集中式缓存也并非是分布式场景下缓存方案的万能银弹。

项目中使用缓存的目的,主要是为了提升整体的运算处理效率,降低对外的IO请求等等。而集中式缓存是独立于进程之外部署的远端服务,需要基于网络IO交互的方式来获取,如果一个业务逻辑中涉及到非常频繁的缓存操作,势必会导致引入大量的网络IO交互,进而导致非常严重的性能损耗

为了解决这个问题,很多时候还是需要本地缓存结合集中式缓存的方式,构建多级缓存的方式来解决。

Ehcache分布式集群方案

相比纯粹的本地缓存,Ehcache自带集群解决方案,通过相应的配置可以让本地缓存变身集群版本,以此来应付分布式场景下各个节点缓存数据不一致的问题,并且由于数据都缓存在进程内部,所以也可以避免集中是缓存频繁在业务流程中频繁网络交互的弊端。

Ehcache官方提供了多种集群方案供选择,下面一起看下。

RMI组播

RMI是一种点对点(P2P)的通信交互机制,Ehcache利用RMI来实现多个节点之间数据的互通有无,相互知会彼此更新数据。对于集群场景下,这就要求集群内所有节点之间要两两互通,组成一张网状结构。

在集群方式下进行数据通信交互,要求被传输的数据一定是要可序列化与反序列化的,对于JAVA而言,直白的说,就是对象一定是要实现了Serializable接口。

基于RMI组播的方式,Ehcache会向对应地址发送RMI UDP组播包,由于Ehcache对于组播的实现较为简单,所以在一些网络情况较为复杂的场景的支持度不是很完善,方案选择的时候需注意。此外,由于是即时消息模式,如果中途某个进程由于某些原因不可达,也可能会导致同步消息的丢失。所以对于可靠性以及数据一致性要求较高的场景需要慎选

JMS消息

JMS消息方案是一种很常用的Ehcache集群方案。JMS是一套JAVA中两个进程之间的异步通信API,定义了消息通讯所必须的一组通用能力接口,比如消息的创建、发送、接收读取等。

JMS也支持构建基于事件触发模型的消息交互机制,也即生产者消费者模式(又称发布订阅模式),其核心就是一个消息队列,集群内各个业务节点都订阅对应的消息队列topic主题,如果有数据变更事件,也发送到消息队列的对应的topic主题下供其它节点消费。

相比于RMI组播方式,JMS消息方式有个很大的优势在于不需要保证所有节点都全部同时在线,因为是基于发布订阅模式,所以即使有节点中途某些原因宕机又重启了,重启之后仍然可以接收其他节点已发布的变更,然后保证自己的缓存数据与其它节点一致。

Ehcache支持对接多种不同的MQ来实现基于JMS消息的集群组网方案,默认使用ActiveMQ,也可以切换为Kafka或者RabbitMQ等消息队列组件。

Cache Server模式

Ehcache的Cache Server是一种比较特殊的存在形式,它通常是一个独立的进程进行部署,然后多个独立的进程之间组成一个分布式集群。Cache Server是一个纯粹的缓存集群,对外提供restful接口或者soap接口,各个业务可以通过接口来获取缓存 —— 这个其实已经不是本地进程内缓存的概念了,其实就是一个独立的集中式缓存,类似Redis般的感觉。

看一下一个典型的高可用水平扩容模式的Cache Server组网与业务调用的场景示意图:

可以看到不管业务模块是用的什么编码语言,或者是什么形态的,都可以通过http接口去访问缓存数据,而Cache Server就是一个集中式缓存。在Cache Server中,集群内部可以有一个或者多个节点,这些节点具有完全相同的数据内容,做到了数据的冗余备份,而集群之间数据可以不同,实现了数据容量的水平扩展。

值得注意的一点是,如果你访问Ehcache的官网,会发现其官方提供的3.x版本的说明文档中不再有Cache Server的身影,而在2.x版本中都会作为一个单独的章节进行介绍。为什么在3.x版本中不再提供Cache Server模式呢?我在官方文档中没找到相关的说明,个人猜测主要有下面几个原因:

  • 定位过于尴尬,如果说要作为集中式缓存来使用,完全可以直接使用redis,没有必要费事劳神的去搭建Cache Server

  • Terracotta方式相比而言功能上更加的完备,兼具水平扩展与本地缓存的双重优势,完全可以取代Cache Server

JGroups方式

JGroups的方式其实和RMI有点类似。JGroups是一个开源的群组通讯工具,可以用来创建一个组,这个组中的成员可以给其他成员发送消息。其工作模式基于IP组播(IP multicast),但可以在可靠性和群组成员管理上进行扩展,而且JGroups的架构上设计非常灵活,提供可以兼容多种协议的协议栈。

JGroups的可靠性体现在下面几个方面:

  1. 对所有接收者的消息的无丢失传输(通过丢失消息的重发)
  2. 大消息的分割传输和重组
  3. 消息的顺序发送和接收
  4. 保证原子性,消息要么被所有接收者接收,要么所有接收者都收不到

也正是由于JGroups具备的上述诸多优秀特性,它常常被选择作为集群内各个节点之间数据同步的解决方案。而Ehcache也一样,支持基于JGroups实现的集群方案,通过IP组播消息,保证集群内各个节点之间数据的同步。

Terracotta方式

Terracotta是什么?看下来自百度百科的介绍:

Terracotta是一款由美国Terracotta公司开发的著名开源Java集群平台。它在JVM与Java应用之间实现了一个专门处理集群功能的抽象层,以其特有的增量检测、智能定向传送、分布式协作、服务器镜像、分片等技术,允许用户在不改变现有系统代码的情况下实现单机Java应用向集群化应用的无缝迁移。使得用户可以专注于商业逻辑的开发,由Terracotta负责实现高性能、高可用性、高稳定性的企业级Java集群。

所以说,Terracotta是一个JVM层专门负责做分布式节点间协同处理的平台框架。那么当优秀的JVM级缓存框架Ehcache与同样优秀的JVM间多节点协同框架Terracotta组合到一起,势必会有不俗的表现。

看下来自Ehcache官网的对于其Terracotta集群模式的图片说明:

基于Terracotta方式,Ehcache可以支持:

  • 热点数据存储在进程本地,然后根据热度进行优化存储,热度高的会优先存储在更快的位置(比如heap中)。

  • 存储在其中一台应用节点上的缓存数据,可以被集群中其它节点访问到。

  • 缓存数据在集群层面是完整的,也支持按照HA模式设定高可用备份。

可以说这种模式下,既保留了Ehcache本地缓存的超高处理性能,又享受到了分布式缓存带来的集群优势,不失为一种比较亮眼的组合。

引申思考 —— 本地缓存的设计边界与定位

如上所言,纵使Ehcache提供了多种集群化策略,但略显尴尬的是实际中各个公司项目并没有大面积的使用。其实分析下来也很好理解:

如果真的需要很明确的诉求去解决分布式场景下的缓存一致性问题,直接选择redis、memcache等主流的集中式缓存组件即可

所以Ehcache的整体综合功能虽然是最强大的,整体定位偏向于大而全,但也导致在各个细分场景下表现不够极致:

  • 相比Caffeine:略显臃肿, 因为提供了很多额外的功能,比如使用磁盘缓存、比如支持多节点间集群组网等;

  • 相比Redis: 先天不足,毕竟是个本地缓存,纵使支持了多种组网模式,依旧无法媲美集中式缓存在分布式场景下的体验。

但在一些相对简单的集群数据同步场景下,或者对可靠性要求不高的集群缓存数据同步场景下,Ehcache还是很有优势的、尤其是Terracotta集群模式,也不啻为一个很好的选择。

小结回顾

好啦,关于Ehcache的集群相关能力,就介绍到这里咯,而关于文章开头的几个问题,我们也在文章内容中做了解答与探讨。至此呢,我们关于Ehcache的相关介绍就全部结束了。那么你对Ehcache是否还有什么自己的观点呢?欢迎评论区一起交流下,期待和各位小伙伴们一起切磋、共同成长。

随着本篇Ehcache介绍文章的结束,我们缓存专栏关于主流本地缓存框架的介绍就告一段落了。下一篇文章开始,我们将开始将目光聚焦到集中式缓存的身上,比如大家耳熟能详的Redis,以及经常在面试中会拿来与Redis做比较的Memcache等等。如有兴趣,欢迎关注。

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

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

相关文章

Metabase学习教程:提问-6

搜索表格和问题 了解如何使用筛选器和自定义表达式在SQL查询和简单问题中进行搜索。在表格中查找单词或短语现在比以往任何时候都容易。 添加过滤器给你的问题可以让你的问题搜索文本轻而易举。您可以使用示例数据库包含在每个Metabase安装中。 在问题中搜索 我们将从单击浏…

linux笔记(8):东山哪吒D1H移植lvgl(HDMI输出)

文章目录1. 下载,修改,编译源码1.1下载源码1.1.1新建一个lvgl目录,在该目录下下载源码1.1.2 在lvgl目录下再建一个myspace/lvgl_demo目录,把参与编译的文件拷贝到本目录1.2 修改源码1.3编译源码2.拷贝到东山哪吒开发板运行3.已移植…

BUUCTF Web 极客大挑战 2019 EasySQL

BUUCTF Web 极客大挑战 2019 EasySQL 文章目录BUUCTF Web 极客大挑战 2019 EasySQL1,输入万能密码:2,输入万能账号首先有点常识:正常SQL语句这样子写:select * from user where username XXX and password XXX&#x…

MySQL函数

函数的理解 什么是函数 函数在计算机语言的使用中贯穿始终,函数的作用是什么呢?它可以把我们经常使用的代码封装起来,需要的时候直接调用即可。这样既 提高了代码效率 ,又 提高了可维护性 。在 SQL 中我们也可以使用函数对检索出…

prompt(1) to win -xss学习

网址 https://prompt.ml/level 0 (闭合) function escape(input) {// warm up// script should be executed without user interactionreturn <input type"text" value" input ">; } 闭合前面的双引号 "><img src1 onerrorprompt(1)…

EasyPoi——导出导入表格数据工具

文章目录文档概念环境搭建&#xff08;maven&#xff09;工具类主要使用注解Excel 主要用的注解实战实体类&#xff08;部分&#xff09;导出Controller层导出结果导入service层controller层文档 官方文档 概念 Easypoi主打的功能就是容易&#xff0c;让一个没见接触过poi的…

java每日一练 (1)

java每日一练 &#xff08;1&#xff09; 单选部分 1.在 Java 中&#xff0c;存放字符串常量的对象属于&#xff08; &#xff09;类对象。   A Character B String C StringBuffer D Vector 答案 &#xff1a; B 复习文章 &#xff1a; String类 — 上篇_ 2.图示 &#xff…

C#在Pdf画统计图表之【雷达图】(以五边形为例)

前言 工具&#xff1a;PdfSharpCore或Pdfsharp 知识 &#xff1a;基本的三角函数 思路 &#xff1a; 画坐标&#xff0c;确定点-------->画多个半径渐变的正多边形------->根据数据确定雷达图的数值位置 StepOne:画一个正五边形 先画一个辅助坐标轴&#xff0c; 再通过…

40多行实现一个非常简单的shell

目录简单的shell的实现附代码简单的shell的实现 目的&#xff1a;主要就是为了加深对shell的底层原理的理解 可以通过接口可以获取到这些主机名等等这里直接就用字符串打印了 当我们打开一个c文件默认就打开了三个输入输出流&#xff1a;stdin(标准输入),stdout(标准输出),st…

一种具有肤质保留功能的磨皮算法

基本原理 1、复制原图Src作为HighPass层&#xff1a;HighPass Copy(Src)。 2、对HighPass层磨皮&#xff08;就是进行保边滤波&#xff0c;可以选择表面模糊、导向滤波、双边滤波、各向异性扩散、BEEP、局部均方差、Domain transfer、 Adaptive Manifolds、 Local Laplacian …

产品经理学习和认证PMP

PMP的功效 PMP是由美国项目管理协会&#xff08;PMI&#xff09;发起的项目管理认证考试&#xff0c;以项目管理知识体系&#xff08;PMBOK&#xff09;为考试基准。经过实际分析和总结&#xff0c;PMP具有如下几种功效&#xff1a; 首先&#xff0c;PMP是国际认可度最高的项目…

Essay写作论证基本的五要素讲解

对于出国留学而言的学生来说&#xff0c;Essay写作是非常重要的。每个学期导师都会布置下Essay课业&#xff0c;如果你的写作能力不够的话&#xff0c;是很难写出让导师满意的Essay来&#xff0c;Essay的写作更是如此。因为Essay的写作难度本身就比普通Essay难度大得多&#xf…

viewerjs -v 11 动态获取图片(ajax),以及重复初始化问题。

&#xff08;1&#xff09;viewerjs 源码&#xff0c;以及官方文档 ​​​​​i​​​​​​​​​​​​​https://github.com/fengyuanchen/viewerjs/blob/main/README.mdhttps://github.com/fengyuanchen/viewerjs/blob/main/README.md &#xff08;2&#xff09;静态图片…

免杀Veil-evasion

● 属于Veil-framework框架的一部分 ● 由Python语言编写 ● 用于自动生成免杀payload ○ 集成msf payload&#xff0c;支持自定义payload ○ 集成各种注入技术 ○ 集成各种第三方工具 ■ Hypersion、PEScrambler、BackDoor、Factory ○ 继承各种开发打包运行环境 ■ Python&am…

企业投放电视广告的正确姿势是什么

越来越多的互联网企业开始选择投放电视广告。 互联网革了电视以外的所有传统媒体的命。传统报刊、杂志大部分淡出人们的视野&#xff0c;报刊亭也在逐渐的减少直至关停&#xff0c;而只有电视媒体屹立不倒——其媒体价值非但没有降低&#xff0c;反而在逐年加大。电视媒体热播…

【模型训练】yolov7猫狗检测

yolov7猫狗检测 1、猫狗检测模型训练2、模型评估3、模型和数据集下载网盘链接1、本项目采用YOLOv7算法实现对猫狗检测,在几千多张猫狗检测数据集中能训练得到,我们训练了YOLOv7、,所有指标都是在同一个验证集上得到; 2、目标类别数:2 ;类别名:cat、dog; 3、本项目提供了…

java项目-第157期ssm毕业生就业信息管理系统-java毕业设计_计算机毕业设计

java项目-第157期ssm毕业生就业信息管理系统-java毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm毕业生就业信息管理系统》 该项目分为4个角色&#xff0c;管理员、用户、导师、企业。 用户可以浏览前台,比如招聘信息&#xff0c;进行简历投递。 导…

当公路的规则与秩序,被昇腾AI时刻守护

作者 | 曾响铃 文 | 响铃说 用一张其他车型的ETC卡&#xff0c;穿过闸机&#xff0c;顺利“节省”一大笔过路费&#xff1b; 超载了一大截&#xff0c;在车型上做点手脚&#xff0c;顺利通过检查&#xff0c;扬长而去&#xff1b; 开着危化品车辆在服务区见到位置就停&…

Redis数据结构解析

文章目录Redis数据结构SDSHash小整数集合实现方式链表压缩链表快速链表紧凑链表级联更新取代ziplist跳表总结参考资料Redis数据结构 详解&#xff1a;mystudy/Redis/Redis数据结构详解.md Zhang-HaoQi/Knowledge - 码云 - 开源中国 (gitee.com) SDS struct sds {int len;//…

数据结构学习笔记(Ⅱ):线性表

目录 1 线性表 1.1 线性表的定义 1.2 线性表的基本操作 2 顺序表 2.1 顺序表定义 2.2 顺序表的实现 1.静态分配 2. 动态分配 3.顺序表的特点 2.3 顺序表操作 1.插入 2.删除 3.按位查找 4.按位查找 3 链表 3.1 单链表 1.定义 2. 插入和删除 3. 查找 4.单链表…