自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Apache Iceberg 中引入索引提升查詢(xún)性能

開(kāi)發(fā) 開(kāi)源
本文將討論火山引擎EMR團(tuán)隊(duì)針對(duì) Iceberg 組件的優(yōu)化思路,通過(guò)引入索引來(lái)提高查詢(xún)性能。

Apache Iceberg 是一種開(kāi)源數(shù)據(jù) Lakehouse 表格式,提供強(qiáng)大的功能和開(kāi)放的生態(tài)系統(tǒng),如:Time travel,ACID 事務(wù),partition evolution,schema evolution 等功能。

本文將討論火山引擎EMR團(tuán)隊(duì)針對(duì) Iceberg 組件的優(yōu)化思路,通過(guò)引入索引來(lái)提高查詢(xún)性能。

采用 Iceberg 構(gòu)建數(shù)據(jù)湖倉(cāng)

火山引擎 E-MapReduce(簡(jiǎn)稱(chēng) EMR)是火山引擎數(shù)智平臺(tái)(VeDI)旗下的云原生開(kāi)源大數(shù)據(jù)平臺(tái)產(chǎn)品, 提供了企業(yè)級(jí)的 Hadoop、Spark、Flink、Hive、Presto、Kafka、StarRocks、Doris、Hudi、Iceberg 等大數(shù)據(jù)生態(tài)組件,100% 開(kāi)源兼容,可以幫助企業(yè)快速構(gòu)建企業(yè)級(jí)大數(shù)據(jù)平臺(tái),降低運(yùn)維門(mén)檻。秉承業(yè)界領(lǐng)先的 EMR Stateless 理念,火山引擎 EMR 可以實(shí)現(xiàn)集群級(jí)別的彈性伸縮,即無(wú)業(yè)務(wù)需求時(shí)釋放集群,有業(yè)務(wù)需求時(shí)再拉起集群,配合智能化的冷熱數(shù)據(jù)分層存儲(chǔ)能力,助力企業(yè)在大數(shù)據(jù)基建領(lǐng)域進(jìn)一步降本提效。

基于火山引擎 EMR 產(chǎn)品,可以構(gòu)建數(shù)據(jù)湖倉(cāng)、近實(shí)時(shí)數(shù)倉(cāng)、實(shí)時(shí)數(shù)倉(cāng)等場(chǎng)景。例如,使用 Iceberg 構(gòu)建數(shù)據(jù)湖倉(cāng),從 ODS 到 DWD 等不同的分層進(jìn)行建模,將數(shù)據(jù) HFDS 或 TOS(火山引擎對(duì)象存儲(chǔ)產(chǎn)品)上,然后采用 Trino 或者 Spark 去做分析。

圖片

如何加速查詢(xún)性能,使其盡可能接近專(zhuān)門(mén)的分布式數(shù)倉(cāng)(如 ClickHouse 等),是需要思考和探究的問(wèn)題。

索引是業(yè)界常用的提高查詢(xún)性能的手段之一,針對(duì) Iceberg 我們也采用了增加索引的方式。對(duì)常用的列字段構(gòu)建 Index,在進(jìn)行 table scan 時(shí)利用 Index 只返回匹配的數(shù)據(jù),降低匹配數(shù)據(jù)量,從而大大提高查詢(xún)性能。

Iceberg 介紹

介紹 Iceberg Index 功能之前,我們先簡(jiǎn)單介紹下 Iceberg 的架構(gòu)。Iceberg 具有分層的元數(shù)據(jù)架構(gòu),如下如所示。

圖片

Spark、Presto、Flink 等多種引擎讀取 Iceberg 的數(shù)據(jù),就是利用分層的元數(shù)據(jù)找到 data file 列表。例如,Spark 引擎解析 SQL 語(yǔ)句,然后調(diào)用 Iceberg 的接口,獲取 data file 并進(jìn)行 task 切分。

圖片

在 Manifest file 中記錄了 data file 中字段的最大值和最小值。

"data_file": {
        "content": 0,
        "file_path": "hdfs://emr-cluster/warehouse/hive/db.db/sample/data/ts_day=2020-12-31/category=diamond/00000-0-220aa9a6-4530-499f-9450-da946d667624-00001.parquet",
        "file_format": "PARQUET",
        ......
        "lower_bounds": {
                "array": [{
                        "key": 1,
                        "value": "\u0006\u0000\u0000\u0000"
                }, {
                        "key": 2,
                        "value": "diamond"
                }, {
                        "key": 3,
                        "value": "\u0000\u0004ü??·\u0005\u0000"
                }]
        },
        "upper_bounds": {
                "array": [{
                        "key": 1,
                        "value": "\u0007\u0000\u0000\u0000"
                }, {
                        "key": 2,
                        "value": "diamond"
                }, {
                        "key": 3,
                        "value": "\u0000¨od?·\u0005\u0000"
                }]
        },
        ......
}

利用這些信息,可以進(jìn)行 data file 級(jí)別的初步過(guò)濾,把不符合條件的 data file 過(guò)濾掉,進(jìn)而減少一部分?jǐn)?shù)據(jù)的讀取。

實(shí)現(xiàn)索引的必要性

既然 Iceberg 已經(jīng)提供 data file 級(jí)別的過(guò)濾。為什么我們還需要引入索引呢?以下面例子進(jìn)行介紹,左邊兩個(gè)表格分別是 data file 文件里面的內(nèi)容,右邊表格是 data file 對(duì)應(yīng)的 manifest file。

圖片

針對(duì)SELECT * FROM table WHERE age > 50,利用 min-max 統(tǒng)計(jì)信息,很容易發(fā)現(xiàn) data file 1 中沒(méi)有滿(mǎn)足條件的數(shù)據(jù),因此 data file 1 就不會(huì)參與計(jì)算。

但是針對(duì)多維分析,如name = 'LiLy' AND age > 30,利用nameage的min-max的統(tǒng)計(jì)信息分別對(duì)條件name = 'LiLy'age > 30進(jìn)行判斷,得到 data file 1 和 data file 2 都滿(mǎn)足條件。然而,仔細(xì)分析 data file 1 和 data file 2 的數(shù)據(jù),并不存在符合條件的數(shù)據(jù),因此 min-max 過(guò)濾效果不太理想。所以通過(guò)引入合適的索引功能,可以提高 data skipping 的概率,提高查詢(xún)性能。

1.  首先探究索引類(lèi)型

索引類(lèi)型有多種,如 BloomFilter、Ribbon Filter、Dictionary Index、BitMap 等。為了滿(mǎn)足多維分析場(chǎng)景,我們選擇了[Range-Encoded BitMap]https://www.featurebase.com/blog/range-encoded-bitmaps ( Base-2, Bit-sliced Index),可適用于高基數(shù)場(chǎng)景,滿(mǎn)足=、<、>、IN、BETWEEN 等操作的多維分析。

例如,對(duì)上面的 name 和 age 兩列分別計(jì)算索引信息。由于 name 屬于字符串類(lèi)型,需要先進(jìn)行字典編碼再進(jìn)行計(jì)算索引信息。采用 Range-Encoded 技術(shù),根據(jù)數(shù)據(jù)的二進(jìn)制相關(guān)信息以及對(duì)應(yīng)的 pos 信息生成索引數(shù)據(jù)。利用索引數(shù)據(jù)分析得到,同時(shí)滿(mǎn)足name = 'LiLy'age > 30的數(shù)據(jù)不在同一行,恰好可利用 Range-Encoded 的交并運(yùn)算將數(shù)據(jù)進(jìn)行過(guò)濾掉,因此 data file 1 不用參與計(jì)算。

也就是說(shuō),BitMap 的交并運(yùn)算可以更好地在復(fù)雜過(guò)濾條件的情況下過(guò)濾掉更多的數(shù)據(jù)文件。

圖片

2.  接下來(lái)探究索引的粒度。

Iceberg 提供的 min-max,也是一種文件級(jí)別的索引。文件級(jí)別的索引就是根據(jù) filter 條件過(guò)濾掉不符合條件的 data file。文件級(jí)別的索引可適用于多種文件類(lèi)型,但這種粒度比較粗,只要 data file 中有一條數(shù)據(jù)符合條件,該 data file 中的數(shù)據(jù)就會(huì)全部讀取出來(lái)參與計(jì)算,從而影響 SQL 的查詢(xún)性能。

對(duì)于 Parquet、ORC 的文件格式,提供有 file chunk 的概念(row group or stripe),我們完全可以按照 row group / stripe 粒度,對(duì)數(shù)據(jù)進(jìn)行過(guò)濾。(為了方便描述,我們將 row group 和 stripe 統(tǒng)稱(chēng) split。)

如:SQL語(yǔ)句:SELECT * FROM table WHERE col_1> v1 AND col_2 = v2,其中對(duì) col_1 字段和 col_2 字段已構(gòu)建 Index 信息?,F(xiàn)在利用索引對(duì) SQL 語(yǔ)句作用。

圖片

SQL 語(yǔ)句解析后,將符合條件的 data file 列表進(jìn)行切分后,得到很多 split 的列表。利用索引,分析 split 中數(shù)據(jù)是否滿(mǎn)足條件,如果不滿(mǎn)足則跳過(guò)。如上圖 data file 列表切分后,得到數(shù)萬(wàn)級(jí)別數(shù)量的 split 列表。將索引數(shù)據(jù)作用在 split1,發(fā)現(xiàn) split1 中沒(méi)有同時(shí)col_1> v1 AND col_2 = v2滿(mǎn)足條件的數(shù)據(jù),該 split1 中的數(shù)據(jù)就不會(huì)參與計(jì)算。最后處理后,只得到了少量的 split 列表,數(shù)據(jù)過(guò)濾度達(dá)到 10% 以上,查詢(xún)性能有明顯提升。

因此,采用 row group / stripe 級(jí)別的細(xì)粒度索引,可以過(guò)濾大部分?jǐn)?shù)據(jù)。

細(xì)粒度索引實(shí)現(xiàn)邏輯

Iceberg 元數(shù)據(jù)中 manifest file 中除了提供 min-max 等統(tǒng)計(jì)信息,還提供有 split 相關(guān)信息:"split_offsets":{"array":[4,...]},極大方便我們實(shí)現(xiàn) row group / stripe 級(jí)別的細(xì)粒度索引。

  1. 提供索引的構(gòu)建 API

Iceberg 中提供構(gòu)建索引的 API,引擎端調(diào)用該 API 即可實(shí)現(xiàn)索引構(gòu)建功能。對(duì)于 Spark 3.3 及以上版本,已經(jīng)提供有索引的 SQL 語(yǔ)句,在 Iceberg 的 Spark 模塊實(shí)現(xiàn) Spark 提供的索引接口即可。

  1. 構(gòu)建索引

我們采用異步構(gòu)建索引,不影響主線(xiàn)任務(wù)。也提供了增量構(gòu)建索引功能,只對(duì) append 數(shù)據(jù)進(jìn)行構(gòu)建索引。調(diào)用 TableScan 讀取數(shù)據(jù),按照 data file 的 split offset 切分?jǐn)?shù)據(jù),進(jìn)行構(gòu)建索引,并保存索引數(shù)據(jù)和對(duì)應(yīng)的元數(shù)據(jù)信息。為了避免出現(xiàn)小文件存在,我們會(huì)進(jìn)行索引數(shù)據(jù)合并。

  1. 索引文件存儲(chǔ)

索引文件格式采用[puffin]https://iceberg.apache.org/puffin-spec/格式,這是一種二進(jìn)制格式。 Magic Blob? Blob? ... Blob? Footer

在 Footer 中保存每個(gè) blob 的元數(shù)據(jù)信息。索引構(gòu)建成功后,會(huì)生成類(lèi)似于下面內(nèi)容的文件。

圖片

索引帶來(lái)的收益

Range-Encoded BitMap 適用于多維分析場(chǎng)景,且 Ranger 范圍較小時(shí),效果非常明顯。下面我們基于 Spark 引擎性能測(cè)試。

  1. 構(gòu)造 1TB 的 SSB 測(cè)試數(shù)據(jù),分別在構(gòu)建 Index 前后,對(duì)以下用例進(jìn)行測(cè)試。
Q1: SELECT count(*) FROM lineorder WHERE  lo_ordtotalprice = 19665277
Q2: SELECT count(*) FROM lineorder WHERE  lo_ordtotalprice = 19665277 AND lo_revenue  = 2141624
Q3: SELECT count(*) FROM lineorder WHERE  lo_ordtotalprice = 19665277 AND lo_revenue  >=10304000
Q4: SELECT count(*) FROM lineorder WHERE  lo_ordtotalprice = 21877827 AND lo_revenue  >= 83800  AND lo_revenue  <= 103800
Q5: SELECT count(*) FROM lineorder WHERE  lo_ordtotalprice > 21877827 AND lo_revenue  >= 83800  AND lo_revenue  <= 93800
Q6: SELECT count(*) FROM lineorder WHERE lo_ordtotalprice >= 93565 AND   lo_ordtotalprice < 93909
Q7: SELECT count(*) FROM lineorder WHERE   lo_ordtotalprice >= 93565 AND   lo_ordtotalprice < 91003562 AND lo_revenue    >=904300 AND lo_revenue    <= 9904300

圖片

左圖展示了 7 條 SQL 語(yǔ)句分別在沒(méi)有 Index 和采用 Index 情況下的執(zhí)行時(shí)間。右圖展示采用 Index 后,7 條 SQL 語(yǔ)句讀數(shù)據(jù)的 split 數(shù)量。很明顯讀數(shù)據(jù)的 split 數(shù)量越少,Index 效果越好。最糟糕的情況,所有的 split 都參數(shù)計(jì)算,這時(shí)和沒(méi)有構(gòu)建索引的效果類(lèi)似。

  1. 采用 SSB 基準(zhǔn)測(cè)試

由于 SSB 提供的測(cè)試場(chǎng)景,和 Range-Encoded 有利的場(chǎng)景,不太匹配,所以 Index 的效果并沒(méi)有明顯的效果。但也不會(huì)比不采用 Index 的效果差。如下面左圖,分別是構(gòu)建索引前后,SQL 語(yǔ)句的執(zhí)行時(shí)間,構(gòu)建索引的優(yōu)勢(shì)并沒(méi)有體現(xiàn)出來(lái)。右圖中,可以看到所有的 split 都參與了計(jì)算。

圖片

總結(jié)

根據(jù)上面的介紹,這里總結(jié)下 Iceberg 中索引實(shí)現(xiàn)的一些特征:

  • 細(xì)粒度索引級(jí)別:提供 RowGroup/Stripe 級(jí)別的索引,可以更加精確的定位數(shù)據(jù)的查詢(xún)范圍,減少不必要數(shù)據(jù)輸入,從而提高查詢(xún)性能;
  • 索引作用于執(zhí)行端:查詢(xún)?nèi)蝿?wù)被分配多個(gè)執(zhí)行端,每個(gè)執(zhí)行端只判斷該節(jié)點(diǎn)上的 RowGroup/Stripe 數(shù)據(jù)是否符合即可;
  • 適配多種引擎:索引構(gòu)建后,可用于多種引擎;
  • 提供異步構(gòu)建 Index,從而不影響主業(yè)務(wù)的進(jìn)行;
  • 適用于高基數(shù) & 低基數(shù)場(chǎng)景,且占有存儲(chǔ)空間小。滿(mǎn)足范圍查詢(xún)、等值查詢(xún)等場(chǎng)景。且范圍越小,收益效果越明顯。
責(zé)任編輯:龐桂玉 來(lái)源: 字節(jié)跳動(dòng)技術(shù)團(tuán)隊(duì)
相關(guān)推薦

2024-09-19 08:09:37

MySQL索引數(shù)據(jù)庫(kù)

2023-12-14 12:56:00

MongoDB數(shù)據(jù)庫(kù)優(yōu)化

2022-09-16 13:53:14

ClouderaApache湖倉(cāng)

2024-12-11 07:59:02

2017-03-13 09:50:00

HadoopHive

2012-04-13 10:00:04

LINQ

2024-10-29 08:21:05

2018-06-07 08:54:01

MySQL性能優(yōu)化索引

2014-04-01 09:52:46

MySQL

2024-04-12 08:28:38

優(yōu)化查詢(xún)語(yǔ)句PostgreSQL索引

2014-04-28 10:17:01

2023-11-14 18:04:26

SQL語(yǔ)句性能

2020-11-27 06:58:24

索引

2024-11-15 10:45:56

2024-02-22 16:55:13

2024-01-02 18:01:12

SQLSELECT查詢(xún)

2011-08-24 11:22:38

SQL ServerUNION代替OR

2010-06-03 09:24:46

Oracle

2024-04-03 09:12:03

PostgreSQL索引數(shù)據(jù)庫(kù)

2024-05-23 10:58:49

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)