美文网首页
JAVA堆外缓存

JAVA堆外缓存

作者: 雪飘千里 | 来源:发表于2023-02-19 21:55 被阅读0次

1 背景

假如有一个服务的各项 JVM 的配置都比较合理的情况下,它的 GC 情况还是不容乐观。

然后 dump 了一把内存,一顿分析之后发现有 2 个对象特别巨大,占了总存活堆内存的 76.8%。

其中第 1 大对象是本地缓存, 使用 caffine 缓存组件,缓存自动刷新周期设定 1 小时,目的是尽量减少 IO 查询次数;

由于占用空间很大,会导致频繁GC,影响系统性能。

如何能尽量缓存较多的数据,同时避免过大的 GC 压力呢?

可以把缓存对象移到堆外,这样可以不受堆内内存大小的限制;并且堆外内存,并不受 JVM GC 的管控,避免了缓存过大对 GC 的影响。

堆外内存不受堆内内存大小的限制,只受服务器物理内存的大小限制。这三者之间的关系是这样的:物理内存=堆外内存+堆内内存。

2 堆外缓存

为了缓解在高并发,高写入操作下,堆内缓存组件造成的频繁GC问题,堆外缓存应运而生。堆内缓存是受JVM管控的,所以我们不必担心垃圾回收的问题。但是堆外缓存是不受JVM管控的,所以也不受GC的影响导致的应用暂停问题。但是由于堆外缓存的使用,是以byte数组来进行的,所以需要自己进行序列化反序列化操作。目前已知的知名开源项目中,netty4的buffer pool采用了堆外缓存实现,具体的比对信息截图如下:

img

带有Direct字眼的即为offheap堆外Buffer,x轴为分配的内存大小,Y轴为耗时。从上面可以看出,小块内存分配,JVM要稍微优秀一点;但是大块内存分配,明显的堆外缓存要优秀一些。由于堆外Buffer操作不受GC影响,实际上性能更好一些。但是需要的垃圾回收管控也需要自己去做,要麻烦很多。

2 开源堆外缓存组件 OHC

2.1 OHC 介绍

OHC 全称为 off-heap-cache,即堆外缓存,是 2015 年针对 Apache Cassandra 开发的缓存框架,后来从 Cassandra 项目中独立出来,成为单独的类库,其项目地址为:https://github.com/snazy/ohc

其特性如下:

  • 数据存储在堆外,只有少量元数据存储堆内,不影响 GC

  • 支持为每个缓存项设置过期时间

  • 支持配置 LRU、W_TinyLFU 驱逐策略

  • 能够维护大量的缓存条目

  • 支持异步加载缓存

  • 读写速度在微秒级别

OHC具有低延迟、容量大、不影响GC的特性,并且支持使用方根据自身业务需求进行灵活配置。

2.2 OHC 用法

快速开始:

OHCache ohCache = OHCacheBuilder.newBuilder().
 keySerializer(yourKeySerializer)
 .valueSerializer(yourValueSerializer)
 .build();

可选配置项:

图片

在我们的服务中,设置 capacity 容量 12G,segmentCount 分段数 1024,序列化协议使用 kryo。

2.3 优化效果

切换到堆外缓存后,服务 YGC 降低到了 800ms / 每分钟,端到端的整体吞吐量上涨了约 20%。

2.4 缺点

缺点主要是序列化、反序列化,如果数据查询特别高频,那反序列化的成本就不可忽略了。

3 应用场景

OHC适合将离线数据进行本地缓存,从而节省访问远程数据库的时间。

网上看到的具体应用场景,主要是在推荐服务中用到,比如 Java堆外缓存OHC在马蜂窝推荐引擎的应用 , vivo的推荐服务计算中也有用到。

相关文章

  • 缓存

    堆缓存堆外缓存磁盘缓存分布式缓存 Guava CacheEHcacheMapDBmemcachedTerracot...

  • 【Spark】Spark 存储原理--存储层分析

    本篇结构: 缓存分析 存储级别 如何选择存储级别 堆内和堆外内存规划 内存空间分配 参考博文 一、缓存分析 RDD...

  • 堆外内存 之 DirectByteBuffer 详解

    堆外内存 堆外内存是相对于堆内内存的一个概念。堆内内存是由JVM所管控的Java进程内存,我们平时在Java中创建...

  • 堆外内存 之 DirectByteBuffer 详解

    堆外内存 堆外内存是相对于堆内内存的一个概念。堆内内存是由JVM所管控的Java进程内存,我们平时在Java中创建...

  • 直接内存与 JVM 源码分析

    直接内存(堆外内存) 直接内存有一种叫法,堆外内存。 直接内存(堆外内存)指的是 Java 应用程序通过直接方式从...

  • Java堆外内存陷阱

    最近在查一个堆外内存泄露的问题,通过-XX:MaxDirectMemorySize仍然限制不住堆外内存的上涨,一直...

  • 堆外内存 Unsafe DirectByteBuffer

    堆内堆外 我们在Java中创建的对象都处于堆内内存(heap)中,堆内内存是由JVM所管控的Java进程内存,并且...

  • JVM-7-线程内存模型

    计算机缓存模型 java缓存模型 主内存主要对应堆 工作内存属于线程私有,可能是cpu寄存器或者高速缓存jvm-0...

  • (13)<架构解决方案>缓存

    静态资源可缓存在cdn、反向代理服务器(nginx)上。概要 1、本地缓存、堆外内存off-heap、 3、red...

  • Netty-内存管理

    但是内存拷贝对性能有可能影响比较大,所以Java中可以绕开堆内存直接操作堆外内存,问题是创建堆外内存的速度比堆内存...

网友评论

      本文标题:JAVA堆外缓存

      本文链接:https://www.haomeiwen.com/subject/lhlbkdtx.html