背景
如果你是一名數據分析師,或者是一位經常和 SQL 打交道的研發工程師,那么 OLAP這個詞對你一定不陌生。你或許聽說過 OLAP、OLTP 技術,但是今天文章的主角OLAP 是由云技術平臺提供的一款分布式數據分析服務,下面先簡單介紹一下它。
小米 OLAP 是集存儲計算于一體的分布式數據分析型數據庫服務,通過 Kudu 實現“熱數據”的實時寫入和更新,通過自定義窗口定期遷移“冷數據”到HDFS,并以Parquet 格式存儲,實現了冷熱數據分離的架構,最終通過 SparkSQL 引擎提供同時對實時數據和歷史數據進行分析的能力。
>>>>
OldArchitecture & Drawbacks
cdn.xitu.io/2019/8/29/16cdc8ef4797bb73?imageView2/0/w/1280/h/960/format/webp/ignore-error/1">
圖1. OLAP 1.0元數據與權限管理
過去究竟有哪些“紛紛擾擾”呢,讓我們先從 OLAP1.0 版本的元數據與權限管理圖說起。可以看到,在舊版的架構中,Kudu表相關的權限和元數據與Hive表相關的權限和元數據,無論在實現上還是底層存儲上都是分離的。前者通過我們自己實現的Metadata Cache 和 Privilege Cache 與 OLAP 服務的組件 Metastore Manager 及SparkSQL 引擎進行交互,數據存儲在 Kudu 上;后者則使用了獨立的服務 Hive Metastore(HMS) 和 Sentry 分別進行元數據與權限的管理,底層數據存儲在 MySQL 數據庫。了解完舊版本的架構,就可以更徹底地了解這樣的架構帶來了的問題:
1、用戶角度:
(1)用戶使用 OLAP 服務時,如果要訪問 Kudu 表,需要對 SparkSQL隊列進行特殊配置,以開啟對 Kudu 數據源的支持。
(2)雖然早期架構在代碼層對meta 做了合并,但是并未從根本上解決權限分離的情況。比如用戶通過 Hive 授權的某個數據庫A,通過 OLAP 系統授權了某個數據庫B,在 OLAP 系統是無法看到數據庫A的相關表信息的。還會出現用戶有Kudu表權限但沒有 Hive 表權限的情況。上述情況不利于用戶數據的打通,還會讓用戶在使用過程中產生疑惑。同時,用戶需要切換隊列配置重啟服務,使用上也不夠友好。
2、開發角度:
Metadata Cache 和 Privilege Cache 在實現上存在冗余,其和底層元數據的交互在兩個組件都存在。其維護和開發成本比較高,沒有統一入口和規范。同時,底層分離的元數據和權限并不利于后續統一的 SQL Proxy 的開發。
可以看到,無論從用戶的角度,還是開發者的角度,進行底層元數據和權限的架構整合都非常必要。
和“紛紛擾擾”說再見
介紹完了過往的“紛紛擾擾”,讓我們看看如何和“紛紛擾擾”說再見。從圖1可以看出,解決這種分離的最簡單方法就是復用現有的 HMS 和 Sentry 組件,將原有的元數據和權限數據遷移到 MySQL 數據庫,同時更改上層組件的在元數據和權限部分的交互方法,包括 SparkSQL 層和 OLAP 服務端組件(OLAP Server、Metastore Manager 和 Dynamic Manager)。
圖2. OLAP 2.0元數據與權限管理
更改后的元數據與權限管理圖如上所示。下面我們分為兩部分來介紹相關的工作。
元數據整合方面,我們引入了 Kudu Storage Handler,其實現了 Hive Meta Hook的接口,繼承了 DefaultStorageHandler 類,可以與 HMS 進行交互,完成了對 Kudu meta 的相關操作。在原版的基礎上,我們補充了分區和表的相關操作,以及一些必要的rollup操作來保證 meta 的一致性。
在 SparkSQL 層,對 Kudu meta 的調用方式轉化為了直接使用 Kudu Storage Handler,原有的 Kudu 相關模塊的功能直接整合進 Hive 模塊,包括了查詢、建表、刪除表、修改表、展示建表語句等操作。我們大體兼容了舊版本的 DML 語法,并通過 tblproperties 來傳遞各種 Kudu 相關的信息,比如表名、range 分區信息、hash分區信息等,同時,我們自定義的信息和數據流部分信息也存在表屬性里,供上層程序使用,比如是否 OLAP 表、OLAP 窗口值等。
在 OLAP 服務端,我們對所有元數據相關的部分做了重構。原有的 Metadata Cache被移除,有關的元數據的操作通過調用 HMS Client 提供的 API 來實現。同時,我們把系統相關的數據從 Kudu 遷移到 MySQL 數據庫,使整個服務端不再對 Kudu Client有直接的依賴。
經過上述整合,所有的meta操作統一到了 Hive MetastoreClient 層,通過 Kudu Storage Handler 實現,數據存儲在 MySQL,和對 Hive meta 的操作一致。對于開發者,這種架構整體上更為清晰,在修改和維護上也更方便。對于用戶來說,通過beeline 去操作 Kudu 表和 Hive 表除了在建表語法上不同,其他基本操作和 Hive 沒有區別,用戶在建表后基本不需要關心底層存儲介質,體驗上更加一致。
權限整合的前提是 Kudu 相關元數據已經整合到了 HMS 中,這樣才能借助 Sentry 進行權限管理。基于此,我們需要實現鑒權和授權兩條通路。
在 SparkSQL 層,由于本身 Hive 模塊就已經集合了 Sentry 用來做權限鑒定,所以元數據遷移過來以后,beeline 的操作都會通過 Sentry 進行鑒權,而授權部分目前SparkSQL 的語法還不支持。
在 OLAP 服務端,我們對原有權限相關的操作進行了重構。原有的 Privilege Cache 被移除,所有權限相關的操作通過調用 Sentry Client API 實現,包括鑒權、授權、移除權限和權限展示。在權限展示方面,由于 Sentry 本身的模型限制,提供的 AP I無法滿足需求,我們根據自身需要進行了定制化開發,如增加了相應的 API 實現基于用戶角色的權限獲取等。
經過權限上的整合,Kudu 和 Hive 的所有權限就打通了,并可以通過 Sentry 統一提供權限相關的服務。
總結與展望
經過元數據與權限的整合,OLAP 服務的元數據范圍和權限范圍都擴大了,同時意味著查詢的范圍也擴大了。新的架構如下圖所示,meta 相關的服務最終都由 Hive Metastore 來提供,權限相關的服務最終都由 Sentry 來提供,我們只需要在各層通過客戶端接口進行調用即可。
New Architecture
圖3. OLAP 2.0架構圖
基于整合后的架構,未來我們可以提供更多的能力,比如基于HMS的元數據服務,基于Sentry的權限服務。未來,我們計劃
支持更多的數據源,比如MySQL數據源,
整合更多的SQL引擎,比如 Hive、Kylin 致力于打造統一的SQL引擎服務。