Vertica併發DML操做性能瓶頸的產生與優化(轉)

文章來源:中國聯通網研院網優網管部IT技術研究團隊git

做者:陸昕算法

 

1. 引言

衆所周知,MPP數據庫以其分佈式的超大存儲能力以及列式的高速彙總能力,已經成爲大數據分析比不可少的工具。Vertica就是這個領域的佼佼者,其最新版本已經發布到7.2版,甚至在Twitter、Facebook等尊崇開源平臺的互聯網公司也有大規模的集羣部署。數據庫

然而萬物有其利必有其弊,MPP數據庫高速的彙總計算能力是創建在其列式存儲、主動壓縮等一系列技術基礎上的。物理上的存儲方式致使了這類數據庫的UPDATE、DELETE等DML語句操做極其低效,有的MPP數據庫甚至取消了這兩類語句。Vertica雖然保留了這兩句DML語句,可是其執行效率,尤爲實在高併發場景下的執行效率如何,並不爲常人所熟知。本文對這一疑問進行了探索,但願對Vertica系統的開發人員有所啓發。性能優化

2.  Vertica併發DML測試

測試環境服務器

  • 5節點Vertica集羣網絡

  • 單節點12核CPU,128G內存,10T硬盤架構

  • 最大併發數:10個,排隊超時門限:5分鐘併發

測試方法分佈式

  • 測試程序分別同時開啓5個併發與10個併發函數

  • 將10000條數據**(INSERT)同一張表、進行單個字段執行10000條更新(UPDATE)、最後刪除(DELETE)10000條數據

  • 對上述三項DML操做作無限循環,記錄每條操做消耗的時間,直至系統性能顯著惡化 

3. Vertica併發DML瓶頸分析

分析以上測試結果能夠發現,在執行大規模併發DML類任務時,Vertica會遇到兩類瓶頸,一類由高併發引起排隊致使,另外一類則因爲DML語句鎖表致使。

1) 高併發排隊致使的第一類性能瓶頸

Vertica的最大執行併發數爲每一個節點CPU核數,在測試環境中,每臺節點擁有12個CPU,其中系統一般須要佔用其中的1-2個核,所以該系統配置了10個最大併發數,對於超過併發數的任務,系統會自動排隊,排隊超時門限5分鐘。理解了以上這一點,就不難解釋圖1中10個併發UPDATE語句的耗時爲何遠遠超過5個併發任務的耗時了。

圖1 UPDATE性能對比

  • 併發任務數爲5個時,此時併發數小於系統最大併發設置(10個),系統總體併發性能良好,基本沒有排隊,執行DML語句的耗時緩慢擡升,可是總體平穩,耗時在1-2s上下,此時性能只受到第二類瓶頸限制(下文詳述)。

  • 併發任務數爲10個時,併發數已經達到系統最大併發數,系統總體併發性能明顯降低。從圖2中能夠看出執行DML語句的耗時顯著高於5個併發的狀況,而且呈10個一組的週期性增加分佈。在每一個週期內,併發DML語句的耗時呈線性增加,增加速率極高(從2s飆漲至20s),此時高併發排隊引起嚴重的性能瓶頸:前一句語句佔用着CPU資源,後來的語句只能排隊等待資源釋放,這就形成了執行時間不斷增加,直到每個循環結束釋放全部資源。與下面要解釋的併發相比,高併發請求形成的性能惡化要遠遠高於鎖表形成的性能瓶頸。能夠預見,當併發數大於10個時,DML語句執行效率會更加惡化,所以控制DML併發數是系統要解決的首要問題。

圖2 UPDATE性能(10併發)

2)DML語句鎖表致使的第二類性能瓶頸

在5併發和10併發測試中,都存在由此類鎖表形成的性能問題。由圖1可見,5併發DML語句的執行耗時遠遠低於10併發,幾乎徹底不受併發瓶頸影響。爲排除第一類瓶頸形成的干擾,下面主要討論5個併發時的狀況。

圖3 DML性能(5併發狀況)

 

從上面三張圖能夠看到,INSERT語句耗時極少,幾乎自始至終都保持在200ms上下,而UPDATE和DELETE語句的執行時間要長出很多,在1000ms以上。這是全部MPP數據庫的相同的特性:對數據作增量操做很容易(HDFS同理),相比之下DELETE須要從列式物理存儲文件中定位到特定行,再標記爲無效(即刪除),耗時較長,而對於UPDATE語句,許多MPP數據庫甚至不支持(例如基於HDFS的Impala),Vertica支持UPDATE,本質上倒是DELETE+INSERT的組合。所以DELETE與UPDATE具備類似特徵也就不奇怪了。

回到第二類性能瓶頸上,上圖中DELETE和UPDATE語句隨着時間的增加,執行耗時會持續擡升,執行速度逐漸降低(固然擡升速率遠遠不及第一類性能瓶頸)。這主要是因爲在執行DML語句時,Vertica對全表加鎖以保證操做的原子性:加鎖後的表必須等待本次DML操做完成後纔會釋放,從而進行下一次DML操做,其中DELETE和UPDATE用到的排它鎖(X鎖)比INSERT用到的數據**鎖(I鎖)更嚴格,這也是爲何前兩者對系統性能的影響要遠遠大於後者。

此處尤爲須要注意的時,在通過一段時間連續執行DML語句後(約10分鐘),本來緩慢上升的執行時間曲線忽然開始劇烈波動並一直持續至測試結束,意味着總體併發性能嚴重惡化。這種惡化在屢次測試中是可重現的,頗有多是Vertica的鎖表機制的缺陷或者是底層硬件如硬盤讀寫和網絡IO出現較大波動形成的。好在大多Vertica的應用不會像這類測試同樣喪心病狂地對錶數據進行併發操做。

從上面的測試可知,基於Vertica的應用應儘可能避免頻繁數據增、刪、改操做。畢竟做爲列式MPP數據庫,對海量數據進行快速彙總和分析運算纔是其強項,頻繁的DML操做仍是交給Oracle等傳統交易型數據庫來作吧。對於那些必須使用Vertica進行DML操做的應用場景,下面探討一些靠譜的(以及不靠譜的)方案供參考。

4.  Vertica系統DML併發優化方案

1) 限制併發量

上面以及說起,由併發任務排隊致使的性能瓶頸是在系統設計階段必定要想辦法避免的。這類優化的關鍵點就是將應用的併發需求與物理硬件的併發能力匹配起來。具體能夠從如下幾個方面考慮:

  • 採用CPU物理核核數較多的服務器搭建Vertica集羣;

  • 在應用端經過合理設置任務請求數,控制數據庫鏈接數,以限制同時執行的任務數小於Vertica設置的最大併發數;

  • 對不一樣類型應用分配彼此獨立的資源池(Resource Pool),例如對頻繁的DML操做單獨設置專用高優先級資源池,而對於數據裝載這類應用分配優先級較低的資源池,這樣在高併發狀況下,系統會優先將內存、CPU等資源分配給容易造成瓶頸的DML語句。在進行資源池分配的時候,須要重點關注優先級(PRIORITY)、最大併發數(MAXCONCURRENCY)以及排隊超時時長(QUEUETIMEOUT)這幾個參數。因爲MPP數據庫對大多數語句的執行時間都在秒級,對少數超長的操做單獨設置資源池,只要避免如測試時的極端連續點擊狀況,大多數任務能夠避免排隊,而在合理的時間內執行完成,而對於超長等待只需設置排隊時間,超時拒絕便可。

2)改變業務邏輯,只進行增量操做

由上面的分析可知,在Vertica中存在着由UPDATE和DELETE語句鎖表形成的性能瓶頸,而INSERT語句的執行則十分平穩,並不會對系統性能形成太大波動。所以咱們能夠經過改變業務邏輯,只對表進行增量操做而避免使用UPDATE和DELETE語句,來提高系統性能。對於那些本來須要更新或者刪除的記錄,咱們只須要在數據表中增長一個字段標記每條記錄有效性,每次須要進行更新操做時,直接**新的數據,並根據時間戳將最新的這條記錄標記爲有效,舊有記錄標記無效。這樣在對字段進行彙總分析時經過有效性標識篩選最新的記錄,就至關於在操做一張更新後的數據表。最後,在系統中增長按期清理過期數據的策略便可。

3) 不靠譜策略之一:Purge

上述兩條是通過驗證,實測可用的優化策略。接下來要分享幾條理論上彷佛可行,實際測試效果不佳的優化策略,目的是進一步理解Vertica運行機制,讓後來人少走彎路。不靠譜策略之一就是在每次執行完UPDATE/DELETE語句後,增長一條Purge命令,以手動清空數據表中的冗餘數據。

咱們已經知道,Vertica的UPDATE/DELETE機制本質上就是將無效數據打上刪除標識,並在閒時由系統自動將標記刪除數據進行物理刪除操做。當對某一張數據表更新、刪除操做十分頻繁時,相關的存儲文件也會十分龐大,致使後續DML操做定位數據要耗費較長時間,從而影響執行速度。加上Purge自己耗時很是短(一般在二、3ms),彷佛在每次更新數據後手動Purge是一個不錯的方法。可是對比下圖與圖3中DELETE操做能夠發現,在應用了Purge以後,本來初期還算平穩的DELETE語句也變得不穩定起來,執行性能沒法獲得保障。Update也有相似的表現。

圖4 應用Purge後性能反而惡化

4) 不靠譜策略之二:DBD

衆所周知,Vertica優化有三寶:統計、排序與壓縮,而Vertica提供了自動化的數據庫優化工具DBD(Database Designer)可以根據具體應用的SQL自動化地生成優化策略。那麼理所固然地,咱們認爲DBD也能對DML語句進行優化。是否能如願呢?咱們先來回顧一下DBD是如何優化依據普通的查詢分析語句的。

以一個簡單的關聯查詢爲例:

SELECT

a.lac,a.ci,a.duration,a.imsi,b.latitude,b.longitude

FROM gn_gprs_data.Gn_GPRS_SH_201411 a

INNER JOIN wrnophq.NE_CELL_W b

ON a.lac=b.lac AND a.ci=b.ci;

DBD首先經過ANALYZE_STATISTICS函數收集這兩張數據表的統計信息,以便讓系統更好地理解這兩張表存放的數據分佈。在進過DBD優化後,生成以下優化腳本,其中可見Vertica新建了一個存放數據的projection,根據字段特色對SQL查詢用到的字段應用了不一樣的壓縮算法,並對關聯字段lac、ci進行了排序優化,這兩項優化策略都有助於減小關聯操做中快速索引。

圖5 DBD對JOIN進行的優化

圖6對比了優化先後的執行計劃,能夠發現:

  • 資源消耗減小了

  • 統計信息補全了

  • 減小了網絡間數據傳輸(BROADTEST標識消失了)

  • 兩表Join算法變成了更具效率的MergeJoin

圖6 DBD優化先後SQL語句的執行計劃對比

然而,遺憾的是DBD對Vertica的優化,更多地集中在如何提高數據分析的性能上,而對DML操做的優化幾乎沒有。在將UPDATE和DELETE語句輸入DBD後,直接提示該類語句不是能夠被優化的類型而拒絕生成新的projection,在執行時也就沒有任何優選路徑能夠選擇。進一步的測試能夠發現,DBD 「優化」後UPDATE語句的執行計劃並無改變,而時延測試結果也印證了最終結論,即DBD並不能優化DML語句,對系統併發性能也沒有任何影響。

 

圖7 UPDATE性能並未獲得DBD優化

5. 總結

本文探討了Vertica系統的DML併發性能瓶頸的產生現象、成因以及優化方法。雖然文中使用的是基於Verica的案例,可是我相信各家MPP數據庫的實現原理都是相近的,其產生相似的瓶頸問題是能夠預料的,固然上面提到的幾項優化方案也是徹底能夠借鑑的。而對於哪些同時包含大量更新操做和大數據分析的應用來講,搭建交易型數據庫(如Oracle)和分析型數據庫(如Vertica)的混合架構是一個更理想的選擇。

比起上述研究獲得的一些具體結論,我更想與你們分享的是一些性能優化方面的感悟:性能瓶頸的產生一般具備高度類似的現象,可是仔細分析後就會發現,其背後的產生機理不盡相同,而且每每錯綜複雜;而要真正地優化一個系統的性能,不只要從硬件架構、軟件配置、算法優化等各個方面進行綜合考慮,還要有一個嚴謹和實事求是的態度,在理解技術原理的基礎上,對優化方案進行全面的探索與測試,在這個過程當中,你會發現許多看似合理的方案實際上是無效的甚至最終結果是與優化目標徹底向左的。

相關文章
相關標籤/搜索