來不及解釋了!看OceanBase SQL團隊如何優雅處理4200萬條/秒SQL峰值
本文作者:柏澤
現任螞蟻金服OceanBase團隊資深技術專家,負責OceanBase的並行查詢和新一代OLAP引擎。曾就職於美國Oracle公司,負責Oracle資料庫並行查詢研發工作並有多項專利申請。OceanBase是阿里巴巴螞蟻金服自研的一個通用分散式關係資料庫,它在分散式架構下能夠保證金融級的數據一致性和高可用,並且有非常靈活的水平擴展能力和彈性部署能力。它一般是多地、多活、多副本的方案去部署,它現在已經支持了螞蟻金服百分之百的核心交易系統。去年雙十一支持了25.6萬筆/秒的交易,4200萬條SQL/秒。
今天有個很流行的說法叫做金融級資料庫,什麼叫做金融級資料庫?我們認為所有的金融客戶使用的各種金融場景,都能夠在這個資料庫里得到很好的支持和執行,這就是一個金融級資料庫。
對於金融客戶的需求場景來說,從最基礎的來講,是要求數據的一致性,可靠性,數據不能出錯,數據不能丟失;從進階的角度來講,系統要有強大的事務處理能力,具有高並發,高可用,可以方便的進行系統擴展和容災能力。然而,除了這些以外,還有個很重要的點是OLAP(OnLine Analytic Processing在線分析型查詢)的查詢支持能力。
不管是從螞蟻內部的業務場景來看,還是從外部金融客戶的行業需求來看,OLAP查詢是在金融場景中不可或缺的。從風險防範,模式識別,業務報表,月度結算等等,都需要資料庫有能夠做OLAP查詢的能力。
OLAP查詢的概念最早由Ed. Codd在1993年提出來,至今也有20多年的歷史,學術界和工業界圍繞OLAP查詢的場景,也提出了很多的思路和實現方法。大體來看,OLAP查詢是對資料庫的SQL查詢優化器和SQL執行引擎有比較高的要求的,目前在使用的資料庫系統中,能夠將OLTP事務型查詢和OLAP分析型查詢都同時支持的比較好的屈指可數。OceanBase從金融客戶的實際需求場景出發,以SQL優化器的代價模型,統計信息收集和查詢改寫以及SQL執行引擎的並行執行能力為突破口,圍繞著OLAP場景的實際需求,做了大量的工作。1. OceanBase的SQL引擎框架
SQL引擎的基本工作就是將每一條用戶輸入的SQL查詢語句通過一系列的語法解析,查詢改寫,計劃代價選擇,最終生成一個可以執行的語法樹,再經由一定的策略通過SQL引擎執行器執行並最終返回結果給用戶的過程。SQL引擎追求的優化目標就是最小化查詢計劃生成時間和執行時間。OceanBase實現了經典SQL引擎的全部模塊,並且在其中創造性的提出了很多新的實現,比如Faster Parser這個快速命中計劃緩存的機制等。
2. OceanBase的優化器
OceanBase優化器代價模型基本的經典理論還是基於System R的模型,它會結合OceanBase的數據存儲引擎的特點,去考慮代價上的一些特殊性。優化器會做兩階段的優化。第一階段是假設所有的關係都是本地的去做一個最優計劃,在各種可替代計劃當中找出CPU和IO總和開銷最小的計劃。第二步會進行分散式並行執行優化,並行執行優化除了要考慮CPU和IO,還要考慮網路的開銷,考慮採用多線程執行帶來的Overhead的開銷。
2.1 緊密結合LSM-TREE存儲的代價模型和統計信息收集
在代價模型對掃描進行代價估計時,不同於單一數據源的存儲引擎,OceanBase需要考慮到一行的數據可能同時來自於靜態的SSTable和動態的MemTable,每個表每個分區隨著動態數據的不同,可能掃描的代價會有差異,我們可以通過一些動態採樣的方式來計算不同的掃描代價。在索引回表時,因為是IOT(Index Organized Table)的形式而不是傳統常見的堆表,且數據會由負載均衡模塊進行動態的遷移,OceanBase的索引中保存的是每行數據的邏輯Rowkey,而不是物理的rowid,這就使得OceanBase的索引回表操作代價會比較高。 對於統計信息的收集,除了傳統的平均行長,行數,每列的NDV(Number of Distinct Value),直方圖等等之外,OceanBase的存儲層會保存SSTable每個block的一些統計信息以及MemTable關於數據修改的一些統計信息,可以方便的給優化器提供一些統計信息的輸入。此外,OceanBase還有動態採樣的框架,可以對於比如沒有統計信息的表,或者較為複雜的有關聯性的多列的一些統計信息採集,預估,使用動態採樣的方法來獲取較好的統計信息預估。 2.2 複雜查詢的查詢改寫查詢改寫是指通過一定的方式,將SQL語句改換成語法不同但是語意一樣的一種SQL查詢優化技術,目前OceanBase已經構建了一個完備的基於代價的SQL查詢改寫框架,可以進行豐富的基於規則的查詢改寫和部分的基於代價的改寫。 OceanBase的查詢改寫框架如下圖所示:目前,OceanBase支持的基於規則和基於代價的查詢改寫列表如下:
基於規則的改寫
視圖合併
子查詢展開Anti/Semi Join過濾條件下推, 連接條件下推,等價條件推導外連接消除distinct消除sort/order by 消除sort方法選擇等
基於代價的改寫
下面各舉一例說明查詢改寫。例1:規則改寫——子查詢展開:OR-expansion
Window functionGroup by placement(開發中)連接條件下推(JPPDto view/table) (開發中)
如上例所示,如果不做查詢改寫,則執行計劃只能是一個filter計劃,對於customer中拿出的每一行,執行子查詢,如果有匹配行,則不返回,否則返回,可以看到,子查詢會被執行非常多次,計劃執行很不高效。在執行查詢改寫後,通過anti join的方式,不用多次執行orders表的子查詢,並且為計劃引入了新的優化可能。
例2:代價改寫——OR Expansion:以上圖的兩個例子來說,第一個查詢,在不採用改寫之前,唯一的執行方法就是對t1表做全表掃描並且帶上t1.a=1 or t1.b=1這個過濾條件。但是在改寫之後,如果在a列或者a,b列上有索引,union all的兩個分支可能分別可以採用索引的方式去查詢,代價可能會比做全表掃描要好。對於第二個查詢,在沒做改寫之前只能採用nested-loop join的方式去做連接,而改寫之後,可以採用hash join,或者merge join等等。
查詢改寫是一種非常有用的對於複雜SQL提供高效的執行方案的手段,以TPC-H Q17為例,1G schema無並行執行的情況,在OceanBase採用了window function的改寫之後,查詢時間從原先的3個小時以上跑不出結果到4.9秒出結果。 正是因為OceanBase有一套自主研發的完備的基於代價的SQL優化器,我們才能擁有執行複雜查詢,大查詢的能力,為金融業務的很多複雜查詢場景提供強有力的支撐。3. OceanBase的並行執行能力
OceanBase是一個分散式的關係資料庫系統,在OLAP查詢場景下,並行執行的能力對於查詢的響應時間(RT)影響很大。OceanBase的SQL引擎實現了一套基於分散式架構的並行執行框架。
3.1 並行執行的基本概念並行執行是一個Divide and Conquer的概念,也就是分治。對於SQL的執行計劃來說,我們將整個的計劃拆分成為一個個可以獨立執行的子計劃,通過調度的手段,讓有相互依賴的子計劃同時採用不同的線程組執行,採用生產者消費者模型,形成局部流水線,充分利用系統的IO和CPU能力,達到降低查詢RT快速響應的目的。同時,在水平層面,在每一個進行基表掃描的子計劃中,會通過切分掃描任務的方式,從基表掃描開始,將所有的SQL查詢運算元都能夠並行執行。以下圖的並行執行計劃為例,一個兩表連接的Hash Join計劃被分成了三個子計劃,分別做並行左表的掃描,右表的掃描和並行的Hash Join。為此我們需要能支持數據的重分布。
OceanBase能夠提供多種豐富的數據重分布方法,比如Hash, Broadcast, Round Robin, PKEY, Merge SORT等等,會由優化器來決定最好的計劃和數據重分布方式。數據在不同線程組之間通過數據傳輸層(Data Transfer Layer)DTL傳輸數據,生產者線程在流水線執行中根據不同的數據重分布方法流式的向DTL層寫入數據,消費者線程會不停的從DTL層讀取數據並進行對應子計劃的執行。
3.2 OceanBase的兩級調度
OceanBase採用了一個兩級調度的機制,整體的調度模型如下所示:OceanBase調度模型
主線程負責生成整體的執行計劃,並且獲得整體的並行度,隨後將子計劃發送到各個節點執行,同時按照優化器的指示給定每個節點的並行度,各節點的控制線程會負責本節點執行資源的獲取和控制調度,各節點獨立決定本節點的掃描任務的粒度,保證並發執行的均勻和高效。以一個30G的分區表分布在3個節點為例,每個節點上的數據都為10G左右,但是第一個節點只有1個分區,其餘兩個節點均有20個分區,總的執行並行度假定為15,優化器給每個節點的指定並行度很顯然為5。對於有20個分區的節點,掃描粒度可以以分區為單位進行,但是只有一個分區的節點,如果以分區為單位,則5個線程會有4個處於空閑狀態,顯然不是最優,此時該節點的並行掃描粒度可以以數據塊的範圍為粒度,將5個線程同時掃描這一個大的分區。OceanBase的並行執行引擎可以支持所有主要運算元的並行執行操作,包括nested loop join, merge join, hash join, aggregation, distinct,group by, window function, count, limit等等。她能夠支持豐富的數據重分區方法,從而為優化器的選優提供了更多的可能。總結OceanBase的SQL團隊通過4年的時間,以關係資料庫成熟的理論基礎為基石,結合分散式系統架構和LSM-Tree的動靜態數據結合的存儲引擎特點,從零開始一步一步搭建起了整個的SQL優化器和處理引擎。我們相信,一個自主研發完全可控的完備的SQL優化器和執行引擎,才可以有能力滿足金融客戶的複雜查詢場景需求,做到真正的具有HTAP的能力,體現出SQL語言的強大查詢表達能力,而不再將關係資料庫僅僅作為一個分散式的KV系統使用。
OceanBase官網鏈接:https://oceanbase.alipay.com/
交流社群
最後,我們給對 OceanBase 資料庫感興趣的同學準備了微信交流群,你除了可以瀏覽OceanBase的官網之外,你還可以搜索並關注 OceanBase 微信公眾號,回復關鍵詞交流群, 加入OceanBase的技術交流群,來和螞蟻金服一線OceanBase技術人員還有其他小夥伴們一起討論交流~!OceanBase 是由螞蟻金服、阿里巴巴完全自主研發的金融級分散式關係資料庫,始創於2010年,至今已成功應用於支付寶全部核心業務:交易、支付、會員、賬務等系統以及阿里巴巴淘寶(天貓)收藏夾、P4P廣告報表等業務。從2017年開始,OceanBase開始服務外部客戶,客戶包括南京銀行、浙商銀行、印度Paytm、人保健康險。想要查看更多優質文章請持續關注OceanBase官網、官方微博、OceanBase微信公眾號、知乎專欄。
推薦閱讀:
※如何將資料庫中查詢出來的數據再進行分頁操作?
※14.6.3 InnoDB Buffer Pool 配置
※Mysql在RC隔離級別下是如何實現讀不阻塞的?
※常見sql注入原理詳解!
※全球MySQL資料庫淪為新一輪勒索軟體攻擊目標