華爲GaussDB數據庫相比PostgreSQL做了哪些內核優化

行業背景

隨着全球經貿摩擦與中美貿易戰愈演愈烈,國家基礎軟件自主可控被提上議程。數據庫作爲基礎設施中重要的一環,承擔着不可忽視的作用。近幾年國產數據庫得到了飛速的發展,特別是雲數據庫、分佈式數據庫產品也越來越多。這其中華爲公司也已經在數據庫領域深耕多年。

華爲公司在今年5月份推出了自研的AI Native數據庫GaussDB。GaussDB分爲三個產品線,GaussDB100、GaussDB200、GaussDB300。

GaussDB100是華爲和招行合作研發的純OLTP類數據庫,底層基於華爲自研的GMDB內存數據庫,GMDB是華爲最早自主研發的內存數據庫,主要應用於電信相關領域,與招行合作研發的GaussDB100也已經在招行若干系統上線。

GaussDB200是華爲與工行合作研發的純OLAP類數據庫,GaussDB200基於經典pgxc架構,底層基於postgresql9.2版本研發,是一款分佈式mpp數據庫,目前已經在工行有大規模應用。

GaussDB300是基於GaussDB200演變而來,在原有集羣上做了很多OLTP的適配,是一款HTAP混合負載分佈式數據庫,當然現在GaussDB300也有單機版,目前300也在和國內某大行進行合作研發。本文主要介紹一下GaussDB300數據庫架構演進以及與pg對比高斯在內核層面做了哪些優化。

架構演進

相比postgresql-xc架構,GaussDB200分佈式數據庫新增了集羣管理cmserver作爲集羣的大腦進行集羣調度管理,增加cmagent作爲集羣每個節點上的agent來完成cmserver下發的具體任務,增加ommonitor監控組件監控每個節點上相關進程狀態,實現進程故障自愈等功能。集羣管理功能比較強大,目前實現了集羣節點故障或者亞健康的自動切換,故障場景涵蓋面比較全,比如宕機、數據庫進程異常終止、網卡故障、文件系統只讀、磁盤緩慢等場景都能夠觸發自動切換。總體架構如下:
在這裏插入圖片描述
GaussDB300數據庫在200的基礎上新增了etcd集羣,用於保存gtm的全局事務id號,同時數據節點由原來的主-備-從(從節點不含數據,當主節點宕機切換後,從節點纔有數據)變爲現在的一主多備模式,每個備節點都有數據,節點間使用quorum協議。Gtm集羣由原來的一主一備變爲了一主多備。總體邏輯架構如下 :
在這裏插入圖片描述
整個系統採用多租戶架構,應用通過負載均衡lvs或者f5連接到多個協調節點(CN),協調節點是無狀態的,協調節點將應用的sql進行解析,生成分佈式執行計劃下發給數據節點(DN),在開啓事務時,CN會先去全局事務管理器(GTM)集羣取事務號和快照信息,最新版本的集羣已經將事務號存儲在etcd集羣中,etcd是集羣raft協議的分佈式存儲。

內核優化

1.進程模型改爲線程模型
我們知道postgresql是進程模型,各個後臺進程由postmaster主進程創建,每個客戶端連接進來服務器端都會創建一個server process與客戶端交互,處理客戶端請求。進程模型有個問題就是容易造成oom,當爆發連接風暴時,work_mem這類參數的設置可能造成內存溢出。高斯數據庫將pg的進程模型改爲了了線程模型,不僅包括server process,也包括各類後臺進程,這樣提高了內存信息的安全性,也降低了內存溢出的風險。但是這樣修改其實有利有弊,不好的地方就是,如果發生遇到使用pg_terminate_backend(pid)殺不掉某條sql的情況下(筆者生產環境多次遇到),pg可以在操作系統層面使用kill命令殺掉該連接,而高斯則不能,因爲如果使用kill殺掉,會造成數據庫主進程也被kill。

2.高可用架構增強
傳統pgxc架構下,高可用其實並不完善,雖然支持多寫,其實也是協調節點層面的多寫,數據節點還是一份,gtm這塊也是單節點或者主備架構。GaussDB300在高可用這個層面做了很多優化,比如gtm改爲一主多備架構,主gtm宕機能夠自動切換到備gtm,同時引入主備超時機制,在早期的版本中,因爲主備之間要同步gxid信息,所以當備gtm宕機時會影響主的運行,進而造成整個集羣hang,這塊經過優化後gtm主備之間超時會自動變爲異步。數據節點層面通過shareding key的哈希策略將數據分散到每個dn分片,每個dn分片由原來的單節點變爲每個分片的一主多備模式,使用quorum協議進行復制,少部分數據節點的宕機不影響全局可用性。同時新增了非常完善的監控及集羣管理組件,如果某個進程異常停止,監控會立即報告集羣管理將進程嘗試拉起,無法啓動則會進行切換。集羣管理除了控制切換這塊十分完善,還有個很強大的功能,主備切換後如果原主庫需要rebuild也是集羣自動完成的,集羣管理會判斷原主再加入集羣時需不需要執行pg_rewind,如果不需要則自動加入,如果需要,集羣管理會自動進行增量或者全量的rebuild操作,這個功能是很好的,考慮的十分全面。

3.使用etcd集羣存儲全局事務號
Gtm組件是集羣的心臟,每個事務的開啓都需要cn與gtm的交互,需要取gxid和快照信息,所以在高併發的情況下交互十分頻繁,所以gtm的網絡流量是非常大的,gtm可能來不及分配事務號,很容易成爲瓶頸。同時,gtm主備節點之間同步信息會造成高可用的問題,任何一個事務號都要到備節點進行sync操作,如果發生某個gtm節點宕機,會造成超時等待,整個集羣會hang,造成高可用的問題。針對上面兩個問題,GaussDB300引入了第三方etcd集羣,etcd集羣是基於raft協議的高可用強一致集羣,最少三個節點,比較輕量化,十分適合用來存儲gxid,這樣一來,gtm的工作就剝離一部分到etcd了,高可用就依賴於etcd集羣的成熟高可用方案,大大縮短了gtm宕機對集羣的影響。Gtm就只負責從etcd集羣讀寫事務號,這塊設計十分巧妙。

4.XID事務號從32位改爲64位
可能大家看到這條的時候可能心裏震撼了一下。32位的事務id是pg永遠的痛,也許以前pg更多的用於分析類場景,所以事務號的消耗沒有那麼大,但是現在高併發場景越來越常見,32位事務id很快就會被消耗殆盡,32位事務號能容納的最大事務號是42億左右。經過測試,pg每秒最多插入大概100000條數據,按照1秒消耗十萬事務號來計算,42億事務號大概只能支撐12個小時,事務號是循環使用的,所以其實用到一半21億的時候爲了保證事務可見性就需要做freeze操作,freeze操作會對超過年齡的表進行凍結,凍結操作(也被稱爲凍結炸彈)會拒絕所有數據庫連接,必須進入單用戶模式執行vacuum freeze操作,這對數據庫無疑是非常難以接受的。華爲將事務號改爲64位後很明顯已經達到了永遠也用不完的情況。當然這塊改動也是很大的,很多其他模塊也需要做聯動,比如提交日誌clog這塊的尋址和清理也需要做相應的調整。

5.GTM性能增強
這個涉及到兩方面問題:第一方面gtm分配gxid的速度成爲瓶頸,針對這方面優化爲使用etcd作爲gxid的存儲,同時gxid的分配由原來的一次分配一個事務號改爲一次批量分配200000事務號,事務開啓後按需去拿已經分配好的序號就行,這樣大大減輕了gtm事務號分配的壓力。第二方面的問題是高併發下cn與gtm的交互過多,網絡流量過大,針對這個問題華爲也已經在預研gtm-lite,對於非全局類型的事務,cn就只作爲一個轉發者,將sql下發,而不再去gtm上取快照信息,oceanbase現在使用的就是這個方案,華爲還在研發。

6.流複製增強
我們知道postgresql需要通過pacemaker+corosync或者repmgr這類的外部工具實現pg的高可用切換方案,華爲拋棄了原來pg配置recovery.conf的方式配置流複製,轉而直接將連接信息放在postgresql.conf文件中,並且將高可用方案做到了內核層面,而不是依賴於外部工具(當然華爲也會做一套高可用集羣管理工具)。現在單機版GaussDB在不依賴於集羣管理的情況下,一主多備能夠實現主備切換後備庫自動連接到新主庫,還有主備切換後原主庫以備庫的角色重新加入集羣會自動判斷是否需要做rebuild(pg裏是pg_rewind)操作,如果不需要,則自動加入,如果需要就會自動做rebuild操作,然後加入集羣,很多以前pg裏涉及切換需要手動操作的內容,在gauss裏已經在內核層面實現自動化,而且不會造成數據丟失。

上面都是比較大的改動,除了上面的優化還有很多細節上的改動,比如集羣日誌優化、監控視圖優化、安裝部署優化、時間線timeline優化等。

當然華爲做的這些內核改動也是一把雙刃劍,有得有失,但是總體利大於弊。我覺得最大的弊端就是失去了插件的支持,pg是一個非常乾淨的開源數據庫,體積很小,生態很好,很多優秀的功能或者運維工具都可以通過擴展插件的方式來進行支持,我們知道pg有很多優秀的插件,比如:pg_stat_statment、pg_repack、bloom、citus、repmgr、pg_strom、pg_pathman等。還有一個問題就是數據庫體積過於龐大,很多無用的文件,相比pg顯得比較臃腫。

歡迎關注我的公衆號:數據庫架構之美

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章