特性快閃:使用 Databend 玩轉(zhuǎn) Iceberg

幾周前,Databricks 和 Snowflake 召開了各自的年度大會,除了今年一路持續(xù)走紅的 AI ,數(shù)據(jù)湖/數(shù)據(jù)倉庫技術(shù)的發(fā)展仍然值得關(guān)注,畢竟數(shù)據(jù)才是基本盤。Apache Iceberg 無疑是數(shù)據(jù)湖方案的大贏家,Databricks 新推出的 UniForm 為以 Apache Iceberg 和 Hudi 表格式讀取 Delta 中的數(shù)據(jù)提供了進(jìn)一步的支持。而 Snowflake 也適時推出了 Iceberg Tables 更新,宣稱要進(jìn)一步打破數(shù)據(jù)孤島。
Databend 最近幾個月正在推動的重要新特性之一就是支持讀取 Apache Iceberg 表格式的數(shù)據(jù),盡管還沒有完全落地,但已經(jīng)取得了不錯的進(jìn)展。
今天這篇文章旨在為大家提前演示這一新特性 —— 使用 Databend 掛載并查詢 Iceberg Catalog ,我們將介紹 Iceberg、表格式的一些核心概念,并且試圖介紹 Databend 的解決方案(包括 Databend 的多源數(shù)據(jù)目錄能力和以 Rust 從頭實現(xiàn)的 IceLake)。當(dāng)然,作為演示,我們將會提供完整的 workshop ,供大家嘗鮮體驗。
Apache Iceberg
時至今日,越來越多的數(shù)據(jù)進(jìn)入云端,并且存儲在對象存儲之中,但這并不能完全適應(yīng)現(xiàn)代分析的需求。這里有兩個問題需要解決:第一個是數(shù)據(jù)以何種形式組織,也就是說,如何得到更結(jié)構(gòu)化的數(shù)據(jù)存儲。第二個問題還要更進(jìn)一步,如何為用戶提供更廣泛的一致性保證以及業(yè)務(wù)中需要的模式信息,以及更多適應(yīng)現(xiàn)代分析負(fù)載的高級特性。
數(shù)據(jù)湖往往會關(guān)注并解決第一個問題,而表格式則會致力于為第二個問題提供解決方案。
Apache Iceberg 是一種高性能的開放表格式,專為大規(guī)模分析工作負(fù)載而設(shè)計,簡單而又可靠。同時支持 Spark、Trino、Flink、Presto、Hive 和 Impala 等查詢引擎,并且具備模式演變(Full Schema Evolution)、時間旅行和回滾等殺手級特性。另外,Apache Iceberg 的數(shù)據(jù)分片和明確定義的數(shù)據(jù)結(jié)構(gòu)還使得對數(shù)據(jù)源進(jìn)行并發(fā)訪問更加安全、可靠和方便。
如果你對 Iceberg 感興趣,我們也推薦閱讀像 Docker, Spark, and Iceberg: The Fastest Way to Try Iceberg!(https://tabular.io/blog/docker-spark-and-iceberg/) 這樣的文章進(jìn)行探索。
表格式初探
表格式(Table Format)是一種利用文件集合存儲數(shù)據(jù)的規(guī)范。它主要包含以下三個部分的定義:
如何將數(shù)據(jù)存儲在文件中
如何存儲相關(guān)文件的元數(shù)據(jù)
如何存儲有關(guān)表本身的元數(shù)據(jù)
表格式的文件通常存儲在 HDFS、S3 或 GCS 這樣的底層存儲服務(wù)中,上層則會對接 Databend、Snowflake 等數(shù)據(jù)倉庫。相比 CSV 或 Parquet ,表格式提供了表形式的標(biāo)準(zhǔn)的結(jié)構(gòu)化數(shù)據(jù)定義,無需加載到數(shù)據(jù)倉庫中就可以使用。
盡管表格式領(lǐng)域還有像 Delta Lake 和 Apache Hudi 這樣的強(qiáng)勁對手,但這篇文章是關(guān)于 Apache Iceberg 的,所以,還是讓我們把目光轉(zhuǎn)向 Apache Iceberg ,一起了解一下它的底層文件組織結(jié)構(gòu)。

上圖中的 s0 、s1 代表的是表的快照信息(snapshot),也就是表在某個時刻的狀態(tài)。每次 commit 都會生成一個快照,每個快照都會對應(yīng)一個清單列表(manifest list),而每個清單列表可以維護(hù)多個清單文件(manifest file)的地址與統(tǒng)計信息,包括路徑和分區(qū)范圍等。清單文件中會記錄當(dāng)前操作生成數(shù)據(jù)文件(data file)的地址和統(tǒng)計信息,比如列中的最大值最小值和數(shù)據(jù)行數(shù)等。
Databend 多源數(shù)據(jù)目錄
要想在 Databend 中實現(xiàn) Iceberg 集成,頭一件是 Databend 的多源數(shù)據(jù)目錄能力。多源數(shù)據(jù)目錄將會允許將原本由其他數(shù)據(jù)分析系統(tǒng)所管理的數(shù)據(jù)掛載到 Databend 。
從設(shè)計之初,Databend 的目標(biāo)就是成為云原生的 OLAP 數(shù)據(jù)倉庫,并考慮到多源數(shù)據(jù)處理的問題。Databend 中的數(shù)據(jù)按三層進(jìn)行組織:"catalog -> database -> table"
,"catalog"
作為數(shù)據(jù)最大一層,會包含所有的數(shù)據(jù)庫和表。
團(tuán)隊在此基礎(chǔ)上設(shè)計并實現(xiàn)對 Hive 和 Iceberg 數(shù)據(jù)目錄的支持,提供配置文件和 CREATE CATALOG
語句多種掛載形式,從而支持對相關(guān)數(shù)據(jù)進(jìn)行查詢。
要想掛載數(shù)據(jù)位于 S3 中的 Iceberg Catalog,只需要執(zhí)行下面的 SQL 語句:
IceLake - Apache Iceberg 的純 Rust 實現(xiàn)
盡管 Rust 生態(tài)中近年來涌現(xiàn)出不少數(shù)據(jù)庫、大數(shù)據(jù)分析相關(guān)的新項目,但 Rust 生態(tài)中仍然缺乏成熟的 Apache Iceberg 綁定,這為 Databend 集成 Iceberg 制造了不少困難。
Databend Labs 支持并發(fā)起的 IceLake 旨在填補(bǔ)這一空白,并致力于建立一個開放生態(tài)系統(tǒng):
用戶可以從 任何 存儲服務(wù)(如 s3、gcs、azblob、hdfs 等)讀寫 Iceberg 表。
任何 數(shù)據(jù)庫都可以集成 "
icelake"
,以支持讀寫 Iceberg 表。提供原生的 "
arrow"
格式互轉(zhuǎn)換的能力。提供多種語言綁定,使其他語言可以享有 Rust 核心帶來的 Iceberg 生態(tài)支持。
當(dāng)前 IceLake 已經(jīng)支持讀取 Apache Iceberg 存儲服務(wù)中的數(shù)據(jù)(Parquet 格式)。而 Databend 的 Iceberg 數(shù)據(jù)目錄能力正是由 IceLake 支撐的,其設(shè)計與實現(xiàn)在和 Databend 集成中得到了驗證。
此外,我們還與 Iceberg 社區(qū)成員攜手發(fā)起并參與 iceberg-rust 項目,旨在將 icelake 中 iceberg 相關(guān)的實現(xiàn)貢獻(xiàn)給上游,目前第一個版本正緊鑼密鼓的開發(fā)中,歡迎關(guān)注https://github.com/apache/iceberg-rust 。
Workshop:體驗 Databend 的 Iceberg 能力
在這個 Workshop 中,我們將會展示如何準(zhǔn)備 Iceberg 表格式的數(shù)據(jù),并以 Catalog 的形式將其掛載到 Databend 上,并執(zhí)行一些基本的查詢。相關(guān)的文件和配置可以在 "PsiACE/databend-workshop"
中找到。
如果你本身有一些符合 Iceberg 表格式的數(shù)據(jù)存放在 OpenDAL 支持的存儲服務(wù)中,我們更推薦使用 Databend Cloud ,這樣你就可以跳過繁瑣的服務(wù)部署和數(shù)據(jù)準(zhǔn)備流程,輕松上手 Iceberg Catalog 。
啟動服務(wù)
為了簡化 Iceberg 的服務(wù)部署和數(shù)據(jù)準(zhǔn)備問題,我們將會使用 Docker 和 Docker Compose ,你需要先安裝這些組件,然后編寫 "docker-compose.yml"
文件。
在上述的配置文件中,我們使用 MinIO 作為底層存儲,Iceberg 提供表格式能力,至于 spark-iceberg ,可以幫助我們準(zhǔn)備一些預(yù)置數(shù)據(jù)并執(zhí)行轉(zhuǎn)換操作。
接下來,我們在 "docker-compose.yml"
文件對應(yīng)的目錄下啟動所有服務(wù):
數(shù)據(jù)準(zhǔn)備
在這個 Workshop 中,我們計劃使用 NYC Taxis 數(shù)據(jù)集(紐約出租車搭乘數(shù)據(jù)),在 spark-iceberg 中已經(jīng)內(nèi)置了 Parquet 數(shù)據(jù),我們只需要將其轉(zhuǎn)化為 Iceberg 格式。
首先啟用 pyspark-notebook :
接下來我們就可以在 "http://localhost:8888"
使用 Jupyter Notebook :

這里我們需要運行一小段程序,實施數(shù)據(jù)轉(zhuǎn)換的操作:
第一行將會讀取 Parquet 數(shù)據(jù),而第二行將會將其轉(zhuǎn)儲為 Iceberg 格式。
為了驗證數(shù)據(jù)是否成功轉(zhuǎn)換,我們可以訪問位于 "http://localhost:9001"
的 MinIO 實例,可以看到數(shù)據(jù)是按之前描述的 Iceberg 底層文件組織形式進(jìn)行管理的。

部署 Databend
這里我們使用手動部署單節(jié)點 Databend 服務(wù)的形式,總體上部署過程可以參考 Databend 官方文檔 ,需要注意的一些細(xì)節(jié)如下:
首先是需要為日志和 Meta 數(shù)據(jù)準(zhǔn)備相關(guān)的目錄
其次,因為默認(rèn)的 "
admin_api_address"
已經(jīng)被前面的服務(wù)占用掉,所以需要編輯 "databend-query.toml"
進(jìn)行一些修改避免沖突:
另外,我們還需要根據(jù) Docs | Configuring Admin Users (https://databend.rs/doc/sql-clients/admin-users) 配置管理員用戶,由于只是一個 workshop ,這里選擇最簡單的方式,只是取消 "
[[query.users]]"
字段以及 root 用戶的注釋:
由于我們本地部署 MinIO ,沒有設(shè)置證書加密,需要使用不安全的 HTTP 協(xié)議加載數(shù)據(jù),所以還需要更改 "
databend-query.toml"
配置文件以允許這一行為。在生產(chǎn)服務(wù)中請盡可能避免開啟它:
接下來就可以正常啟動 Databend :

我們強(qiáng)烈推薦你使用 BendSQL (https://databend.rs/doc/sql-clients/bendsql) 作為客戶端,當(dāng)然,我們也支持像 MySQL Client 和 HTTP API 等多種訪問形式。
掛載 Iceberg Catalog
根據(jù)之前的配置文件,只需要執(zhí)行下述 SQL 就可以一鍵掛載 Iceberg Catalog 。
為了驗證是否成功,我們可以執(zhí)行 "SHOW CATALOGS"
查看:

當(dāng)然,我們也支持了 "SHOW DATABASES"
和 "SHOW TABLES"
語句,之前轉(zhuǎn)換數(shù)據(jù)時的 "nyc.taxis"
對應(yīng)在 MinIO 中是二級目錄,而在 Databend 則會映射到數(shù)據(jù)庫和表。


執(zhí)行查詢
數(shù)據(jù)已經(jīng)掛載,那么就讓我們執(zhí)行一些簡單的查詢:
首先是對數(shù)據(jù)進(jìn)行行數(shù)統(tǒng)計,可以看到一共掛載了 200 萬行數(shù)據(jù)到 Databend:

讓我們從其中幾列試著取一些數(shù)據(jù)出來:

下面的查詢可以幫助我們探索乘客數(shù)量和旅程距離之間的相關(guān)性,這里只取其中 10 條結(jié)果:

總結(jié)
在這篇文章中,我們介紹到 Apache Iceberg 表格式和 Databend 的相關(guān)解決方案,并且提供了一個相對完整的 workshop 供大家探索。
不難看出,盡管目前我們只為 Iceberg Catalog 提供了單機(jī)模式的目錄掛載能力,但 Databend 可以勝任一些基本的查詢處理任務(wù)。也歡迎大家在自己感興趣的數(shù)據(jù)上進(jìn)行嘗試,并給我們提供一些反饋。