深入淺出話DB|柏睿數(shù)據(jù)RapidsDB高性能解密之自動(dòng)優(yōu)化
各位同行朋友,本篇是本系列的最后一篇,也是最舒服的一篇,因?yàn)橹v內(nèi)容是自動(dòng)優(yōu)化,也就是不需要DBA主動(dòng)干預(yù),數(shù)據(jù)庫(kù)會(huì)沒(méi)事就給自己做優(yōu)化!是不是有種躺贏的感覺(jué)?讓本人給大家匯報(bào)數(shù)據(jù)庫(kù)到底是怎么實(shí)現(xiàn)自動(dòng)優(yōu)化的?
柏睿數(shù)據(jù)內(nèi)存分布式數(shù)據(jù)庫(kù)RapidsDB的自動(dòng)優(yōu)化體現(xiàn)在2個(gè)階段:
數(shù)據(jù)入庫(kù)過(guò)程
入庫(kù)過(guò)程的自動(dòng)優(yōu)化解決2個(gè)常見(jiàn)的OLAP型MPP數(shù)據(jù)庫(kù)問(wèn)題,傳統(tǒng)的數(shù)控則需要外部手段或者手工執(zhí)行命令來(lái)實(shí)現(xiàn)相同的優(yōu)化效果:
1、自動(dòng)優(yōu)化小批量寫(xiě)入(比如單行插入)過(guò)程,解決高頻小數(shù)據(jù)量寫(xiě)入的性能低下問(wèn)題;
2、自動(dòng)優(yōu)化數(shù)據(jù)入庫(kù)前排序入庫(kù)過(guò)程,解決因新數(shù)據(jù)無(wú)序?qū)懭氘a(chǎn)生的查詢性能不高問(wèn)題。
RapidsDB實(shí)現(xiàn)的方式如下:
跟其他友商分布式數(shù)據(jù)庫(kù)的列存儲(chǔ)實(shí)現(xiàn)不同,RapidsDB將新寫(xiě)入的數(shù)據(jù)先將它們以跳表的方式臨時(shí)存儲(chǔ)在內(nèi)存中。這個(gè)操作由數(shù)據(jù)庫(kù)后臺(tái)自動(dòng)處理的,這些以行存方式的跳過(guò)列表數(shù)據(jù),可以對(duì)讀取可見(jiàn)。
具體一點(diǎn),向列存表插入數(shù)據(jù)時(shí),數(shù)據(jù)會(huì)先寫(xiě)入臨時(shí)的行存跳表或創(chuàng)建新的列存儲(chǔ)支持行段。至于是臨時(shí)表還是新建行段,數(shù)據(jù)庫(kù)引擎需要由根據(jù)插入數(shù)據(jù)量大小和列存儲(chǔ)索引的當(dāng)前狀態(tài)的自動(dòng)觸發(fā)確定的。每個(gè)數(shù)據(jù)分區(qū)16 MB,是 INSERT 或 LOAD DATA 寫(xiě)入數(shù)據(jù)優(yōu)化的默認(rèn)閾值。當(dāng)超過(guò)這個(gè)閾值時(shí),當(dāng)前外部寫(xiě)入的數(shù)據(jù)就會(huì)在內(nèi)存經(jīng)過(guò)排序后,直接寫(xiě)入新建的行段,反之則臨時(shí)存放在行存跳表中,經(jīng)過(guò)超時(shí)或者新來(lái)數(shù)據(jù)達(dá)到閾值后,寫(xiě)入列存行段中。
經(jīng)過(guò)上述操作,數(shù)據(jù)入庫(kù)過(guò)程的自動(dòng)優(yōu)化完成。
數(shù)據(jù)入庫(kù)后
入庫(kù)過(guò)程后的自動(dòng)優(yōu)化,就是為了解決傳統(tǒng)分布式數(shù)據(jù)庫(kù)甚至Hadoop平臺(tái)也非常常見(jiàn)的:在用戶使用一段時(shí)間后,發(fā)現(xiàn)如果沒(méi)有對(duì)數(shù)據(jù)庫(kù)的存儲(chǔ)進(jìn)行人工定時(shí)維護(hù),則會(huì)引起性能大幅下降的問(wèn)題,RapidsDB的3個(gè)自動(dòng)優(yōu)化手段,就是解決核心的3個(gè)性能影響因素:
1、無(wú)論做增刪改操作,數(shù)據(jù)庫(kù)都會(huì)自動(dòng)對(duì)相關(guān)的列存行段中的數(shù)據(jù)自動(dòng)重新排序,保證最佳的查詢性能;
2、當(dāng)列存行段內(nèi)重新排序完成后,其外的行段組會(huì)重新做排序組織,進(jìn)一步使數(shù)據(jù)有序,二次優(yōu)化性能;
3、經(jīng)過(guò)上述2點(diǎn)的優(yōu)化,有序數(shù)據(jù)使壓縮率得到提升,數(shù)據(jù)文件也得到合并,數(shù)據(jù)文件個(gè)數(shù)同時(shí)也會(huì)減少。IO讀寫(xiě)性能可以在整個(gè)使用過(guò)程中,一直保存在極高的狀態(tài)中。
基本實(shí)現(xiàn)手段如下:
我們都知道如果表中的行在所有行段中都是全局排序的,那么列式表的性能最好。實(shí)際上,在連續(xù)寫(xiě)入的情況下,維持這樣的順序是極難的。
RapidsDB使用了一種高級(jí)的算法,允許它在新增或更新數(shù)據(jù)時(shí)盡可能保持有序。這個(gè)過(guò)程被稱為background merger,并且為使行段的數(shù)據(jù)順序能夠得到持續(xù)優(yōu)化,則該過(guò)程會(huì)一直在后臺(tái)自動(dòng)運(yùn)行。
當(dāng)background merger在運(yùn)行過(guò)程中,在庫(kù)內(nèi)數(shù)據(jù)被增刪改等改變時(shí),它會(huì)停止到當(dāng)前任務(wù)并且重新開(kāi)始。鑒于每次只處理一小塊行段數(shù)據(jù),所以被停止的任務(wù)影響的只是少量的數(shù)據(jù)。只有在大量的更新工作負(fù)載下,重新排序處理效率才會(huì)顯著減慢,這是因?yàn)榱硪粋€(gè)機(jī)制pessimistic merger會(huì)鎖定當(dāng)前正在處理的行段。用戶也可以通過(guò)運(yùn)行命令OPTIMIZE TABLE手動(dòng)觸發(fā)pessimistic merger。我們將在下面解釋如何決定是否有必要進(jìn)行該指令,并如何運(yùn)行它。
RapidsDB使用sorted row segment group(排序行段組)的概念來(lái)描述參與排序的一組行段。即行段重新排序的過(guò)程,并且對(duì)于一個(gè)行段而言,其最小的行號(hào)不小于其之前的任何行段中最大的行號(hào),則這些行段形成排序的行段組。這里所描述的一行比另一行小,是代表該行的CLUSTERED COLUMNSTORE鍵的列值比另一行的列值小。
如果數(shù)據(jù)有一個(gè)完美的全局順序,它將由一個(gè)排序的行段組組成。如果剛?cè)霂?kù)的原始數(shù)據(jù)是以完全隨機(jī)的順序排列的,那么它會(huì)包含與行段一樣多的排序行段組。background merger的任務(wù)邏輯就是重新組織行段之間的行,即盡量減少排序的行段組的數(shù)量。
以下面的例子直觀介紹:
要檢查特定表的已排序行段組的當(dāng)前狀態(tài),請(qǐng)?jiān)贑LI環(huán)境中運(yùn)行SHOW COLUMNAR MERGE STATUS FOR來(lái)查看:
讓我們仔細(xì)看結(jié)果的第一行,我們知道存儲(chǔ)在分區(qū)0上的表的切片具有3個(gè)有序的行段組,一個(gè)由741個(gè)行段組成,一個(gè)由16個(gè)行段組成,最后一個(gè)由1行段組成,共計(jì)758個(gè)行段??紤]這種有序的行段組對(duì)非常簡(jiǎn)單查詢的影響:
根據(jù)排序行段組的定義,第一個(gè)排序的行段組最多包含一個(gè)包含user_group = 15的行的行段,除非user_group = 15位于兩個(gè)行段的邊界上,或者如果存在較大數(shù)據(jù)傾斜并且?guī)讉€(gè)行段僅由user_group = 15的行組成。類似的,第二排序行段組中最多一個(gè)行段包含相關(guān)行。這樣,總共758個(gè)行段中只有三個(gè)將被打開(kāi)和具體化。雖然本例中的查詢非常簡(jiǎn)單,但類似的推理同樣適用于復(fù)雜查詢中。
現(xiàn)在我們看一下分區(qū)2上有序的行段組。很明顯,它的優(yōu)化程度遠(yuǎn)遠(yuǎn)低于剩下的2個(gè),類似上面所示的選擇查詢將會(huì)導(dǎo)致物化8個(gè)行段。如果啟用了background merger,并且沒(méi)有或者少量工作負(fù)載同時(shí)運(yùn)行,那么這個(gè)分區(qū)將會(huì)在幾秒鐘內(nèi)得到優(yōu)化。然而,在數(shù)據(jù)庫(kù)執(zhí)行大量的增刪改任務(wù)時(shí),background merger的處理性能會(huì)被影響。在這種情況下,不如通過(guò)手動(dòng)觸發(fā)pessimistic merger,讓增刪改任務(wù)和后臺(tái)優(yōu)化任務(wù)前后腳獨(dú)立完成更合理:
如果當(dāng)我們執(zhí)行OPTIMIZE TABLE時(shí)運(yùn)行SHOW COLUMNAR MERGE STATUS,那么我們將會(huì)看見(jiàn)其作用:
新出現(xiàn)的一行代表分區(qū)3上正在進(jìn)行一個(gè)手動(dòng)合并,此時(shí)已經(jīng)完成了53.12%的工作任務(wù)。
當(dāng)完成合并任務(wù)后,現(xiàn)在情況更好了:
請(qǐng)注意,在本例中,沒(méi)有任何分區(qū)被合并到單個(gè)有序的行段組中。其原因是,兩種不同的合并方式均采用一種高級(jí)算法,該算法被優(yōu)化為在并發(fā)寫(xiě)入的情況下進(jìn)行小的分批次工作,并將數(shù)據(jù)保持在幾個(gè)有序的行段組中,而不是試圖將所有數(shù)據(jù)合并到單個(gè)有序的行段組中。如果可以犧牲一些數(shù)據(jù)處理時(shí)間來(lái)獲得更高的查詢性能,則可以運(yùn)行手動(dòng)命令,將每個(gè)分區(qū)上的數(shù)據(jù)合并到一個(gè)有序的行段組中:
此時(shí),任何選擇查詢將只具體化每一個(gè)分區(qū)的一個(gè)行段。
當(dāng)向列式表中插入少量行時(shí),使用內(nèi)存中行存儲(chǔ)支持的段來(lái)存儲(chǔ)行。當(dāng)這個(gè)以行存儲(chǔ)為基礎(chǔ)的段被填滿時(shí),后臺(tái)刷新程序background flusher會(huì)定期將這些行刷新到磁盤中。通過(guò)運(yùn)行OPTIMIZE TABLEFLUSH,可以手動(dòng)將受行存儲(chǔ)支持的段刷新到磁盤中。
至此,例子中數(shù)據(jù)表t的后臺(tái)自動(dòng)排序完成了。整個(gè)過(guò)程中,數(shù)據(jù)庫(kù)無(wú)須用戶干預(yù),僅通過(guò)自動(dòng)優(yōu)化實(shí)現(xiàn)了高性能。
目前,RapidsDB已經(jīng)在國(guó)有某大行普惠金融項(xiàng)目應(yīng)用中運(yùn)行超過(guò)10個(gè)月,產(chǎn)品自動(dòng)優(yōu)化證明了它的能力和價(jià)值。中間經(jīng)歷過(guò)幾次10TB級(jí)的數(shù)據(jù)加載,每天10GB級(jí)的數(shù)據(jù)新增和更新,以及定時(shí)的滾動(dòng)式刪除。過(guò)程中,技術(shù)團(tuán)隊(duì)無(wú)需對(duì)數(shù)據(jù)庫(kù)做任何優(yōu)化干預(yù),相同場(chǎng)景的數(shù)據(jù)操作沒(méi)有任何性能下降的跡象!
免責(zé)聲明:市場(chǎng)有風(fēng)險(xiǎn),選擇需謹(jǐn)慎!此文僅供參考,不作買賣依據(jù)。
編輯:qysb005標(biāo)簽: