网站首页 > 博客文章 正文
1. 背景
在大数据分析领域中,ElasticSearch常常被作为日志存储分析引擎,快速构建日志数据分析服务。但随着日志量的不断增加,ES在大规模日志存储上面的一些问题逐渐暴露出来:
1. ES 对服务器的内存磁盘性能要求较高,随着数据量增加,投入的服务器成本越来越高,不支持直接查询存储于S3的历史快照数据,无法做到存算分离;
2. ES 运维较为复杂,成本高;
3. SQL支持不完善,在聚合查询方面与传统OLAP引擎性能差距较大;
4. 与数仓数据脱节,不方便与Hive/Mysql中的数据关联分析;
针对以上几个问题,在智汇云的数仓产品中,在Iceberg基础上,开出了一个新的引擎 — Archer,将倒排索引机制引入,从而使奇麟数仓分析工具具备了全文检索的能力。由新版Archer引擎加持的数仓具备了以下几个特点:
1. 正排数据和倒排索引文件直接存储于HDFS/S3中,存储横向扩展;
2. 通过LocalCache本地缓存数据,加速索引的访问和检索速度;
3. 计算引擎构建于容器之上,支持算力的灵活弹性扩缩容,运维简单;
4. SQL支持完善,列式存储数据,OLAP查询性能强;
5. 灵活的倒排索引构建方式,满足全文检索和json数据检索场景;
6. 支持联邦查询,方便与Hive/Mysql中的数据进行关联查询;
2. 设计
Archer设计中采用了Parquet格式存储数据文件,采用Tantivy技术构建倒排索引。Tantivy启发于Lucene,用于构建搜索引擎,Tantivy对减少IO请求次数做了优化,因此更适合存储于HDFS/S3。
2.1. 索引类型
支持text/json/json_text/ip/datetime/raw六种类型索引
? text,对varchar字段进行分词并索引
? json,对varchar字段按Json object进行解析并索引,类似ES的嵌套文档
? json_text,对varchar字段按Json object进行解析,并对json内的string value进行分词,然后构建索引
? ip,对varchar字段按照ip格式解析成字节数组进行索引,支持范围查询
? datetime,对timestamp字段进行索引,支持范围查询
? raw,索引原值,支持boolean/int/long/float/double/varchar/varbinary字段类型
2.2. 架构
存算分离
与Lucene的LuceneDirectory类似,Tantivy也支持通过实现TantivyDirectory,来支持对索引文件的自定义读写模式。通过实现TantivyDirectory,可以获得直接在HDFS/S3之上读写索引文件的能力,再通过LocalCache提高了IO性能,减少对HDFS/S3的请求。
通过查询倒排索引,可以获得满足条件的doc id列表(与Parquet文件内行号一致),再通过Parquet文件内的PageOffset对Page进行裁剪,以减少IO请求,同时也避免了大量的数据解析和计算工作。默认情况下,每个Page保存1MB数据。
奇麟数仓倒排索引功能的框架如下图所示:
Parquet Page裁剪图示:
2.3. 查询
在奇麟数仓架构中,我们使用Trino作为查询引擎,需要在建表/查询上做一些兼容性工作。
? 支持查询倒排索:为了避免对Trino核心代码进行修改,我们对包含倒排索引的表,添加了一个varchar类型的隐藏列"$inverted_index_query",当where条件包含该列时,就自动获得了Trino的谓词下推能力,从而把Query提交到倒排索引。因为是enforced predicate,此时Trino不需要connector返回该隐藏列。
? 支持OR逻辑:此时Trino需要connector返回该隐藏列,这里我们在查询完倒排索引后,并不会过滤数据,而是把符合条件的行填充成query字符串本身,不符合条件的行填充成NULL
建表语句例子如下:
查询语句例子如下:
2.4. 优化
2.4.1. 文件裁剪
Tantivy会为每个segment创建最少8个文件,其中有4个是我们的场景下完全用不上的,比如fieldnorm/store/fast等文件,这类文件用于支持文档评分和列式存储。在实际的检索过程中,这些文件并不会被读取具体内容,但会增加HDFS/S3上的小文件数量,且会在加载所有segment的时候自动加载元数据部分,进一步提高了检索延迟。我们在实现TantivyDirectory的时候,会忽略这些文件的写入请求,并在读取的时候,返回符合文件规范的静态数据。
2.4.2. 优化内存
我们需要为每个parquet构建一个倒排索引,为了避免小文件过多的问题,一般单个parquet文件的大小在一定范围内是越大越好的,在写入parquet文件的过程中,内存占用的大小就是单个RowGroup的大小。但构建倒排索引文件需要对数据进行排序,在不进行外排序的情况下,需要把全量数据都缓存在内存,因此可能导致进程内存占用过多而崩溃。因此我们对单个索引segment的内存占用进行了限制,当内存超过限制时,会在后台提前写到外部存储,然后再开一个新的segment写新数据。最后关闭parquet的时候,会根据segment数量来决定是否进一步执行segment合并,来优化查询性能。
2.4.3. 预读取
文件内的term/doc id/pos id等数据都是经过排序的,因此在进行范围检索和索引文件合并的时候,有顺序读取文件的特征,但Tantivy目前的实现没有考虑这个问题,在这些场景下,会有非常多小而连续的IO请求。我们在实现TantivyDirectory的时候,对这类操作添加了preload+cache的操作,读取数据时候,会优先查看cache是否已经满足要求,如果不满足,则会在实际请求之上额外请求一部分数据并缓存,这样可以明显减少对远程存储的请求次数,性能会有 100x ~ 1000x 的提升。
2.4.4. 合并IO
对Parquet Page进行裁剪之后,可能会有不连续,但间隔比较小的Page请求。我们对间隔较小的请求进行合并,在读放大和IO次数间做了一些平衡,以减少读延迟。
2.4.5. 动态Split分配
Trino默认按128MB切分文件分发Split,如果以这种方式分发Split,同一个倒排索引会被加载和查询多次。同时,倒排索引一般可以过滤掉大部分RowGroup和Page,也就不需要通过切分文件来增加并行处理能力。因此我们添加了一种动态Split分配模式,在分配Split的时候,如果检查到倒排索引查询,将不再切分文件,而是把整个文件作为一个Split来分发。该行为可以在session级别随时调整。
2.4.6. 序列化
Tantivy采用Rust开发,而Trino采用Java开发,因此需要通过JNI交换数据。为了提高序列化和反序列性能,我们采用Arrow作为内存数据格式,避免了反复的序列化和反序列化操作。
3. 测试结果
我们使用amazon_reviews数据对全文检索进行了测试,使用内部数据对json检索进行了测试,并记录了查询时间和扫描数据量。对比iceberg connector,在使用倒排索引时,可以显著减少查询时间和扫描数据量。
3.1. 全文检索
SQL查询代码如下:
archer,1.52秒,扫描122KB数据
iceberg,15.64秒,扫描7.02GB数据
3.2. Json检索
SQL如下:
archer,1.36秒,扫描14.6MB数据
iceberg,14.37秒,扫描454MB数据
了解更多奇麟数仓大数据产品,请关注“360智汇云”
猜你喜欢
- 2024-10-27 MySQL 为什么使用数据索引能提高效率
- 2024-10-27 Elasticsearch 在地理信息空间索引的探索和演进
- 2024-10-27 终于有人把Elasticsearch原理讲透了(二)
- 2024-10-27 PostgreSQL技术内幕6:PostgreSQL索引技术
- 2024-10-27 ElasticSearch的分布式架构原理(吐血整理!)
- 2024-10-27 「漫画」elasticsearch原理就是这么简单(上)
- 2024-10-27 Elasticsearch读书笔记(二)(elasticsearch 书推荐)
- 2024-10-27 搜索引擎原理系列教程:收录、索引、排名
- 2024-10-27 什么是预处理: 预处理简称为“索引”
- 2024-10-27 陈年SEO:解密百度SEO排序影响因素
你 发表评论:
欢迎- 367℃用AI Agent治理微服务的复杂性问题|QCon
- 359℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 358℃初次使用IntelliJ IDEA新建Maven项目
- 351℃Maven技术方案最全手册(mavena)
- 348℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 346℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 345℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 342℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)