11 月 19 - 20 日 Apache Pulsar 社区年度盛会来啦,立即报名! 了解详情
写点什么

Ari Zilka 谈 Ehcache 的进程内堆外缓存 BigMemory

  • 2010-11-29
  • 本文字数:2501 字

    阅读完需:约 8 分钟

Ehcache 的 BigMemory 提供了一个进程内的堆外缓存,用来存储应用相关的大批量数据。 Terracotta 上周发布了 BigMemory 模块的 GA 版本,该模块支持 Ehcache 企业版。BigMemory 是 Ehcache 标准 API 的一部分,为 cache 定义两个新属性(overflowToOffHeap 和 maxMemoryOffHeap)就可以使用了,代码片段如下所示:

复制代码
<cache name="sample-offheap-cache"
maxElementsInMemory="10000"
eternal="true"
memoryStoreEvictionPolicy="LRU"
overflowToOffHeap="true"
maxMemoryOffHeap="1G"/>

BigMemory 在内存存储策略上有别于传统的缓存解决方案。它不把数据存储在 Java 堆里,从而避免了 JVM 的 GC 问题。BigMemory 这种特别的存储被称为堆外(Off-Heap)存储。传统的缓存解决方案为了规避这些问题,都将数据分布在缓存节点组成的集群上。BigMemory 提供了一种新的架构选择方案,允许应用运行在堆小于 1G 的 JVM 上,利用堆外的内存来加快数据访问的速度。

InfoQ 有幸采访了 Terracotta 的 CTO Ari Zilka,请他谈了 Ehcache 框架里的 BigMemory 新特性、BigMemory 有助于应用性能提升的用例场景,以及 BigMemory 的局限性。

InfoQ:为 Ehcache 框架添加 BigMemory 特性的主要动机是什么?

主要动机是为了解决我们在 Terracotta 服务器里遇到的 GC 问题。服务器里的 GC 会引起响应时间和大规模 GC 事件出现变化,可能会致使(一级缓存 L1 的)缓存客户端故障转移到备份的 Terracotta 服务器上去。我们意识到这个解决方案的好处后就立即扩大了它的应用范围,包括为独立 Ehcache 追加一个内存存储,这个内存存储后来就发展成了 BigMemory——Ehcache 企业版的一个插件。

InfoQ:BigMemory 堆外存储提供的方式能避免 Java GC 的复杂性,你能谈一谈实现的具体细节么?

BigMemory 把缓存对象存储在 Java 堆之外,但仍然在操作系统的 Java 进程里。所以它仍然是个进程内的缓存,具备所有与此相关的高性能,但它不使用堆,这样就可以给应用配置很小的堆空间,从而避免 GC 问题。BigMemory 使用了 JDK 1.4 引入的 DirectByteBuffers 。所有的 Java 实现都可以运行 BigMemory,所以任何人都可以使用 BigMemory,而不用更换 JDK。 操作系统内存管理器的功能差不多就要完成了。届时我们会在放入数据时分配内存、移除数据时释放内存,我们能做这些事情是因为 BigMemory 是个缓存,而不是一般用途的 Java 程序。DirectByteBuffers 分配内存很慢,但用起来非常快。所以我们会在启动的时候就从操作系统获取所有需要的内存。

BigMemory 的关键之处在于,怎样判断某个对象不再被使用、关联的内存被释放了,这也是很多人一开始最难理解的地方。对缓存来说,这其实非常简单。Map 主要涉及 put、get 和 remove 操作。我们在放入数据的时候分配内存(malloc),移除数据的时候释放内存(free)。我们实现了一个内存管理器,它使用的是很好理解的计算机科学算法,还有我们专门为此实现的增强。

在被问及 BigMemory 什么情况下能提升应用性能时(从只读、经常读、读写操作来说),Ari 回答说,在“90% 读 /10% 写”的常见情况和“50% 读 /50% 写”的写操作过多的情况下,他们都见过比较好的性能结果。这是因为缓存是进程内的。只读操作会受到分布式缓存的影响。读取活跃数据集要比读取其它数据快很多,那些不活跃的数据必须通过网络获取。

InfoQ:BigMemory 解决方案有什么局限性?

鉴于 BigMemory 是纯 Java 的、进程内的,而且和常见的 JVM、容器兼容,所以它没有明显的局限性。我们找到的最大的内存盒有 384GB 内存,我们在上面测试的结果显示,在 BigMemory 始终有 350GB 内存的空闲情况下,性能都是线性的,没有明显的增长。 我们要向用户强调的限制只有一个,那就是使用堆外存储的话,放置在 BigMemory 中的对象必须进行序列化。对通常就存储在缓存里的那些数据来说,这并不是什么问题。

一旦对象被序列化,在返回 Java 堆的时候必需反序列化才可以使用。这确实是一笔性能开销。因此在没有 GC 的时候,BigMemory 会比堆内存储慢。但 BigMemory 还是要比底层可用的存储快很多,不论是本地磁盘、网络存储,还是 RDBMS 等原本记录数据的系统。

还应指出的是,序列化 / 反序列化的性能开销远没有很多用户想象的那么大。BigMemory 已经针对字节缓冲区做了优化,本身也包含一些优化机制,可以对使用标准 Java 序列化的对象进行优化。举例来说,测试版发布之后添加的那些优化机制能使复杂 Java 对象的性能提升两倍,使 byte 数组的性能提升四倍。Terracotta Server Array 正是用 byte 数组存储数据的。用自定义的序列化则能进一步减少性能开销。

InfoQ 问 Ari,架构师和开发人员在应用中使用 BigMemory 时应该注意哪些最佳实践和问题。Ari 回答说,任何成功的商业应用都要处理伸缩性问题。缓存是最稳妥、最容易实现的解决方案之一。现在比较新颖的是,不用非得引入缓存集群了。

最好的做法就是用新眼光来审视一下你的性能架构,看你能否从大型的进程内缓存获益。BigMemory 可以让架构师对服务器和进程密度进行优化,以满足特定的需求,而不用受制于 Java 的局限性。 最大的问题则是大多数人已经针对 Java 本身的局限性做了优化。比如说,大多数 Ehcache 用户会运行 32 位的 JVM。根据 OS 的不同,32 位 Java 的地址空间会是 2 到 4GB 不等。所以这些用户在用 Java 时就放弃了使用很多内存。应用目前可能都运行在 RAM 很小的硬件上。所以用户要是想使用 BigMemory 来运行 100GB 的进程内缓存,可能就意味着要更换新的硬件,即便现在硬件很便宜。

InfoQ:Ehcache 框架以后的路线图是怎样的?BigMemory 有什么特殊的么?

我们正在开发 Ehcache 和 Terracotta 的下一个版本(代码以澳大利亚弗里曼特尔的别称 Freo 命名),计划本月发布测试版。我们计划在这个版本中添加一系列功能特性和性能增强。比如 Ehcache Search ,它能让 Ehcache 用户在缓存里进行搜索,就像使用数据库一样。Ehcache Search 已经发布了测试版,文档也已经全部可用了。 至于 BigMemory,我们还在继续提升性能,同时会增加一系列比较实用的增强,例如提供更多的工具,帮助人们更好地理解最适合他们用例的设置。

查看英文原文: Ari Zilka on Ehcache BigMemory

2010-11-29 11:016502
用户头像

发布了 151 篇内容, 共 56.7 次阅读, 收获喜欢 17 次。

关注

评论

发布
暂无评论
发现更多内容

网络入侵检测系统之Suricata(五)--Worker Model线程调度详解详解

于顾而言

网络安全 suricata

网络入侵检测系统之Suricata(十二)--TCP重组优化

于顾而言

网络安全 suricata

网络入侵检测系统之Snort(二)--数据流图与环境搭建

于顾而言

网络安全 ips

网络入侵检测系统之Suricata(十四)--匹配流程

于顾而言

网络安全 suricata

【算法实践】分块查找知多少?手把手带你实现分块查找

迷彩

数据结构 算法 9月月更 分块查找 查找算法

网络入侵检测系统之Snort(一)--snort概览

于顾而言

网络安全 ips

网络入侵检测系统之Suricata(十三)--网络安全威胁及攻击手段总览

于顾而言

网络安全 suricata

网络入侵检测系统之Suricata(三)--日志代码详解

于顾而言

网络安全 suricata

网络入侵检测系统之Suricata(八)--Option实现详解

于顾而言

网络安全 suricata

【云原生 | 从零开始学Docker】六、如何写出自己的镜像——Docker file

泡泡

Docker 云计算 容器 云原生 9月月更

【云原生 | 从零开始学Docker】七丶实战提交自己的镜像以及docker网络

泡泡

Docker 云计算 容器 云原生 9月月更

网络入侵检测系统之Suricata(四)--初始化模块代码详解

于顾而言

网络安全 suricata

网络入侵检测系统之Suricata(十一)--TCP重组实现详解

于顾而言

网络安全 suricata

网络入侵检测系统之Suricata(十五)--IPOnly/Radix Tree详解

于顾而言

网络安全 suricata

网络入侵检测系统之Suricata(十六)--类suricata/snort规则自动维护工具

于顾而言

网络安全 suricata

大数据调度平台Airflow(一):什么是Airflow

Lansonli

9月月更

一文带你快速入门【哈希表】

Fire_Shield

数据结构 哈希表 9月月更

【Meetup预告】OpenMLDB+37手游:一键查收实时特征计算场景案例及进阶使用攻略

第四范式开发者社区

机器学习 数据库 实时计算 特征平台 特征工程

网络入侵检测系统之Suricata(一)--概览

于顾而言

网络安全 suricata

[极致用户体验] 微信设置大字号后,iOS加载网页时闪动怎么办?

HullQin

CSS JavaScript html 前端 9月月更

[Maven进阶]属性与版本管理

十八岁讨厌编程

maven 后端开发 9月月更

[Maven进阶]聚合和继承

十八岁讨厌编程

maven 后端开发 9月月更

网络入侵检测系统之Suricata(十)--ICMP实现详解

于顾而言

网络安全 suricata

网络入侵检测系统之Snort(三)--优劣势与性能指标

于顾而言

网络安全

网络入侵检测系统之Suricata(二)--运行模式及数据流图

于顾而言

网络安全 suricata

网络入侵检测系统之Suricata(七)--DDOS流量检测模型

于顾而言

网络安全 suricata

[Maven进阶]多环境配置与应用

十八岁讨厌编程

maven 后端开发 9月月更

网络入侵检测系统之Suricata(九)--Storage实现详解

于顾而言

网络安全 suricata

MyBatisPlus(四、代码生成器)

Mybatis-Plus 代码生成 9月月更

2022-09-17:一个字符串s,表示仓库的墙 与 货物,其中‘|‘表示墙,‘*‘表示货物。 给定一个起始下标start和一个终止下标end, 找出子串中 被墙包裹的货物 数量。 比如: s = “

福大大架构师每日一题

算法 福大大

网络入侵检测系统之Suricata(六)--规则加载模块代码详解

于顾而言

网络安全 suricata

Ari Zilka谈Ehcache的进程内堆外缓存BigMemory_Java_Srini Penchikala_InfoQ精选文章