Apache Kyuubi 高可用的雲原生實現

danny_2018發表於2022-10-27

Apache Kyuubi 是一個分散式的、多租戶閘道器,用於在 Lakehouse 上提供 Serverless SQL。Kyuubi 最初是基於 Apache Spark 構建的相容 HiveServer2 協議的大規模資料處理和分析工具,目前已經支援 Flink/Trino/Hive/Doris 等引擎。Kyuubi 致力於成為一個開箱即用的資料倉儲和資料湖工具,讓任何人都可以輕鬆高效地使用各種計算引擎,在瞭解 SQL 的基礎上可以像處理普通資料一樣處理大資料。在 Kyuubi 架構中,有三個主要的特性:

1. 多租戶,Kyuubi 透過統一的身份驗證授權層為資源獲取和資料 / 後設資料訪問提供端到端的多租戶支援。2. 高可用,Kyuubi 透過 ZooKeeper 提供負載均衡,它提供了企業級的高可用性,以及無限的客戶端高併發。3. 多個工作負載,Kyuubi 可以透過一個平臺、一個資料副本和一個 SQL 介面輕鬆支援多個不同的工作負載。

在雲原生場景中,額外部署和維護 ZooKeeper 代價很高,我們是否有云原生的方案可以替代?

基於 ZooKeeper 的高可用實現

Kyuubi-ha 模組下的 DiscoveryClient 介面中包含了服務註冊和發現所需要實現的所有的介面(基於 master 分支),大致包含:客戶端的建立和關閉、節點的建立和刪除、節點是否存在、註冊和登出服務、獲取分散式鎖、獲取引擎地址等。下圖簡要展示了租戶連線到 Kyuubi 的過程中與 discovery 互動的步驟。

當我們啟動 Kyuubi server 或者拉起 engine 時,ServiceDiscovery 會在 ZooKeeper 中註冊相關資訊,租戶獲取到可用 server 列表後,根據策略選擇 server 開啟 session,在開啟 session 的過程中,Kyuubi server 會根據使用者連線時制定的引擎共享策略在 ZooKeeper 中查詢是否有可用的 engine,如果沒有則拉起一個新的 engine 並連線。

在整個過程中,主要是用了 ZooKeeper 的兩個核心功能:服務註冊和分散式鎖。

服務註冊

ZooKeeper 提供 4 種建立節點的方式:

1.PERSISTENT(持久化)即使客戶端與 ZooKeeper 斷開連線,該節點依然存在,只要不手動刪除該節點,將永遠存在;2.PERSISTENT_SEQUENTIAL(持久化順序編號目錄節點)在持久化目錄節點基礎上,ZooKeeper 給該節點名稱進行順序編號;3.EPHEMERAL(臨時目錄節點)客戶端與 ZooKeeper 斷開連線後,該節點就會被刪除;4.EPHEMERAL_SEQUENTIAL(臨時順序編號目錄節點)在臨時目錄節點基礎上 ZooKeeper 給該節點名稱進行順序編號

Kyuubi 中 server 和 engine 的服務註冊基於 EPHEMERAL_SEQUENTIAL 實現,在服務啟動時建立臨時節點,退出時斷開連結,ZooKeeper 自動刪除對應節點。同時,服務啟動時會建立 watcher 監聽註冊的臨時節點,當該節點被刪除時,會優雅的停止服務。

分散式鎖

如上圖,當兩個客戶端同時請求同一個引擎時,如果引擎不存在,在不加鎖狀態下,我們會啟動兩個 engine,後續再有新連線時,總會連線到後註冊的引擎,先註冊的引擎會長時間空閒。因此,在建立新的引擎時,透過對對應節點新增分散式鎖,先獲取到鎖的客戶端建立引擎,後獲取鎖的客戶端直接使用已啟動的引擎。

基於 ETCD 的高可用雲原生實現

上圖是雲原生場景下,租戶連線 Kyuubi 的過程,其中涉及到雲原生應用中比較關鍵的元件,ETCD 和 MetalLB。其中,ETCD 負責引擎服務註冊和發現,MetalLB 則為 Kyuubi server 提供負載均衡能力。

ETCD 既然支援引擎的註冊和發現,為什麼不像 ZooKeeper 一樣同時支援 Server 的高可用呢?

這個我們主要從客戶使用方面考量,我們通常使用的 beeline、jdbc 驅動都支援基於 ZooKeeper 的服務發現,但並不支援 ETCD。如果將 server 註冊到 ETCD 中,我們沒有辦法相容現有的客戶端,需要為租戶提供額外的驅動。同時,我們也知道在雲原生場景中 MetalLB 可以透過單個 IP 為下面的 pod(deployment)提供負載均衡。經過考量最終我們選擇 ETCD+MetalLB 的方式。

關於 ETCD

ETCD 是用於共享配置和服務發現的分散式,一致性的 KV 儲存系統,是 CoreOS 公司發起的一個開源專案,授權協議為 Apache。ETCD 有很多使用場景,包括:配置管理、服務註冊與發現、leader 選舉、應用排程、分散式佇列、分散式鎖等。其中,比較多的應用場景是服務發現,服務發現 (Service Discovery) 要解決的是分散式系統中最常見的問題之一,即在同一個分散式叢集中的程式或服務如何才能找到對方並建立連線。ETCD 是 Kubernetes 的首要資料儲存,也是容器編排的實際標準系統。使用 ETCD,雲原生應用可以保持更為一致的執行時間,而且在個別伺服器發生故障時也能正常工作。應用從 ETCD 讀取資料並寫入到其中;透過分散配置資料,為節點配置提供冗餘和彈性。

ETCD 與 ZooKeeper 的簡單對比如下:

關於 MetalLB

Kubernetes 預設沒有提供負載均衡器的實現,MetalLB 透過 MetalLB hooks 為 Kubernetes 中提供網路負載均衡器的實現。簡單的說,它允許在私有的 Kubernetes 中建立 LoadBalancer 型別的 services。MetalLB 有兩大功能:

1. 地址分配:在平臺中申請 LB,會自動分配一個 IP,因此,MetalLB 也需要管理 IP 地址的分配工作 2.IP 外部宣告:當 MetalLB 獲取外部地址後,需要對外宣告該 IP 在 Kubernetes 中使用,並可以正常通訊。

實現細節

當 Kyuubi 底層引擎啟動時,會在 ETCD 中建立對應的 Key。租戶使用是,直接連線 MetalLB 提供的地址,由底層 LoadBalancer 負責負載均衡,連線到對應 Kyuubi server 後,server 會在 ETCD 中查詢是否有可用的引擎,沒有則建立。其中主要涉及以下三點內容:

1. 使用 Kubernetes 中原生元件 MetalLB+Deployment 方式實現實現 Kyuubi server 的高可用 2.ETCD 中模擬 EPHEMERAL_SEQUENTIAL 節點。在 ETCD 中沒有臨時 Key 的概念,無法在服務停止是自動刪除對應 Key 資訊。但是在客戶端中提供了 KeepAlive 功能:為特定的 Key 附加一個過期時間,並且在客戶端未被關閉或超時的情況下,自動重新整理這個過期時間。同時,引擎在註冊時,獲取對應節點的分散式鎖,計算編號,以實現節點編號的自增長。3. 分散式鎖,ETCD 的分散式鎖在使用方面和 ZooKeeper 基本一致,但在鎖持有時間方面稍有區別,ETCD 中鎖有租約時間,到時間後如果沒有主動釋放鎖,則會自動釋放,而 ZooKeeper 不主動釋放則不會釋放。

總結

首先,我們先簡單對比下雲原生架構和現有架構:

引入雲原生架構的 Kyuubi 在部署和運維方面極大的節約了成本,並且基於 deployment 我們可以實現 Kyuubi server 的動態擴容,基於 comfigmap 實現 server 的統一配置管理。目前,ETCD 的服務註冊和發現邏輯我們主要參考 ZooKeeper 的實現,後續工作會進一步最佳化呼叫邏輯。

最後,我們目前 Kyuubi 的整體架構圖如下,供大家參考。

來自 “ 開源部落格 ”, 原文作者:洪鼕鼕;原文連結:https://my.oschina.net/u/4565392/blog/5581654,如有侵權,請聯絡管理員刪除。

相關文章