使用 Iceberg on Kubernetes 打造新一代雲原生數據湖

背景

大數據發展至今,按照 Google 2003年發佈的《The Google File System》第一篇論文算起,已走過17個年頭。惋惜的是 Google 當時並無開源其技術,「僅僅」是發表了三篇技術論文。因此回頭看,只能算是揭開了大數據時代的帷幕。隨着 Hadoop 的誕生,大數據進入了高速發展的時代,大數據的紅利及商業價值也不斷被釋放。現今大數據存儲和處理需求愈來愈多樣化,在後 Hadoop 時代,如何構建一個統一的數據湖存儲,並在其上進行多種形式的數據分析,成了企業構建大數據生態的一個重要方向。怎樣快速、一致、原子性地在數據湖存儲上構建起 Data Pipeline,成了亟待解決的問題。而且伴隨雲原生時代到來,雲原生天生具備的自動化部署和交付能力也正催化這一過程。本文就主要介紹如何利用 Iceberg 與 Kubernetes 打造新一代雲原生數據湖。node

何爲 Iceberg

Apache Iceberg is an open table format for huge analytic datasets. Iceberg adds tables to Presto and Spark that use a high-performance format that works just like a SQL table.

Apache Iceberg 是由 Netflix 開發開源的,其於2018年11月16日進入 Apache 孵化器,是 Netflix 公司數據倉庫基礎。Iceberg 本質上是一種專爲海量分析設計的表格式標準,可爲主流計算引擎如 Presto、Spark 等提供高性能的讀寫和元數據管理能力。Iceberg 不關注底層存儲(如 HDFS)與表結構(業務定義),它爲二者之間提供了一個抽象層,將數據與元數據組織了起來。nginx

Iceberg 主要特性包括:git

  • ACID:具有 ACID 能力,支持 row level update/delete;支持 serializable isolation 與 multiple concurrent writers
  • Table Evolution:支持 inplace table evolution(schema & partition),可像 SQL 同樣操做 table schema;支持 hidden partitioning,用戶無需顯示指定
  • 接口通用化:爲上層數據處理引擎提供豐富的表操做接口;屏蔽底層數據存儲格式差別,提供對 Parquet、ORC 和 Avro 格式支持

依賴以上特性,Iceberg 可幫助用戶低成本的實現 T+0 級數據湖。github

Iceberg on Kubernetes

傳統方式下,用戶在部署和運維大數據平臺時一般採用手動或半自動化方式,這每每消耗大量人力,穩定性也沒法保證。Kubernetes 的出現,革新了這一過程。Kubernetes 提供了應用部署和運維標準化能力,用戶業務在實施 Kubernetes 化改造後,可運行在其餘全部標準 Kubernetes 集羣中。在大數據領域,這種能力可幫助用戶快速部署和交付大數據平臺(大數據組件部署尤其複雜)。尤爲在大數據計算存儲分離的架構中,Kubernetes 集羣提供的 Serverless 能力,可幫助用戶即拿即用的運行計算任務。而且再配合離在線混部方案,除了可作到資源統一管控下降複雜度和風險外,集羣利用率也會進一步提高,大幅下降成本。web

咱們可基於 Kubernetes 構建 Hadoop 大數據平臺:

在近幾年大熱的數據湖領域,經過傳統 Hadoop 生態構建實時數據湖,受制於組件定位與設計,較爲複雜與困難。Iceberg 的出現使得依賴開源技術快速構建實時數據湖成爲可能,這也是大數據將來發展方向 - 實時分析、倉湖一體與雲原生。引入 Iceberg 後,總體架構變爲:

Kubernetes 負責應用自動化部署與資源管理調度,爲上層屏蔽了底層環境複雜性。Iceberg + Hive MetaStore + HDFS 實現了基於 Hadoop 生態的實時數據湖,爲大數據應用提供數據訪問及存儲。Spark、Flink 等計算引擎以 native 的方式運行在 Kubernetes 集羣中,資源即拿即用。與在線業務混部後,更能大幅提高集羣資源利用率。sql

如何構建雲原生實時數據湖

架構圖

  • 資源層:Kubernetes 提供資源管控能力
  • 數據層:Iceberg 提供 ACID、table 等數據集訪問操做能力
  • 存儲層:HDFS 提供數據存儲能力,Hive MetaStore 管理 Iceberg 表元數據,Postgresql 做爲 Hive MetaStore 存儲後端
  • 計算層:Spark native on Kubernetes,提供流批計算能力

建立 Kubernetes 集羣

首先經過官方二進制或自動化部署工具部署 Kubernetes 集羣,如 kubeadm,推薦使用騰訊雲建立 TKE 集羣

推薦配置爲:3 臺 S2.2XLARGE16(8核16G)實例shell

部署 Hadoop 集羣

可經過開源 Helm 插件或自定義鏡像在 Kubernetes 上部署 Hadoop 集羣,主要部署 HDFS、Hive MetaStore 組件。在騰訊雲 TKE 中推薦使用 k8s-big-data-suite 大數據應用自動化部署 Hadoop 集羣。

k8s-big-data-suite 是咱們基於生產經驗開發的大數據套件,可支持主流的大數據組件在 Kubernetes 上一鍵部署。部署以前請先按照要求作集羣初始化:apache

# 標識存儲節點,至少三個
$ kubectl label node xxx storage=true

部署成功後,連入 TKE 集羣查看組件狀態:json

$ kubectl  get po
NAME                                                   READY   STATUS      RESTARTS   AGE
alertmanager-tkbs-prometheus-operator-alertmanager-0   2/2     Running     0          6d23h
cert-job-kv5tm                                         0/1     Completed   0          6d23h
elasticsearch-master-0                                 1/1     Running     0          6d23h
elasticsearch-master-1                                 1/1     Running     0          6d23h
flink-operator-controller-manager-9485b8f4c-75zvb      2/2     Running     0          6d23h
kudu-master-0                                          2/2     Running     2034       6d23h
kudu-master-1                                          2/2     Running     0          6d23h
kudu-master-2                                          2/2     Running     0          6d23h
kudu-tserver-0                                         1/1     Running     0          6d23h
kudu-tserver-1                                         1/1     Running     0          6d23h
kudu-tserver-2                                         1/1     Running     0          6d23h
prometheus-tkbs-prometheus-operator-prometheus-0       3/3     Running     0          6d23h
superset-init-db-g6nz2                                 0/1     Completed   0          6d23h
thrift-jdbcodbc-server-1603699044755-exec-1            1/1     Running     0          6d23h
tkbs-admission-5559c4cddf-w7wtf                        1/1     Running     0          6d23h
tkbs-admission-init-x8sqd                              0/1     Completed   0          6d23h
tkbs-airflow-scheduler-5d44f5bf66-5hd8k                1/1     Running     2          6d23h
tkbs-airflow-web-84579bc4cd-6dftv                      1/1     Running     2          6d23h
tkbs-client-844559f5d7-r86rb                           1/1     Running     6          6d23h
tkbs-controllers-6b9b95d768-vr7t5                      1/1     Running     0          6d23h
tkbs-cp-kafka-0                                        3/3     Running     2          6d23h
tkbs-cp-kafka-1                                        3/3     Running     2          6d23h
tkbs-cp-kafka-2                                        3/3     Running     2          6d23h
tkbs-cp-kafka-connect-657bdff584-g9f2r                 2/2     Running     2          6d23h
tkbs-cp-schema-registry-84cd7cbdbc-d28jk               2/2     Running     4          6d23h
tkbs-grafana-68586d8f97-zbc2m                          2/2     Running     0          6d23h
tkbs-hadoop-hdfs-dn-6jng4                              2/2     Running     0          6d23h
tkbs-hadoop-hdfs-dn-rn8z9                              2/2     Running     0          6d23h
tkbs-hadoop-hdfs-dn-t68zq                              2/2     Running     0          6d23h
tkbs-hadoop-hdfs-jn-0                                  2/2     Running     0          6d23h
tkbs-hadoop-hdfs-jn-1                                  2/2     Running     0          6d23h
tkbs-hadoop-hdfs-jn-2                                  2/2     Running     0          6d23h
tkbs-hadoop-hdfs-nn-0                                  2/2     Running     5          6d23h
tkbs-hadoop-hdfs-nn-1                                  2/2     Running     0          6d23h
tkbs-hbase-master-0                                    1/1     Running     3          6d23h
tkbs-hbase-master-1                                    1/1     Running     0          6d23h
tkbs-hbase-rs-0                                        1/1     Running     3          6d23h
tkbs-hbase-rs-1                                        1/1     Running     0          6d23h
tkbs-hbase-rs-2                                        1/1     Running     0          6d23h
tkbs-hive-metastore-0                                  2/2     Running     0          6d23h
tkbs-hive-metastore-1                                  2/2     Running     0          6d23h
tkbs-hive-server-8649cb7446-jq426                      2/2     Running     1          6d23h
tkbs-impala-catalogd-6f46fd97c6-b6j7b                  1/1     Running     0          6d23h
tkbs-impala-coord-exec-0                               1/1     Running     7          6d23h
tkbs-impala-coord-exec-1                               1/1     Running     7          6d23h
tkbs-impala-coord-exec-2                               1/1     Running     7          6d23h
tkbs-impala-shell-844796695-fgsjt                      1/1     Running     0          6d23h
tkbs-impala-statestored-798d44765f-ffp82               1/1     Running     0          6d23h
tkbs-kibana-7994978d8f-5fbcx                           1/1     Running     0          6d23h
tkbs-kube-state-metrics-57ff4b79cb-lmsxp               1/1     Running     0          6d23h
tkbs-loki-0                                            1/1     Running     0          6d23h
tkbs-mist-d88b8bc67-s8pxx                              1/1     Running     0          6d23h
tkbs-nginx-ingress-controller-87b7fb9bb-mpgtj          1/1     Running     0          6d23h
tkbs-nginx-ingress-default-backend-6857b58896-rgc5c    1/1     Running     0          6d23h
tkbs-nginx-proxy-64964c4c79-7xqx6                      1/1     Running     6          6d23h
tkbs-postgresql-5b9ddc464c-xc5nn                       1/1     Running     1          6d23h
tkbs-postgresql-ha-pgpool-5cbf85d847-v5dsr             1/1     Running     1          6d23h
tkbs-postgresql-ha-postgresql-0                        2/2     Running     0          6d23h
tkbs-postgresql-ha-postgresql-1                        2/2     Running     0          6d23h
tkbs-prometheus-node-exporter-bdp9v                    1/1     Running     0          6d23h
tkbs-prometheus-node-exporter-cdrqr                    1/1     Running     0          6d23h
tkbs-prometheus-node-exporter-cv767                    1/1     Running     0          6d23h
tkbs-prometheus-node-exporter-l82wp                    1/1     Running     0          6d23h
tkbs-prometheus-node-exporter-nb4pk                    1/1     Running     0          6d23h
tkbs-prometheus-operator-operator-f74dd4f6f-lnscv      2/2     Running     0          6d23h
tkbs-promtail-d6r9r                                    1/1     Running     0          6d23h
tkbs-promtail-gd5nz                                    1/1     Running     0          6d23h
tkbs-promtail-l9kjw                                    1/1     Running     0          6d23h
tkbs-promtail-llwvh                                    1/1     Running     0          6d23h
tkbs-promtail-prgt9                                    1/1     Running     0          6d23h
tkbs-scheduler-74f5777c5d-hr88l                        1/1     Running     0          6d23h
tkbs-spark-history-7d78cf8b56-82xg7                    1/1     Running     4          6d23h
tkbs-spark-thirftserver-5757f9588d-gdnzz               1/1     Running     4          6d23h
tkbs-sparkoperator-f9fc5b8bf-8s4m2                     1/1     Running     0          6d23h
tkbs-sparkoperator-f9fc5b8bf-m9pjk                     1/1     Running     0          6d23h
tkbs-sparkoperator-webhook-init-m6fn5                  0/1     Completed   0          6d23h
tkbs-superset-54d587c867-b99kw                         1/1     Running     0          6d23h
tkbs-zeppelin-controller-65c454cfb9-m4snp              1/1     Running     0          6d23h
tkbs-zookeeper-0                                       3/3     Running     0          6d23h
tkbs-zookeeper-1                                       3/3     Running     0          6d23h
tkbs-zookeeper-2                                       3/3     Running     0          6d23h

注意

當前 TKE k8s-big-data-suite 1.0.3 在初始化 Postgresql 時,缺乏對 Hive transaction 的支持,從而致使 Iceberg 表建立失敗。請先執行如下命令手動修復:後端

$ kubectl  get pod | grep postgresql
tkbs-postgresql-5b9ddc464c-xc5nn                       1/1     Running            1          7d18h
$ kubectl exec tkbs-postgresql-5b9ddc464c-xc5nn -- psql -c "UPDATE pg_database SET datallowconn = 'false' WHERE datname = 'metastore';SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'metastore'"; kubectl exec tkbs-postgresql-5b9ddc464c-xc5nn -- psql -c "drop database metastore"; kubectl exec tkbs-postgresql-5b9ddc464c-xc5nn -- psql -c "create database metastore"
$ kubectl get pod | grep client
tkbs-client-844559f5d7-r86rb                           1/1     Running     7          7d18h
$ kubectl exec tkbs-client-844559f5d7-r86rb -- schematool -dbType postgres -initSchema

集成 Iceberg

當前 Iceberg 對 Spark 3.0 有較好支持,對比 Spark 2.4 有如下優點:

因此咱們默認採用 Spark 3.0 做爲計算引擎。Spark 集成 Iceberg,首先需引入 Iceberg jar 依賴。用戶可在提交任務階段手動指定,或將 jar 包直接引入 Spark 安裝目錄。爲了便於使用,咱們選擇後者。筆者已打包 Spark 3.0.1 的鏡像,供用戶測試使用:ccr.ccs.tencentyun.com/timxbxu/spark:v3.0.1。

咱們使用 Hive MetaStore 管理 Iceberg 表信息,經過 Spark Catalog 訪問和使用 Iceberg 表。在 Spark 中作以下配置:

spark.sql.catalog.hive_prod = org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.hive_prod.type = hive
spark.sql.catalog.hive_prod.uri = thrift://metastore-host:port

若使用 TKE k8s-big-data-suite 套件部署 Hadoop 集羣,可經過 Hive Service 訪問 Hive MetaStore:

$ kubectl  get svc | grep hive-metastore
tkbs-hive-metastore                                 ClusterIP      172.22.255.104   <none>           9083/TCP,8008/TCP                                             6d23h

Spark 配置變動爲:

spark.sql.catalog.hive_prod = org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.hive_prod.type = hive
spark.sql.catalog.hive_prod.uri = thrift://tkbs-hive-metastore

建立和使用 Iceberg 表

執行 spark-sql 進行驗證:

$ spark-sql --master k8s://{k8s-apiserver} --conf spark.kubernetes.container.image=ccr.ccs.tencentyun.com/timxbxu/spark:v3.0.1 --conf spark.sql.catalog.hive_prod=org.apache.iceberg.spaparkCatalog --conf spark.sql.catalog.hive_prod.type=hive --conf spark.sql.catalog.hive_prod.uri=thrift://tkbs-hive-metastore --conf spark.sql.warehouse.dir=hdfs://tkbs-hadoop-hdfs-nn/iceberg

各參數含義以下:

  • --master k8s://{k8s-apiserver}:Kubernetes 集羣地址
  • --conf spark.kubernetes.container.image=ccr.ccs.tencentyun.com/timxbxu/spark:v3.0.1:Spark Iceberg 鏡像
  • --conf spark.sql.catalog.hive_prod.type=hive:Spark Catalog 類型
  • --conf spark.sql.catalog.hive_prod.uri=thrift://tkbs-hive-metastore:Hive MetaStore 地址
  • --conf spark.sql.warehouse.dir=hdfs://tkbs-hadoop-hdfs-nn/iceberg:Spark 數據地址

建立 Iceberg 表:

spark-sql> CREATE TABLE hive_prod.db.table (id bigint, data string) USING iceberg;

查看是否建立成功:

spark-sql> desc hive_prod.db.table;
20/11/02 20:43:43 INFO BaseMetastoreTableOperations: Refreshing table metadata from new version: hdfs://10.0.1.129/iceberg/db.db/table/metadata/00000-1306e87a-16cb-4a6b-8ca0-0e1846cf1837.metadata.json
20/11/02 20:43:43 INFO CodeGenerator: Code generated in 21.35536 ms
20/11/02 20:43:43 INFO CodeGenerator: Code generated in 13.058698 ms
id    bigint
data    string
# Partitioning
Not partitioned
Time taken: 0.537 seconds, Fetched 5 row(s)
20/11/02 20:43:43 INFO SparkSQLCLIDriver: Time taken: 0.537 seconds, Fetched 5 row(s)

查看 HDFS 是否存在表信息:

$ hdfs dfs -ls /iceberg/db.db
Found 5 items
drwxr-xr-x   - root supergroup          0 2020-11-02 16:37 /iceberg/db.db/table

查看 Postgresql 是否存在表元數據信息:

$ kubectl get pod | grep postgresql
tkbs-postgresql-5b9ddc464c-xc5nn                       1/1     Running     1          7d19h$ kubectl exec tkbs-postgresql-5b9ddc464c-xc5nn -- psql -d metastore -c 'select * from "TBLS"'

向 Iceberg 表插入數據:

spark-sql> INSERT INTO hive_prod.db.table VALUES (1, 'a'), (2, 'b');

查看是否插入成功:

spark-sql> select * from hive_prod.db.table;
...
1    a
2    b
Time taken: 0.854 seconds, Fetched 2 row(s)
20/11/02 20:49:43 INFO SparkSQLCLIDriver: Time taken: 0.854 seconds, Fetched 2 row(s)

查看 Kubernetes 集羣 Spark 任務運行狀態:

$ kubectl get pod | grep spark
sparksql10-0-1-64-ed8e6f758900de0c-exec-1              1/1     Running            0          86s
sparksql10-0-1-64-ed8e6f758900de0c-exec-2              1/1     Running            0          85s

Iceberg Spark 支持的更多操做可見:https://iceberg.apache.org/sp...

經過以上步驟,咱們便可在 Kubernetes 上快速部署生產可用的實時數據湖平臺。

總結

在這個數據量爆炸的時代,傳統數倉已較難很好知足數據多樣性需求。數據湖憑藉開放、低成本等優點,逐漸居於主導地位。而且用戶和業務也再也不知足於滯後的分析結果,對數據實時性提成了更多要求。以 Iceberg、Hudi、Delta Lake 爲表明的開源數據湖技術,填補了這部分市場空白,爲用戶提供了快速搭建適用於實時 OLAP 的數據湖平臺能力。另外雲原生時代的到來,更是大大加速了這一過程。大數據毋庸置疑正朝着實時分析、計算存儲分離、雲原生,乃至於湖倉一體的方向發展。大數據基礎設施也正由於 Kubernetes、容器等雲原生技術的引入,正發生巨大變革。將來大數據會更好的「長於雲上」,Bigdata as a Service 的時代,相信很快會到來。

參考材料

【騰訊雲原生】雲說新品、雲研新術、雲遊新活、雲賞資訊,掃碼關注同名公衆號,及時獲取更多幹貨!!
相關文章
相關標籤/搜索