作者:morningchen,腾讯 TEG 后台开发工程师
![](https://i-blog.csdnimg.cn/blog_migrate/997cf3ea9a169d76e68603835240ea13.png)
Elasticsearch( ES )是一款功能强大的开源分布式实时搜索引擎,在日志分析(主要应用场景)、企业级搜索、时序分析等领域有广泛应用,几乎是各大公司搜索分析引擎的开源首选方案。
Tencent ES 是内核级深度优化的 ES 分支,持续地进行高可用、高性能、低成本等全方位优化,已支撑的单集群规模达到千级节点、万亿级吞吐。Tencent ES 已在公司内部开源,同时也积极贡献开源社区,截止目前已向社区提交 PR 25+。腾讯联合 Elastic 官方在腾讯云上提供了内核增强版 ES 云服务,支撑公司内部云、外部云、专有云达 60PB+ 的数据存储,服务 蘑菇街、知乎、B 站、凤凰网等业内头部客户。
本文主要介绍 Tencent ES 的主要优化点之一:零拷贝 内存 Off Heap,提升内存使用效率,降低存储成本。最终达到,在读写性能与源生逻辑一致的前提下,堆内存使用率降低 80%,单节点存储量从 5TB 提升至 50TB 的效果。
问题:日志分析场景数据量大,ES 内存瓶颈导致存储成本较高
上节提到,日志分析是 ES 的主要应用场景(占比 60%),而日志数据的特点显著:
数据量大,成本是主要诉求:我们大批线上大客户,数据量在几百 TB 甚至 PB 级,单集群占用几百台机器。如此规模的数据量,带来了较高的成本,甚至有些客户吐槽,日志的存储成本已超越产品自身的成本。
数据访问冷热特性明显:如下图所示,日志访问近多远少,历史极少访问却占用大量成本。
![](https://i-blog.csdnimg.cn/blog_migrate/e33a31e568544894635849cf2ee0768f.png)
分析:成本瓶颈在哪里:堆内存使用率过高
![](https://i-blog.csdnimg.cn/blog_migrate/dfd221c88b099eaac05ecf85f836a6cd.png)
我们对线上售卖的集群做硬件成本分析后,发现成本主要在磁盘和内存。为了降低磁盘成本,我们采取冷热分离、Rollup、备份归档、数据裁剪等多种方式降成本。在冷热分离的集群,我们通过大容量的冷存储机型,来存储历史数据,使得磁盘成本下降 60% 左右。
![](https://i-blog.csdnimg.cn/blog_migrate/dd9c7515831de99f0e3c048460bb74d8.png)
问题也随之而来:如上图所示,大容量的冷机型,存在磁盘使用率过低的问题( 40 % 以下),原因是堆内存使用率过高了( 70 % 左右),制约磁盘使用率无法提升。(其中单节点磁盘使用率 40%,约 13TB 左右,这已经是 Tencent ES 优化后的效果,源生只能支持到 5 TB 左右)所以,为了提升低成本的冷机型磁盘使用率,同时也为了降低内存成本,我们需要降低 ES 的堆内存使用率。
堆内存使用率为什么会高?
ES 是通过 JAVA 语言编写的,在介绍如何降低堆内存使用率之前,先了解下 JAVA 的堆内存:
![](https://i-blog.csdnimg.cn/blog_migrate/f068741a65986663dc9b43cc92745f60.png)
堆内存就是由 JVM (JAVA 虚拟机)管理的内存。建立在堆内存中的对象有生命周期管理机制,由垃圾回收机时自动回收过期对象占用的内存。
堆外内存是由用户程序管理的内存,堆外内存中的对象过期时,需要由用户代码显示释放。
1. 运营侧调整装箱策略能否解决问题?
了解了 JAVA 堆内存后,我们看,能否通过调整运营策略来提升堆内存容量呢?
堆内存分配大一点行不行?超过 32GB,指针压缩失效,内存浪费, 50GB 堆内存性能与 31GB 接近且垃圾回收压力大,也影响性能;
多节点部署提高堆内存总量是否可行?多节点部署,占用机器量更大,用户成本上升大客户节点数过多