最近開始刷 VLDB 2019 中感興趣的 paper, 今天開始第一篇: 來自阿里云的分析性數(shù)據(jù)庫 AnalyticDB
由于這是一個(gè)云廠商的商業(yè)產(chǎn)品, 因此寫之前還是事先說明一下: 我沒有用過阿里云的 AnalyticsDB 產(chǎn)品以及 Paper 中提到的相關(guān)產(chǎn)品例如 AWS 的 Redshift 和 Google 的 BigQuery; 本文中所有的觀點(diǎn)僅代表個(gè)人, 如有不對(duì)的地方, 還請(qǐng)指正.
什么是 AnalyticDB
AnalyticsDB(下文簡(jiǎn)稱 ADB)是一個(gè) OLAP 數(shù)據(jù)庫, 對(duì)標(biāo)類似的產(chǎn)品是 AWS 的 Redshift/Google 的 BigQuery 或者開源的 Druid/Pinot
架構(gòu)
ADB 的一個(gè)優(yōu)勢(shì)是可以實(shí)時(shí)更新數(shù)據(jù), 因此在設(shè)計(jì)上將讀寫節(jié)點(diǎn)做了分離:
- 寫請(qǐng)求直接通過 Coordinator 路由到 Writer Node, 最終數(shù)據(jù)落盤到 Pangu(阿里云的分布式文件系統(tǒng)
- 數(shù)據(jù)寫入到一定程度后, 啟動(dòng) MapReduce 任務(wù)將數(shù)據(jù)合并成最終的數(shù)據(jù)文件
架構(gòu)上來說個(gè)人認(rèn)為一個(gè)大的亮點(diǎn)是雖然整體的數(shù)據(jù)庫引擎是自研的, 但 ADB 卻選擇了支持 MySQL 和 PostgreSQL 兩種協(xié)議, 直接享受了 MySQL 和 PostgreSQL 兩個(gè)數(shù)據(jù)庫相關(guān)的生態(tài)優(yōu)勢(shì).
數(shù)據(jù)寫入流程
第一個(gè) Writer Node 啟動(dòng)后, 會(huì)作為 Master 分派后續(xù)的 Writer Worker Node. 當(dāng)一個(gè) Write 請(qǐng)求到達(dá) Coordinator 后, Coordinator 先解析寫入請(qǐng)求的 SQL 后在分配寫入的節(jié)點(diǎn). Writer Node 寫入一定數(shù)據(jù)后再刷盤到 Pangu.
疑問 1: 如果在中途 Writer Node 停機(jī), 是不是沒有刷盤到 Pangu 的數(shù)據(jù)就丟失了?
疑問 2: 所有的寫請(qǐng)求都通過單一的 Coordinator 做路由轉(zhuǎn)發(fā), 如果寫入請(qǐng)求非常多(例如 paper 中提到的
handle tens of millions of online write requests per second
), Coordinator 會(huì)不會(huì)成為瓶頸?
數(shù)據(jù)讀取流程
由于 ADB 的 table 是分區(qū)的, 因此具體數(shù)據(jù)的放置就可以實(shí)現(xiàn) Storage-aware Query Optimizer.
Reader Node 啟動(dòng)時(shí)會(huì)從 Pangu 拉取數(shù)據(jù)文件, 因此猜測(cè) Reader Node 還是會(huì)通過本地盤的方式加速查詢的. 實(shí)時(shí)讀取時(shí), Reader Node 會(huì)時(shí)不時(shí)從 Writer Node 拉取最新的增量數(shù)據(jù). Reader Node 也可以設(shè)置 replication factor 來提升 concurrency 和 reliability. 每個(gè) Reader Node
都會(huì)分別從 Writer Node 獲取最新的增量數(shù)據(jù).
疑問 3: Reader Node 是間隔多少時(shí)間拉取 Writer Node 的數(shù)據(jù)的? 這期間豈不是根本查詢不到增量寫入的數(shù)據(jù)? 多個(gè) Reader Node replica 獲取并構(gòu)建增量數(shù)據(jù)索引, 會(huì)不會(huì)導(dǎo)致不同 replica 在某些情況下數(shù)據(jù)不一致(拉取增量有快有慢)?
集群管理
除了使用 Fuxi 做基礎(chǔ)計(jì)算資源的申請(qǐng)外, ADB 里面還有一個(gè) Gallardo 服務(wù)做資源分配, 據(jù)稱是為了多個(gè) ADB instance 之間采用 Control Group 做隔離.
疑問 4: 這個(gè) Gallardo 有必要嗎? 難道不是直接從 Fuxi 申請(qǐng)物計(jì)算資源就可以嗎? 是多個(gè) ADB instance 共用 Fuxi 分配的一臺(tái)計(jì)算節(jié)點(diǎn)的?
存儲(chǔ)
數(shù)據(jù)存儲(chǔ)設(shè)計(jì)
ADB 設(shè)計(jì)了自己的存儲(chǔ)文件格式(Hybrid Row-Column Store):
- Table 的一個(gè) partition 中所有的數(shù)據(jù)是一個(gè)文件, 稱之為 Detail File
- 為了解決單純 Column Store 對(duì) Point Query 性能問題, 數(shù)據(jù)被劃分成多個(gè) Row Group.每個(gè) Row Group 中有固定數(shù)量的 column, 同樣的column 的數(shù)據(jù)被組織到同一個(gè) data block.
疑問 5: 說實(shí)話, 我沒看懂為啥這個(gè) Hybrid Row-Column Store 能夠同時(shí)對(duì) OLAP 和 Point lookup 查詢都有優(yōu)勢(shì).
疑問 6: 如果數(shù)據(jù)量非常大而 Partition 數(shù)據(jù)量有不是足夠多(比如 100TB 數(shù)據(jù)的 Table 只有 100 個(gè) Partition), 豈不是單個(gè) Detail 文件會(huì)很大? 這樣設(shè)計(jì)在移步構(gòu)建索引的時(shí)候豈不是降低了任務(wù)的并發(fā)度? 還是說構(gòu)建索引的后臺(tái)任務(wù)可以使用 RowGroup 切分 Detail File 提升任務(wù)并發(fā)度?
數(shù)據(jù)查詢
由于有數(shù)據(jù)頻繁更新的場(chǎng)景, 因此 ADB 在數(shù)據(jù)查詢上采用的是 Lambda 架構(gòu):
- 將 Baseline 數(shù)據(jù)和 Incremental 數(shù)據(jù)進(jìn)行合并
- 對(duì)于刪除的場(chǎng)景, 通過 Bitset 判斷
- 由于增量數(shù)據(jù)查詢只有 sorted index, 對(duì)比 Baseline data 索引有很大差距, 定期會(huì)進(jìn)行 Incremental 數(shù)據(jù)合并.
索引設(shè)計(jì)
索引是所有的數(shù)據(jù)庫系統(tǒng)提升性能的法寶. ADB 也設(shè)計(jì)了自己的索引. 簡(jiǎn)單總結(jié)幾個(gè)我能看懂的點(diǎn)吧:
- ADB 的索引是將所有的 column 都索引的, 包括復(fù)雜的數(shù)據(jù)類型
- 由于索引多, 索引路徑選擇也有優(yōu)化空間. ADB 通過 filter ratio 來自動(dòng)決定索引路徑, 進(jìn)一步提升性能
- 對(duì)比 Greenplum, 1TB 數(shù)據(jù)文件情況下, ADB 僅僅使用 0.66TB 索引空間, 而 Greenplum 需要 2.7TB 索引存儲(chǔ)空間
- 常規(guī)數(shù)據(jù)庫都是在寫入時(shí)更新索引,因此會(huì)影響一定的寫入性能. ADB 使用后臺(tái)任務(wù)在 Merge 數(shù)據(jù)的時(shí)候構(gòu)建索引, 避免了這個(gè)問題, 提升了寫入性能.
- 增量數(shù)據(jù)也是有索引的, 使用了一個(gè) sorted index 設(shè)計(jì), 并且索引是在 Reader Node 上構(gòu)建的, 非常輕量級(jí).
Optimizer
OLAP 數(shù)據(jù)庫的查詢優(yōu)化器肯定是非常關(guān)鍵的. 可惜我在這個(gè)領(lǐng)域了解是在不多. 感興趣的自己去看吧, 我就不瞎 BB 了.
測(cè)試結(jié)果
Paper 中給出了三個(gè)測(cè)試查詢(SQL 見上圖), 一共有三種類型:
- Q1: 全表掃描查詢數(shù)據(jù), 并且有全局的
ORDER BY
操作 - Q2: 根據(jù)
o_trade_time
o_trade_price
seller_id
三個(gè)過濾條 - Q3:
JOIN
GROUP BY
ORDER BY
和聚合計(jì)算SUM
操作的查詢. 應(yīng)該算三個(gè)里面最復(fù)雜的.
跟著對(duì)比的是 PrestoDB, SparkSQL, Druid 和 Greenplum
1TB 數(shù)據(jù)查詢 Latency
從上圖可以看出, 整體的 latency ADB 都是在 1s 內(nèi)返回的, 即便是 Q3 這種復(fù)雜的查詢. 注意 Y 坐標(biāo)軸的刻度和單位(秒).
10TB 數(shù)據(jù)查詢 Latency
當(dāng)數(shù)據(jù)量增長到 10TB 時(shí), 查詢 P50 latency 依舊影響不太大, 結(jié)果見上圖. 不過不知道為啥沒有貼出 P95 的數(shù)據(jù), 畢竟 P95 更有說服力吧.
寫入性能
可以看出, 基本上寫入性能是跟著 Writer Node 數(shù)量線性增長的.
TPC-H 對(duì)比
TPC-H 的查詢就比上面 Paper 中自己定義的三個(gè) Query 復(fù)雜多了, 例如 TPC-H Q7 的查詢?nèi)缦?
select
supp_nation,
cust_nation,
l_year, sum(volume) as revenue
from (
select
n1.n_name as supp_nation,
n2.n_name as cust_nation,
extract(year from l_shipdate) as l_year,
l_extendedprice * (1 - l_discount) as volume
from
supplier,
lineitem,
orders,
customer,
nation n1,
nation n2
where
s_suppkey = l_suppkey
and o_orderkey = l_orderkey
and c_custkey = o_custkey
and s_nationkey = n1.n_nationkey
and c_nationkey = n2.n_nationkey
and (
(n1.n_name = '[NATION1]' and n2.n_name = '[NATION2]')
or (n1.n_name = '[NATION2]' and n2.n_name = '[NATION1]')
)
and l_shipdate between date '1995-01-01' and date '1996-12-31'
) as shipping
group by
supp_nation,
cust_nation,
l_year
order by
supp_nation,
cust_nation,
l_year;
感興趣的可以自己去看看 TPC-H 規(guī)范
ADB 的 TPC-H 結(jié)果如下圖(注意 Y 軸), 可以看出優(yōu)勢(shì)還是很明顯, 超過 10 秒的查詢都沒有幾個(gè).
總結(jié)
從架構(gòu)上來說, ADB 走的是 shared-storage 的路線, 大體架構(gòu)跟 Azure SQL 數(shù)倉和當(dāng)紅炸子雞 Snowflake 架構(gòu)類似, 都是采用"無狀態(tài)" 的節(jié)點(diǎn)實(shí)現(xiàn)數(shù)倉橫向擴(kuò)展的, 本質(zhì)上說跟 Redshift 還是不一樣. 對(duì) Cloud Data Warehousing 感興趣的同學(xué)也強(qiáng)烈建議去看 大神 Dr David DeWitt 的演講: Data Warehousing in the Cloud
- 來源: Azure 官網(wǎng)文檔
疑問 7: 從 Azure SQL 和 Snowflake 的架構(gòu)圖看, 二者都是采用云服務(wù)的 Object Storage 作為 shared-storage 架構(gòu)中的 Storage 選型的, 那么為何 ADB 沒有直接使用 OSS 而是選擇了 Pangu?
個(gè)人認(rèn)為, ADB 這個(gè)架構(gòu)設(shè)計(jì)上最大的亮點(diǎn)就是既然都徒手?jǐn)]了一個(gè) OLAP 數(shù)據(jù)庫了, 還選擇了支持 MySQL 和 PostgreSQL 兩種最為廣泛的協(xié)議, 而不是安耐不住自己設(shè)計(jì)了一個(gè)協(xié)議然后再苦哈哈的去構(gòu)建所謂的生態(tài). 原因很簡(jiǎn)單: MySQL 協(xié)議和 PostgreSQL 協(xié)議應(yīng)該算是這個(gè)領(lǐng)域使用最為廣泛的, 支持這兩種協(xié)議, 用戶就可以有大量的生態(tài)體系中的工具或則其他產(chǎn)品整合, 大為降低了 ADB 的使用門檻. 反觀 Snowflake, 幾乎是為主流語言都開發(fā)了 SDK, 也不知道這滿滿一屏幕的產(chǎn)品是如何被 Snowflake 拿下的.
Reference:
- ADB 官網(wǎng)文檔: https://help.aliyun.com/product/92664.html
- Snowflake 文檔: https://docs.snowflake.net/manuals/user-guide/intro-key-concepts.html#query-processing
- Azure SQL 數(shù)據(jù)倉庫架構(gòu)介紹: https://docs.microsoft.com/zh-cn/azure/sql-data-warehouse/massively-parallel-processing-mpp-architecture
- VLDB 2019 Industrial Track Papers: https://vldb.org/2019/?papers-industrial
- TPC-H 規(guī)范: http://www.tpc.org/tpc_documents_current_versions/pdf/tpc-h_v2.18.0.pdf