首页 > 其他分享 >Ehcache 介绍(1)--Ehcache 功能特性

Ehcache 介绍(1)--Ehcache 功能特性

时间:2024-02-25 10:12:30浏览次数:22  
标签:Ehcache 缓存 堆外 -- 特性 缓存数据 内存 磁盘

Ehcache 是一个开源的、基于标准的缓存工具,它能提升性能、减轻数据库负载并简化可扩展性。由于其稳健性、经得起考验的特点以及与其他流行框架的集成,Ehcache 成为最广泛使用的基于 Java 的缓存工具。Ehcache 从进程内缓存一直扩展到混合的进程内/进程外部署,可以处理 TB 的数据。

1、Ehcache 特性

1.1、支持多级缓存

Guava Cache 或 Caffeine,都是纯内存缓存,使用上会受到内存大小的制约,而 Ehcache 则打破了这一约束。Ehcache2.x 支持基于内存磁盘的二级缓存能力,Ehcache3.x 进一步扩展了此部分能力,增加了对于堆外缓存的支持。此外,结合 Ehcache 原生支持的集群能力,又可以打破单机的限制,完全解决容量这一制约因素。 Ehcache 支持如下形式的缓存:

1.1.1、堆内缓存(heap)

所谓的堆内(heap)缓存,就是我们常规意义上说的内存缓存,严格意义上来说,是指被 JVM 托管占用的部分内存。内存缓存最大的优势就是具有超快的读写速度,但是不足点就在于容量有限、且无法持久化。

1.1.2、堆外缓存(off-heap)

堆外(off-heap)缓存,同样是存储在内存中。其实就是在内存中开辟一块区域,将其当做磁盘进行使用。由于内存的读写速度特别快,所以将数据存储在这个区域,读写上可以获得比本地磁盘读取更优的表现。这里的“堆外”,主要是相对与 JVM 的堆内存而言的,因为这个区域不在 JVM 的堆内存中,所以叫堆外缓存。这块的关系如下图:

既然都是内存中存储,那为何多此一举非要将其划分为堆外缓存呢?直接将这部分的空间类驾到堆内缓存上,不是一样的效果吗?原因如下:

JVM 会基于 GC 机制自动的对内存中不再使用的对象进行垃圾回收,而 GC 的时候对系统性能的影响是非常大的。堆内缓存的数据越多,GC 的压力就会越大,对系统性能的影响也会越明显。所以为了降低大量缓存对象 GC 回收动作的影响,便出现了 off-heap 处理方式。在 JVM 堆外的内存中开辟一块空间,可以像使用本地磁盘一样去使用这块内存区域,这样就既享受了内存的高速读写能力,又避免频繁 GC 带来的烦恼。

堆内缓存与堆外缓存的区别与各自优缺点:
堆内缓存是由 JVM 管理的,在 JVM 中可以直接以引用的形式去读取,所以读写的速度会特别高。而且 JVM 会负责其内容的回收与清理,使用起来比较“省心”。
堆外缓存是在内存中划定了一块独立的存储区域,然后可以将这部分内存当做“磁盘”进行使用。需要使用方自行维护数据的清理,读写前需要序列化与反序列化操作,但可以省去 GC 的影响。

1.1.3、磁盘缓存(disk)

当我们需要缓存的数据量特别大、内存容量无法满足需求的时候,可以使用 disk 磁盘存储来作为补充。相比于内存,磁盘的读写速度显然要慢一些、但是胜在其价格便宜,容量可以足够大。

1.1.4、集群缓存(Cluster)

作为单机缓存,数据都是存在各个进程内的,在分布式组网系统中,如果缓存数据发生变更,就会出现各个进程节点中缓存数据不一致的问题。为了解决这一问题,Ehcache 支持通过集群的方式,将多个分布式节点组网成一个整体,保证相互节点之间的数据同步。

 

需要注意的是,除了堆内缓存属于 JVM 堆内部,可以直接通过引用的方式进行访问,其余几种类型都属于 JVM 外部的数据交互,所以对这部分数据的读写时,需要先进行序列化与反序列化,因此要求缓存的数据对象一定要支持序列化与反序列化。

不同的缓存类型具有不同的运算处理速度,堆内缓存的速度最快,堆外缓存次之,集群缓存的速度最慢。为了兼具处理性能与缓存容量,可以采用多种缓存形式组合使用的方式,构建多级缓存来实现。组合上述几种不同缓存类型然后构建多级缓存的时候,也需要遵循几个约束:

A、多级缓存中必须有堆内缓存,必须按照 堆内缓存 < 堆外缓存 < 磁盘缓存 < 集群缓存 的顺序进行组合;
B、多级缓存中的容量设定必须遵循 堆内缓存 < 堆外缓存 < 磁盘缓存 < 集群缓存 的原则;
C、多级缓存中不允许磁盘缓存与集群缓存同时出现;

1.2、支持缓存持久化

常规的基于内存的缓存都有一个通病就是无法持久化,每次重启的时候,缓存数据都会丢失,需要重新去构建。而 Ehcache 支持使用磁盘来对缓存内容进行持久化保存。

1.3、支持分布式缓存

对于分布式系统,或者是集群场景下,并非是本地缓存的主战场。为了保证集群内数据的一致性,很多场景往往直接选择 Redis 等集中式缓存。但是集中式缓存也弊端,比如有些数据并不怎么更新、但是每个节点对其依赖度却非常高,如果频繁地去 Redis 请求交互,又会导致大量的性能损耗在网络 IO 交互处理上。
针对这种情况,Ehcache 给出了一个相对完美的答案:本地 + 集群化策略。即在本地缓存的基础上,将集群内各本地节点组成一个相互连接的网,然后基于某种机制,将一个节点上发生的变更同步给其余节点进行同步更新,这样就可以实现各个节点的缓存数据一致。

Ehcache 提供了多种不同的解决方案,可以将其由本地缓存变身为“分布式缓存”:
RMI 组播方式
JMS 消息方式
Cache Server 模式
JGroup 方式
Terracotta 方式

1.4、更灵活和细粒度的过期时间设定

Guava Cache 与 Caffeine,它们支持设定过期时间,但是仅允许设定缓存容器级别的过期时间,容器内的所有元素都遵循同一个过期时间。
Ehcache 不仅支持缓存容器级别的过期时间设定,还会支持为容器中每一条缓存记录设定独立过期时间,允许不同记录有不同的过期时间。这在某些场景下还是非常友好的,可以指定部分热点数据一个相对较长的过期时间,避免热点数据因为过期导致的缓存击穿。

1.5、同时支持 JCache 与 SpringCache 规范

Ehcache 作为一个标准化的通用缓存框架,同时支持 Java 目前最为主流的两大缓存标准,即官方的 JSR107 标准以及使用非常广泛的 Spring Cache 标准,这样使得业务中可以基于标准化的缓存接口去调用,避免了 Ehcache 深度耦合到业务逻辑中去。

1.6、Ehcache、Caffeine、Redis 如何选择

1.6.1、Caffeine

A、更加轻量级,使用更加简单,可以理解为一个增强版的 HashMap
B、足够纯粹,适用于仅需要本地缓存数据的常规场景,可以获取到绝佳的命中率与并发访问性能

1.6.2、Redis

A、纯粹的集中缓存,为集群化、分布式多节点场景而生,可以保证缓存的一致性
B、业务需要通过网络进行交互,相比与本地缓存而言性能上会有损耗

1.6.3、Ehcache

A、支持多级缓存扩展能力。通过内存+磁盘等多种存储机制,解决缓存容量问题,适合本地缓存中对容量有特别要求的场景
B、支持缓存数据持久化操作。允许将内存中的缓存数据持久化到磁盘上,进程启动的时候从磁盘加载缓存数据到内存中
C、支持多节点集群化组网。可以将分布式场景下的各个节点组成集群,实现缓存数据一致,解决缓存漂移问题

相比而言,Caffeine 专注于提供纯粹且简单的本地基础缓存能力;Redis 则聚焦集中缓存可保证数据的一致性;Ehcache 的功能比较中庸,介于两者之间,既具有本地缓存无可比拟的性能优势,又兼具分布式缓存的多节点数据一致性与容量扩展能力。项目里面进行选型的时候,可以结合上面的差异点,评估下自己的实际诉求,决定如何选择。

简单来说,把握如下原则即可:
A、如果只是本地简单、少量缓存数据使用的,选择 Caffeine
B、如果本地缓存数据量较大、内存不足需要使用磁盘缓存的,选择 EhCache
C、如果是大型分布式多节点系统,业务对缓存使用较为重度,且各个节点需要依赖并频繁操作同一个缓存,选择 Redis

    参考:https://juejin.cn/post/7167259989826863112

标签:Ehcache,缓存,堆外,--,特性,缓存数据,内存,磁盘
From: https://www.cnblogs.com/wuyongyin/p/17992954

相关文章

  • 《程序是怎样跑起来的》第九章读后感
    在阅读第九章后,我对操作系统和应用程序之间的关系有了更深入的理解。系统调用作为连接两者的桥梁,起到了至关重要的作用。    操作系统就像一个精心编排的舞台导演,为应用程序提供了一个稳定且安全的演出环境。它负责管理硬件资源、处理并发任务、保障数据的完整性和安全性。......
  • 通过ncc 打包unpkg 服务
    默认unpkg是基于rollup构建的,构建之后还如果实际运行还是需要安装依赖的,基于ncc是一个很不错的选择可以实现all-in-one这样实际运行以及docker容器和会小很多,以下是一个简单说明参考配置主要是添加packagescript以及依赖packagescript"scripts":{......
  • 3-3. 野猪-受伤及死亡的逻辑和动画
    制作受伤和死亡动画受伤动画死亡动画就是在受伤动画基础上,增加Color.a从1~0的变化动画状态机如下当hurt触发的时候,从AnyState立刻进入boarHurt,当boarHurt播放完一帧之后进入Exit当dead=true的时候,从AnyState立刻进入boarDead注意,从AnyState出......
  • PropTypes 是 React 提供的一个用于类型检查的库 若使用了ts,还需要使用PropTypes吗
    在使用了TypeScript的React项目中,由于TypeScript已经提供了静态类型检查的能力,通常不需要再额外使用prop-types库进行运行时的类型检查。TypeScript在编译阶段就能通过类型注解确保组件之间的props类型正确无误,这有助于在开发阶段就发现类型不匹配的问题。而prop-ty......
  • 计算机底层知识的“第一课”
    为什么你需要学习计算机组成原理?计算机底层知识的“第一课”其实在看完各个大学的计算机课程设计之后。,你会发现,它们都有差不多十来门核心课程。其中,“计算机组成原理”是入门和底层层面的第一课。虽然计算机系的学生毕业后大多从事软件开发工作,但计算机是由硬件设备如CPU、内......
  • CSP-S联考总结
    目录2023.10.9T1T2T32023.10.11T1T2T3T42023.10.13T1T2T3T42023.10.14T1T22023.10.16T1T22023.10.17T1T2T3T42023.10.19T1T2T3T42023.10.9感觉还不在状态,被卡了一下常,加上没思路,加上部分分没怎么想,加上开错题,打得比较差T1打标找规律,然后\(\sqrtn\)做,但不能取mod,不然会TLE80,还......
  • Jetbrains IDE新UI设置前进/后退导航键
    参考文档:https://blog.csdn.net/qq_37475168/article/details/132507910  背景2023年6月,Jetbrains在新发布的IDE(Idea、PyCharm等)中开放了新UI选项,我们勾选后重启IDE,便可以使用这一魔性的UI界面了。但是前进/后退这对常用的导航键却找不到了,以前的设置方式(View->Appearance->......
  • Volcano架构
    架构-Queue  -Queue是容纳一组PodGroup的队列,也是PodGroup获取集群资源的划分依据。-PodGroup  -PodGroup是一组强关联的pod,对应批处理workload。-VolcanoJob  -VolcanoJob(vcjob)是自定义的Job资源类型,区别于KubernetesJob,vcjob可以指定调度器、支持最......
  • Koordinator架构
     Koordinator设计思路-拥抱Kubernetes上游标准,基于Scheduler-Framework来构建调度能力,而不是实现一个全新的调度器。构建标准形成共识是困难的,但破坏是容易的,Koordinator社区与Kubernetessig-scheduling社区相向而行。-QoS是系统的一等公民,与业界大多数调度器更多......
  • Ray学习记录
     分布式计算框架Ray介绍当我们要构建一个涉及大规模数据处理或者复杂计算的应用,传统的方式是使用现成的大数据框架,例如ApacheFlink和ApacheSpark。这些系统提供的API通常基于某种特定的计算范式(例如DataStream、DataSet),要求用户基于这些特定的计算范式实现应用逻辑。对......