京东ES支持ZSTD压缩算法上线了:高性能,低成本 | 京东云技术团队

1 前言

在《ElasticSearch降本增效常见的方法》一文中曾提到过zstd压缩算法[1],一步一个脚印我们终于在京东ES上线支持了zstd;我觉得促使目标完成主要以下几点原因:

  1. Elastic官方原因:zstd压缩算法没有在Elastic官方的开发计划中;Elastic的licenes变更,很多功能使用受限

  2. ES产品竞争力:提升京东ES产品在业界的竞争力,两大云友商和其他大厂都在陆续支持,在对外比拼的时候,我们需要提升我们这方面的能力

  3. 信创大背景:我们需要对开源组件有更好的自主管控和建设能力

  4. 京东零售ES与云ES产品融合:有更好的机会去打磨我们的ES内核

  5. 降本增效:ztsd压缩算法,能够在降低存储成本的前提下,保证性能几乎不受损,写入性能还有所提升

2 测试结果

测试集群配置:4c8g; 3个数据节点;
测试索引设置:3主分片1副本
测试数据mapping: keyword字段14个,geo_point字段3个,integer字段2个,text字段1个,date字段:2个,ip类型字段1个,boolean字段1个

在考虑到读写性能和压缩比均衡的情况下,我们推荐使用jd_zstd(压缩等级3):

  • jd_zstd(压缩等级3)写入性能相对于best_compression提升38.46%,相对于lz提升5.88%

  • jd_zstd(压缩等级3)存储相对于lz4节省24%,与best_compression基本持平,单位写的gb实际是要比best_compression的存储量小。

下表为es6.8.23版本,在cpu压测到100%时,不通压缩算法下ES的bulk、termquery、rangequery、matchquery等TPS以及压缩比测试结果:

压缩算法bulktermqueryrangequerymatchquery数据存储大小(580W条文档)segment forcemerge为1个压缩率,基准为lz(ES默认为lz压缩算法)
lz434K7.7K79045013gb-
best_compression26K4.7K78043010gb76.9%
jd_zstd(压缩等级3)36K5.4K79045010gb76.9%
jd_zstd(压缩等级6)32K5.6K7904609.8gb75.38%
jd_zstd(压缩等级9)25K5.5K7904509.8gb75.38%

注意⚠️:测试数据仅供参考,实际情况与用户数据有关

3 适用场景

写多读少的场景,比如日志和监控场景。


4 使用方法

云上ES等待上线后,可以进行申请

目前我们暂时只在内部泰山零售ES上线,支持7.X和6.8.23版本;后续会在云舰ES和公有云ES上线,由于licenes的限制,我们将只推出6.8.23版本。

Q1: 如何申请?
**A1:**内部用户:之前在泰山平台申请的杰斯ES,如果使用的是7.X和6.8.23,可以选择版本升级到最新版本。新建集群,直接提工单申请

Q2 ztsd如何使用?
A2:我们在ES中支持两种zstd压缩等级,用户可以根据自己的业务和数据特性选择合适的压缩等级; ES创建索引时指定index.codec:jd_zstd(压缩等级为3)或者jd_zstd_6(压缩等级为6)即可,其余没有其他任何特殊之处。

注意⚠️:index.codec的压缩算法不支持动态修改,必须创建索引时设定好。

# 创建索引zstdtest 压缩等级为 3
PUT zstdtest
{
    "settings": {
      "index": {
        "codec": "jd_zstd"
      }
    }
}

# 创建索引zstdtest_6 压缩等级为 3
PUT zstdtest_6
{
    "settings": {
      "index": {
        "codec": "jd_zstd_6"
      }
    }
}


5 技术实现

首先我们介绍下ES与Lucene的关系;如下图所示,在集群层面:一个ES集群由多个节点组成。数据层面:1个索引是由多个分片组成的,一个分片可以看是一个Lucene实例;一个分片包含多个segement,一个segement即一组数据的最小单元,包含很多的数据文件。

es集群文件 (1).png

5.1 Lucene文件

lucene[2]的数据文件主要由以下文件组成:

NAMEExtensionBrief Description
Segments Filesegments_N存储已经落盘数据的位移提交点
Lock Filewrite.lock锁文件,防止多个 IndexWriters 写同一个文件
Segment Info.si存储单个segment的metadata
Compound File.cfs, .cfe复合文件主要是为了减少文件描述符;在IndexWriterConfig可以配置是否生成复合索引文件;复合文件实质是索引文件的组合,意思是无论是否设置了使用复合文件,总是先生成非复合索引文件,随后在flush阶段,才将这些文件生成.cfs、.cfe文件,其中.liv、.si所以文件不会被组合到.cfs、.cfe中。
Fields.fnm存储有关字段的信息
Field Index.fdx指向字段数据的指针;存储了原文数据在原文存储文件中的位置信息,建立起了doc id和原文之间的联系,以支持快速访问和定位
Field Data.fdt文档的存储字段
Term Dictionary.timterm词典,存储term信息
Term Index.tipTerm词典的索引
Frequencies.doc文档列表,其中包含每个term以及频率
Positions.pos存储term在索引中出现位置的位置信息
Payloads.pay存储附加的每个位置元数据信息,如字符偏移和用户payloads
Norms.nvd, .nvm编码文档和字段的长度以及权重提升因子
Per-Document Values.dvd, .dvm编码额外的评分因子或其他每个文档的信息
Term Vector Index.tvx矢量数据的索引文件;将偏移量存储到文档数据文件中
Term Vector Data.tvdterm矢量数据
Live Documents.liv有关哪些文档处于存活的信息;当发生标记删除时会产生该文件
Point values.dii, .dim保留索引点,如果存在

上述的文件大致可以分为以下几类:

  • 行存相关文件:主要包括原文存储文件.fdt和原文索引文件.fdx。用户写入的原始数据都被存储于.fdt,占比是最大的,Lucene在原文存储上支持LZ4和ZIP(best_compression)压缩。在写入数据时,ES把doc原始数据的整个json结构体当做一个string,存储为_source字段,因此原文存储文件.fdt中_source字段占比最大;部分场景为了节省磁盘存储,直接将该字段关闭,数据查询时仍可通过ES的docvalue_fields获取所有字段的值;
 "_source": {
   "enabled": false
 }


注意⚠️:关闭_source后, update, update_by_query, reindex等功能无法正常使用,因此有update等需求的索引不能关闭_source.

  • 列存相关文件:.dvd文件,常用于OLAP分析,ES使用列存来支持sorting, aggregations和scripts功能。不同文档Document中的同一列(Field)数据相邻存放,加速列聚合分析性查询。相邻每列类型相同,在存储的时候可以进行统一性的编码优化,提高压缩率,减少存储磁盘空间的占用。ES中字段使用doc_values字为true,即为开启列存储。

  • 索引相关文件:主要文件包括字典数据文件.tim和倒排索引.doc文件。ES依靠分词器产生倒排索引,从而具备强大的全文检索能力。索引配置分词器后,将从摄入文档数据中提取分词信息并存储于.tim文件。同一列的分词信息相邻存放,按块组织;.doc文件也被称为"倒排拉链表",记录每一个词项所关联的文档id列表,实现词项到文档的快速倒排查找。倒排索引也会进行压缩,其压缩算法主要有Frame Of Reference、Roaring Bitmap和fst等。

  • 向量数据文件:矢量索引tvx和矢量数据.tvd文件,支持以图搜图,和音频的查找等。通过对摄入实体进行矢量化,然后使用向量搜索算法进行检索。相关向量搜索算法有HNSW[3],近似向量搜索knn[4];elastic公司在今年5月份左右推出用于人工智能的 Elasticsearch相关性引擎ESRE[5]。

zstd主要压缩为行存储相关文件.fdm、.fdt 和.fdx;如下代码块为压缩文件对比,可以看出在不同的压缩算法中,这几个文件的大小是不同的。

# 为了节省篇幅部分文件省略      
## lz4压缩算法索引testlz4    0 号分片
total 2.4G
-rw-r--r-- 1 admin admin 1.2K Nov 16 16:19 _32.fdm
-rw-r--r-- 1 admin admin 1.3G Nov 16 16:19 _32.fdt
-rw-r--r-- 1 admin admin  76K Nov 16 16:19 _32.fdx
-rw-r--r-- 1 admin admin  85M Nov 16 16:21 _32.kdd
-rw-r--r-- 1 admin admin 149M Nov 16 16:21 _32_Lucene80_0.dvd
.........................................
-rw-r--r-- 1 admin admin  401 Nov 16 16:21 segments_b
-rw-r--r-- 1 admin admin    0 Oct 16 16:05 write.lock

## best_compression压缩算法索引 testbestcompression   0 号分片
total 1.9G
-rw-r--r-- 1 admin admin  287 Nov 16 17:01 _2b.fdm
-rw-r--r-- 1 admin admin 781M Nov 16 17:01 _2b.fdt
-rw-r--r-- 1 admin admin  17K Nov 16 17:01 _2b.fdx
-rw-r--r-- 1 admin admin  85M Nov 16 17:03 _2b.kdd
-rw-r--r-- 1 admin admin 148M Nov 16 17:03 _2b_Lucene80_0.dvd
.........................................
-rw-r--r-- 1 admin admin  401 Nov 16 17:03 segments_a
-rw-r--r-- 1 admin admin    0 Oct 16 16:27 write.lock

## zstd压缩等级为3 索引testzstd3   0 号分片
total 1.9G
-rw-r--r-- 1 admin admin  286 Nov 16 17:26 _8e.fdm
-rw-r--r-- 1 admin admin 758M Nov 16 17:26 _8e.fdt
-rw-r--r-- 1 admin admin  15K Nov 16 17:26 _8e.fdx
-rw-r--r-- 1 admin admin  84M Nov 16 17:29 _8e.kdd
-rw-r--r-- 1 admin admin 148M Nov 16 17:29 _8e_Lucene80_0.dvd
-rw-r--r-- 1 admin admin 3.5K Nov 16 17:29 
.........................................
-rw-r--r-- 1 admin admin  402 Nov 16 17:29 segments_9
-rw-r--r-- 1 admin admin    0 Nov 15 16:50 write.lock

## zstd压缩等级为6 索引testzstd6   0 号分片
total 1.9G
-rw-r--r-- 1 admin admin  286 Nov 16 16:56 _29.fdm
-rw-r--r-- 1 admin admin 742M Nov 16 16:56 _29.fdt
-rw-r--r-- 1 admin admin 9.8K Nov 16 16:56 _29.fdx
-rw-r--r-- 1 admin admin  86M Nov 16 16:58 _29.kdd
-rw-r--r-- 1 admin admin 148M Nov 16 16:58 _29_Lucene80_0.dvd
.........................................
-rw-r--r-- 1 admin admin  412 Nov 16 16:58 segments_a
-rw-r--r-- 1 admin admin    0 Oct 16 16:04 write.lock

## zstd压缩等级为9 索引testzstd9      0 号分片
total 1.9G
-rw-r--r-- 1 admin admin  286 Nov 16 17:21 _gp.fdm
-rw-r--r-- 1 admin admin 738M Nov 16 17:21 _gp.fdt
-rw-r--r-- 1 admin admin  13K Nov 16 17:21 _gp.fdx
-rw-r--r-- 1 admin admin  85M Nov 16 17:23 _gp.kdd
-rw-r--r-- 1 admin admin 149M Nov 16 17:23 _gp_Lucene80_0.dvd
.........................................
-rw-r--r-- 1 admin admin  402 Nov 16 17:23 segments_8
-rw-r--r-- 1 admin admin    0 Nov 15 16:50 write.lock


5.2 ES侧实现

理论上来说index.codec支持的压缩算法最好下沉到lucene代码中,目前我们并没有维护lucene代码,因此我们直接ES侧面代码实现。
zstd[1]算法是基于C++实现,而ES是基于java编写,因此借助开源的力量,引入zstd-jni来实现zstd压缩能力.

# zstd_jni版本 1.5.5-1
api "com.github.luben:zstd-jni:${versions.zstd_jni}"


在ES代码中编写自定义的index.codec;扩展CompressionMode压缩模式,自定义实现ZstdCompressor压缩和ZstdDecompressor解压缩方法,可以在这设定zstd的压缩等级以及控制读写数据块大小;最后通过java的spl机制实现加载我们自定义的压缩算法实现类
在server/src/main/resources/META-INF/services/org.apache.lucene.codecs.Codec文件中定义如下.

org.elasticsearch.index.codec.custom.ZstdCodec


注意⚠️:由于ES节点启动的时候,有security检查机制,因此我们需要在server/src/main/resources/org/elasticsearch/bootstrap/security.policy文件中添加代码权限授权策略

grant codeBase "${codebase.zstd-jni}" {
  permission java.lang.RuntimePermission "loadLibrary.*";
  permission java.lang.RuntimePermission "libzstd.*";
};


6 参考文档

[1] https://github.com/facebook/zstd
[2] https://lucene.apache.org/core/8_11_2/core/org/apache/lucene/codecs/lucene87/package-summary.html#package.description
[3] Y. Malkov, D. Yashunin,Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs(2016), IEEE Transactions on Pattern Analysis and Machine Intelligence
[4] https://www.elastic.co/guide/en/elasticsearch/reference/current/knn-search.html#approximate-knn
[5] https://mp.weixin.qq.com/s/awxgy9pSgv0lVPTfvzfxBw
[6] https://mp.weixin.qq.com/s/dmJwEpl6CWtv-MLdvR7g

作者:京东科技 杨松柏

来源:京东云开发者社区 转载请注明来源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/325367.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

屏幕录制软件有哪些?强烈推荐5款免费好用录屏软件

录制全屏视频是制作视频教程、评论、游戏等内容的绝佳方式。它可以包括您计算机屏幕上的任何活动以及您的音频和网络摄像头。特别是,屏幕录像机对喜欢创建软件评论的视频博主很有帮助。如果您是其中之一,那么好消息是您可以在网络上找到很多屏幕录制应用…

基于 IDEA 进行 Maven 依赖管理

一、依赖管理概念 Maven 依赖管理是 Maven 软件中最重要的功能之一。Maven 的依赖管理能够帮助开发人员自动解决软件包依赖问题,使得开发人员能够轻松地将其他开发人员开发的模块或第三方框架集成到自己的应用程序或模块中,避免出现版本冲突和依赖缺失等…

「工业遥测」图表控件LightningChart在制造加工业中的应用

LightningChart.NET完全由GPU加速,并且性能经过优化,可用于实时显示海量数据-超过10亿个数据点。 LightningChart包括广泛的2D,高级3D,Polar,Smith,3D饼/甜甜圈,地理地图和GIS图表以及适用于科学…

基于LLM大模型的结构化数据批量提取

在当今世界,越来越多的组织致力于数据驱动的决策。 然而,他们通常面临着从非结构化文本数据(例如客户评论或反馈)中提取有价值的见解的挑战。 这篇文章是为想要使用非结构化数据获得有用见解的数据科学家、分析师和决策者量身定制…

电子版试卷怎么打印出来?分享3个扫描小技巧

电子版试卷怎么打印出来?在日常学习中,将试卷打印成电子版可以带来很多方便。首先,电子版试卷方便存储和查找,可以随时随地使用电脑或手机进行阅读和复习。其次,电子版试卷方便进行标注和分析,可以使用不同…

提供多语种客户服务的正确方法:让你更接近全球客户

优质的客户支持是任何成功企业的核心。每位客户都希望得到全天候的及时响应。事实上,根据《哈佛商业评论》的研究报告,快速响应会促使人们在未来支付更多的费用。此外,在与全球客户打交道时,您的沟通必须超越语言障碍。用客户的语…

2-Linux-应用-部署icwp-Linux虚拟机【Django+Vue+Nginx+uwsgi+Linux】

本文概述 本文章讲述基于Linux CentOS 7系统(虚拟机),部署DjangoVue开发的前后端分离项目。 项目源码不开放,但是操作步骤可以借鉴。 该文章将项目部署在Linux虚拟机上,暂不使用Docker 相关指令尽量展示执行路径&am…

python下常用的爬虫模块

目录 一:requests 二:BeautifulSoup 三:Scrapy 四:Selenium 一:requests requests 是一个用于发送 HTTP 请求的 Python 库。它提供了简洁的 API 来发送各种类型的 HTTP 请求,如 GET、POST、PUT、DELETE…

多级缓存架构(二)Caffeine进程缓存

文章目录 一、引入依赖二、实现进程缓存1. 配置Config类2. 修改controller 三、运行四、测试 通过本文章&#xff0c;可以完成多级缓存架构中的进程缓存。 一、引入依赖 在item-service中引入caffeine依赖 <dependency><groupId>com.github.ben-manes.caffeine…

过滤器、拦截器、AOP、ControllerAdvcie执行顺序对比

过滤器Filter 简介 来自J2EE中的Servlet技术实现原理&#xff1a;基于servlet的函数回调实现只可以获取到请求中的request和response&#xff0c;无法获取到响应方法的信息可以拦截所有请求支持使用xml配置和注解配置应用场景&#xff1a;权限认证、敏感词检测、访问日志记录…

【Python机器学习系列】建立随机森林模型预测心脏疾病(完整实现过程)

这是Python机器学习系列原创文章&#xff0c;我的第200篇原创文章。 一、引言 对于表格数据&#xff0c;一套完整的机器学习建模流程如下&#xff1a; 针对不同的数据集&#xff0c;有些步骤不适用即不需要做&#xff0c;其中橘红色框为必要步骤&#xff0c;由于数据质量较高&…

【国产mcu填坑篇】华大单片机(小华半导体)一、SPI的DMA应用(发送主机)HC32L136

最近需要用华大的hc32l136的硬件SPIDMA传输&#xff0c;瞎写很久没调好&#xff0c;看参考手册&#xff0c;瞎碰一天搞通了。。。 先说下我之前犯的错误&#xff0c;也是最宝贵的经验&#xff0c;供参考 没多看参考手册直接写&#xff08;即使有点烂仍然提供了最高的参考价值。…

记edusrc一处信息泄露

一、信息收集 在搜索某一学校的资产时&#xff0c;找到了一处学工系统。 登录进去&#xff0c;发现有两种登陆方式&#xff0c;一种是统一身份认证&#xff0c;一种是DB认证。 统一身份认证是需要通过学生的学号和密码进行登录的&#xff0c;利用谷歌语法可以搜索到相关学…

多特征变量序列预测(四)Transformer-BiLSTM风速预测模型

目录 往期精彩内容&#xff1a; 前言 1 多特征变量数据集制作与预处理 1.1 导入数据 1.2 数据集制作与预处理 2 基于Pytorch的Transformer BiLSTM 预测模型 2.1 定义Transformer BiLSTM预测模型 2.2 设置参数&#xff0c;训练模型 3 模型评估与可视化 3.1 结果可视…

计算机视觉技术的应用前景如何?

计算机视觉技术在各个领域都有广阔的应用前景。以下是一些计算机视觉技术可能的应用&#xff1a; 1. 安全和监控&#xff1a;计算机视觉可以用于视频监控、入侵检测、人脸识别等安全和监控领域。它可以帮助监测和识别异常行为或威胁&#xff0c;并提供实时警报。 2. 自动驾驶和…

如何使用iPad通过Code App+cpolar实现公网地址远程访问vscode

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 1. 在iPad下载Code APP2.安装cpolar内网穿透2.1 cpolar 安装2.2 创建TCP隧道 3. iPad远程vscode4. …

BootStrap 实现轮播图

Bootstrap中文网 1、下载BootStrap 2、引入相关文件 在下载好的文件夹中找到下面的文件&#xff0c;复制到自己的项目中并引入 <link rel"stylesheet" href"bootstrap/css/bootstrap.min.css" /><script src"bootstrap/js/jquery.min.js…

中仕公考:2024年度河南省公务员考试公告发布!共招录9900人!

河南省2024年度统一考试录用公务员公告于今日发布&#xff0c;共计划招录9900人。 报名时间&#xff1a;1月18日9&#xff1a;00-1月24日17&#xff1a;00 笔试时间&#xff1a;3月16日-3月17日 报名方式&#xff1a;登录“河南人事考试网”进行网上报名 2024年省考29.5%的…

HTML--JavaScript--语法基础

变量与常量 这个基本上没啥问题 变量命名规则&#xff1a; 变量由字母、数字、下划线、$组成&#xff0c;且变量第一个字符不能为数字 变量不能是系统关键字和保留字 语法&#xff1a; var 变量名 值&#xff1b;所有Javacript变量都由var声明 定义赋值字符串&#xff1a; …

OpenHarmony——基于HDF驱动框架构建的Display驱动模型

概述 功能简介 LCD&#xff08;Liquid Crystal Display&#xff09;驱动编程&#xff0c;通过对显示器上电、初始化显示器驱动IC&#xff08;Integrated Circuit&#xff09;内部寄存器等操作&#xff0c;使其可以正常工作。 基于HDF&#xff08;Hardware Driver Foundation…