北京短视频代运营,北京抖音广告片,北京抖音代运营公司欢迎您 ! 联系朗创|收藏本站|网站地图

朗创seo公司

北京专业抖音代运营广告片拍摄10年短视频运营经验!

咨询电话:13683819778

北京seo服务首选朗创网络营销
您的位置: 资讯中心 > 行业资讯 >

如何减少90%的Java垃圾收集时间以Ali HBase的气相色谱优化实践为例

作者: 1 来源:朗创seo公司 发布日期: 2018-08-21 19:22:48
信息摘要:
文摘:GC在Java应用中一直是一个热门话题,特别是在HbASE这样的大型在线存储系统中,数百GB的GC暂停延迟的在线实时性的影响已经成为内核和应用开发者的一大痛点。通过对Ali HBase这一
文摘:GC在Java应用中一直是一个热门话题,特别是在HbASE这样的大型在线存储系统中,数百GB的GC暂停延迟的在线实时性的影响已经成为内核和应用开发者的一大痛点。通过对Ali HBase这一公认的痛点,并进行了深入的分析和全面的创新工作,取得了一些良好的效果。

以蚂蚁风控制方案为例,HBASE的在线YNG GC时间从120 ms减少到15 ms,并结合ZJC,阿里巴巴JDK团队提供的强大工具,在实验室压力测量环境中进一步实现了5毫秒。在这方面的工作和技术思维。

JVM的GC机制屏蔽了开发人员对内存管理的细节,提高了开发效率。对于GC来说,许多人的第一反应可能是JVM有很长的停顿,或者FGC已经导致进程陷入停滞和不可用。数据存储服务,如HBASE,JVM带来的GC挑战是相当复杂和困难的。有三个原因:

1,内存规模巨大,大部分的在线HBASE进程都是96G块。今年,新机型已经配备了160G或更多的堆配置。

2,对象的状态是复杂的。HBASE服务器将保持大量的读写高速缓存,达到几十GB的规模。HBASE提供有序的服务数据以表格形式,组织在一个结构中,产生超过1亿个级别的对象和引用。

3、年轻GC频率越高,接入压力越大,年轻区域的内存消耗越快,一些繁忙的集群可以达到每秒1-2次的年轻GC,大的年轻区域可以降低GC频率,但会带来更大的年轻GC暂停,损害了实时业务需求。

1。作为一个存储系统,HBASE使用大量的内存作为写缓冲器和读高速缓存。例如,在96G堆(4G YNY+92G旧)中,写缓冲器+Read Cache占用内存的70%以上(大约70G),堆本身的内存级别控制在85%,而剩下的内存仅在10G以内。对于JVM,一百千兆字节的GC压力相当于十千兆字节的GC压力,并且当面对较大的堆栈时,它不会在未来恶化。在这种思路下,我们的在线年轻GC时间从120毫秒到15MS获得了优化效果。

2。在一个高吞吐量的数据密集型服务系统中,大量的临时对象经常被创建和回收,如何管理这些临时对象的分配和循环,AliJDK团队开发了一种新的基于租户的GC算法。Rithm,我们将实验室测量的年轻GC时间从15毫秒减少到5毫秒,这是一种意想不到的极端效应。

目前,HBASE使用的存储模型是LSMTAR模型,所写入的数据将临时存储在内存中,以一定的大小和转储到磁盘上形成文件。

SKIPLIST是一种广泛使用的数据结构,以提高并发读写效率,满足数据排序和支持SekSCAN的基本要求。

有许多内部对象。对于存储的每个元素,平均需要4个对象(索引+节点+密钥+值,平均楼层高度为1)。

苏州网站优化 新插入的对象在年轻区域,旧对象在旧区域中,当元素不断插入时,内部参考关系频繁变化。无论PARNED算法的可写标签还是G1算法的RSET标记,都有可能触发旧的区域扫描。

业务所写的KEYVALY元素不是规则长度的,当它被推广到旧区域时,会产生大量的内存碎片。

问题1使得年轻区GC的目标扫描成本非常高,年轻GC提高了更多的对象。问题2使得年轻GC扩展时需要扫描的旧区域。问题3增加了内存碎片造成的FGC的概率。当写入元素小时,问题就变了。更严重的是,我们有在线区域服务器进程的统计数据。有1亿2000万个活动对象。

在分析当前青年GC更大的敌人之后,出现了一个大胆的想法。由于写高速缓存的分配、访问、销毁和循环是由我们来管理的,如果JVM不能看到写缓存,我们可以自己管理写缓存的生命周期,而GC问题自然会得到解决。

当涉及到JVM不可见时,许多人可能会想到一个堆堆解决方案,但是编写高速缓存并不那么简单,因为即使把KeyValue放在堆中也无法避免问题1,而问题2.1和2也是年轻GC的更大问题。

需求增强:如何构建一个有序的地图,支持不使用对象的并发访问,不存在性能损失。

我们在大容量内存段(块)中写入缓存的内存,每个块包含多个节点,每个节点对应一个元素。新插入的元素总是放置在被使用的内存的末端。节点的复杂内部结构存储索引/下一个/键/值的维护信息。新插入的元素需要复制到节点结构。当HBase写入缓存转储时,将恢复整个CCSMAP的所有块。当一个元素被删除时,我们在逻辑上将元素踢出列表,而实际上不从内存中检索元素(A)。虽然有办法实际检索它,而不一定是HBASE。

键值数据被插入一个额外的拷贝,但是在大多数情况下拷贝速度更快。因为CCSMAP结构显示了映射中元素的控制节点和键值是内存接近的,使用CPU缓存更高效,查找速度更快。对于SkipList,写入速度实际上是BO。UND在寻找速度,并且由实际副本生成的开销远小于搜索产生的开销。根据我们的测试,CCSMAP在与JDK一起传输的并发SKIPLISTMAP中,在50字节长度KV测试中增加了20-30%的读写吞吐量。

由于没有JVM对象,每个JVM对象也可以保存至少16字节空间(8字节被保留为标签,8字节是类型指针)。考虑到50BooKEY值,CCSMAP比JDK自己的并发SKIPLISMAP内存容量减少了40%。

使用CCSMAP,原始的1亿2000万个幸存者减少到1000万个级别,大大减少了GC的压力,由于紧凑的内存分配,写入吞吐量也增加了30%。

HBASE在磁盘上以块的方式组织数据。一个典型的HBASE块大小在16K~64公里之间。HBASE内部维护块缓存以减少磁盘I/O块缓存,像写缓存,不符合GC算法理论中的代际假设,并且本质上不利于GC算法。既不是短暂的,也不是永久的。

数据块从磁盘加载到JVM存储器中,生命周期从一个月到另一个月变化。大多数块进入旧区,这只是由JVM为主要GC回收的,其麻烦主要体现在:

在PARNEW算法中,提升是麻烦的,问题不是复制成本,而是找到合适的空间来存储HBASE块的成本更高,因为大小。

读取缓存优化的想法是应用到JVM的块缓存将永远不会返回。我们把记忆分割成一个固定的大小。当块被加载到内存中时,我们将块复制到一个分段的范围,并将其标记为使用。当块不需要时,我们将间隔标记为可用的,并且可以重新定位新块,即BukCask.BukC缓存中关于内存空间的分配和回收(这片DES)IGN和发展是在几年前完成的。

许多基于堆内存的RPC框架也通过自己来管理堆内存的分配和回收,并且通常通过显式释放来回收内存。但是对于HBase来说,存在一些困难。我们将块对象视为需要自我管理的内存片段。CKS可以被多个任务引用,而解决块恢复问题的更简单的方法是将每个任务复制到堆栈上(拷贝块通常不升级到旧区域),并将其交给JVM管理。

事实上,我们以前一直使用这种方法,它简单,JVM背书,安全可靠。但是这是一个有损内存管理方法,它引入了每个请求的拷贝成本来解决GC问题。复制到堆栈中的CPU的额外副本和内存分配成本在您的AR中。EA,由于CPU和总线变得越来越珍贵,所以今天是很高的。

多个变量可以由同一个任务中的同一个块引用。引用可以是堆栈上的临时变量,也可以是堆上的对象。

块上的处理逻辑相对复杂,并且以参数、返回值和字段赋值的形式在多个函数和对象之间传递块。

块可能由我们管理(有些块需要手动释放,有些不需要手动释放)。

结合这些点,编写正确的代码是一个挑战,但是在C++中,使用智能指针管理对象生命周期是很自然的,那么为什么Java中的智能化很难呢

Java中的变量赋值,在用户代码级别上,只产生引用赋值行为。C++中的变量赋值可以用对象构造函数和析构函数来做很多事情,这是基于智能指针(当然,C++构造函数和析构函数的不正确使用会导致许多问题,每个问题都有其优点和缺点。这里没有讨论)。

因此,我们参考C++智能指针,设计了一个块引用管理和回收框架SalabL持有人来解决编码中的困难。

当ShrableHolder被重新赋值时,它释放先前的对象。如果对象被管理,引用计数减少1,如果没有,则没有变化。

由于不能直接分配Syrr持有者,当包含生命周期语义的块需要传递给它时,不能将SalabL持有者用作函数的参数。

根据在这个范例中编写的代码,在原始代码中很少有逻辑改变,并且如果不引入其他的话,虽然仍然有一些复杂性,但幸运的是,受影响的间隔被限制在非常局部的较低层上,这对于HBase来说是可以接受的。为了安全起见,为了避免内存泄漏,我们将一种检测机制添加到检测长非活动引用的框架中,然后强制将其标记为已删除。

在这两个主要优化之后,蚂蚁的风控生产环境的年轻GC时间已经减少到15毫秒。由于在这个尺度上很难优化PARNEX+CMS算法,我们转向ZenGC.ZenGC在G1算法和存储器SE的基础上做了深刻的改进。LF的HBASE和ZEnC堆产生了良好的化学反应。

ZGNC是阿里巴巴JVM团队基于G1算法的大规模堆应用场景的优化GC算法的通用术语,这主要是关于多租户GC。

多租户GC包含三个核心逻辑层:1)JavaHeP上的对象分配基于租户隔离,不同租户使用不同的堆区;2)允许GC以租户粒度较小的成本发生,而不仅仅是整个应用程序;3)允许上层应用程序映射。租户可根据业务需求灵活调整。

ZeNC将内存区域划分为多个租户,在每个租户中独立触发GC,在此基础上,将内存划分为普通租户和中等生命周期租户。中等生命周期对象指的是既不是短暂的也不是永久性的对象。堆中的中等生命周期对象和内存占用的数量现在非常小,但是当生成它们时,旧的周期对象被旧的区域对象引用,并且每个年轻的GC都需要扫描RSET,这对于年轻GC来说仍然是一个耗时巨大的报头。

在AJDK团队的ObjtTrack函数的帮助下,我们发现了中等生命周期对象的大头部分,并将它们直接分配给中等生命周期租户在生成时间的老区域,避免了RSET标签。普通租户以正常的方式分配内存。

平均租户的GC频率非常高,但由于较少的对象推广,较少的跨代参考,年轻小区GC时间得到了很好的控制。在实验室场景模拟环境中,我们优化了年轻的GC到5ms。

Ali HBase已经在阿里云商业化了,任何需要它的用户都可以在Ali云中使用一个深入的、改进的、一站式的HbASE服务。云HBASE版本与自制HB相比,在维护、可靠性、性能、稳定性、安全性、成本等方面都有了许多改进。ASE版。

福利:HasBeCon亚洲2018将于八月在北京举行。识别下面的二维代码或点击左下角阅读原始的免费注册!

更精彩

咨询热线

13683819778