OpenMLDB 線上模組架構解析

第四正規化開發者社群發表於2022-03-23

本文介紹 OpenMLDB 線上模組的架構,歡迎通過以下渠道瞭解關於 OpenMLDB 的更多資訊

GitHub:GitHub - 4paradigm/OpenMLDB: OpenMLDB is an open-source machine learning database that provides a full-stack FeatureOps solution for production.​github.com/4paradigm/OpenMLDB

OpenMLDB 使用文件:OpenMLDB 文件 (v0.4)

技術交流群:微信群掃碼

1. 概覽

OpenMLDB 的線上模組主要負責特徵指令碼上線以後的實時特徵計算,因此對於低延遲、高併發、高可用等有較高的要求。線上架構的主要模組包括 Apache ZooKeeper, nameserver 以及 tablets(進一步包含了SQL engine 和 storage engine)。如下圖顯示了這些模組之間的相互關係。其中 tablets 是整個 OpenMLDB 儲存和計算的核心模組,也是消耗資源做多的模組;ZooKeeper 和 nameserver 主要用於輔助功能,如後設資料的管理和高可用等。本文以下將會詳細介紹各個模組的作用。

2. Apache ZooKeeper

OpenMLDB 依賴 ZooKeeper 做服務發現和後設資料儲存和管理功能。ZooKeeper 和 OpenMLDB SDK,tablets, namesever 之間都會存在互動,用於分發和更新後設資料。

3. Nameserver

Nameserver 主要用來做 tablet 管理以及故障轉移(failover)。當一個 tablet 節點當機後,nameserver 就會觸發一系列任務來執行故障轉移,當節點恢復後會重新把資料載入到該節點中。同時,為了保證 nameserver 本身的高可用,nameserver 在部署時會部署多個例項,採用了 primary/secondary 節點的部署模式,同一時刻只會有一個 primary 節點。多個 nameserver 通過 ZooKeeper 實現 primary 節點的搶佔。因此,如果當前的 primary 節點意外離線,則 secondary 節點會藉助 ZooKeeper 選出一個節點重新作為 primary 節點。

4. Tablets

Tablet 是 OpenMLDB 用來執行 SQL 和資料儲存的模組,也是整個 OpenMLDB 功能實現的核心以及資源佔用的瓶頸。Tablet 從功能上來看,進一步包含了 SQL engine 和 storage engine 兩個模組。Tablet 也是 OpenMLDB 部署資源的可調配的最小粒度,一個 tablet 不能被拆分到多個物理節點;但是一個物理節點上可以有多個 tablets。

4.1 SQL Engine

SQL engine 負責執行 SQL 查詢計算。SQL engine 收到 SQL 查詢的請求後的執行過程如下圖所示:

SQL 引擎通過 ZetaSQL 把 SQL 解析成AST語法樹。因為我們加入了 LAST JOINWINDOW``UNION 等針對特徵工程擴充套件的特殊 SQL 語法,所以對開源的 ZetaSQL 做了優化。經過如上圖一系列的編譯轉化、優化,以及基於 LLVM 的 codegen 之後,最終生成執行計劃。SQL 引擎基於執行計劃,通過 catalog 獲取儲存層資料做最終的 SQL 執行運算。在分散式版本中,會生成分散式的執行計劃,會把執行任務發到其他 tablet 節點上執行。目前 OpenMLDB 的 SQL 引擎採用 push 的模式,將任務分發到資料所在的節點執行,而不是將資料拉回來。這樣做的好處可以減少資料傳輸。

4.2 Stoage Engine

Storage engine 負責 OpenMLDB 資料的儲存,以及支援相應的高可用相關的功能。

資料分佈

OpenMLDB 叢集版是一個分散式的資料庫,一張表的資料會進行分片,並且建立多個副本,最終分佈在不同的節點中。這裡展開說明兩個重要的概念:副本和分片。

  • 副本(replication):為了保證高可用以及提升分散式查詢的效率,資料表將會被存放多個拷貝,這些拷貝就叫做副本。
  • 分片(partition):一張表(或者具體為一個副本)在具體儲存時,會進一步被切割為多個分片用於分散式計算。分片數量可以在建立表時指定,但是一旦建立好,分片數就不能動態修改了。分片是儲存引擎主從同步以及擴縮容的最小單位。一個分片可以靈活的在不同的 tablet 之間實現遷移。同時一個表的不同分片可以平行計算,提升分散式計算的效能。OpenMLDB 會自動儘量使得每一個 tablet 上的分片數目儘量平衡,以提升系統的整體效能。一張表的多個分片可能會分佈在不同 tablet 上,分片的角色分為主分片(leader)和從分片(follower)。當獲得計算請求時,請求將會被髮送到資料所在對應的主分片上進行計算;從分片用於保證高可用性。

如下圖顯示了一個資料表,在兩個副本的情況下,基於四個分片,在三個 tablets 上的儲存佈局。實際使用中,如果某一個或者幾個 tablet 的負載過高,可以基於分片,進行資料遷移,來改善系統的負載平衡和整體的吞吐。

資料持久化及主從同步

目前版本的 OpenMLDB 的線上資料全部儲存在記憶體中,為了實現高可用會把資料通過 binlog 以及 snapshot 的形式持久化到硬碟中。

如上圖所示,服務端收到 SDK 的寫請求後會同時寫記憶體和 binlog。binlog 是用來做主從同步的,資料寫到 binlog 後會有一個後臺執行緒非同步的把資料從 binlog 中讀出來然後同步到從節點中。從節點收到同步請求後同樣是寫記憶體和 binlog。Snapshot 可以看作是記憶體資料的一個映象,不過出於效能考慮,snapshot 並不是從記憶體 dump 出來,而是由 binlog 和上一個 snapshot 合併生成。在合併的過程中會刪除掉過期的資料。OpenMLDB會記錄主從同步和合併到 snapshot 中的 offset, 如果一個 binlog 檔案中的資料全部被同步到從節點並且也合併到了 snapshot 中,這個 binlog 檔案就會被後臺執行緒刪除。

注意:在即將釋出的 v0.5.0 版本中,OpenMLDB 也會支援基於磁碟的儲存引擎,則其持久化機制會和本文描述不一樣。

相關文章