目錄
1. 前言
2. 核心端高可用設計
2.1 GTM高可用
2.2 CN高可用
2.3 DN高可用
2.3.1 主、備、從高可用設計
2.3.2 資料複制
3. 叢集管理端高可用設計
3.1 CMserver高可用
3.2 CMagent高可用
1. 前言
MPPDB叢集服務元件主要分為核心端和叢集管理端,核心端主要包括GTM元件,CN元件和DN元件;叢集管理端主要包括CMServer元件和CMagent元件。

2. 核心端高可用設計
2.1 GTM高可用
在MPPDB中,GTM在叢集中隻有一個執行個體,如果故障後,叢集将無法使用,是以需要給GTM配置一個備機,主機故障後,備機可以接管服務。 GTM主要負責分發xid和snapshot,由于xid要全局唯一,是以需要持久化到磁盤上,凡是需要持久化磁盤的都需要有備份,那麼GTM主機在每将一次xid值寫入到gtm.control檔案中,就會和備機同步一次,備機寫完後,主機再寫。 在同步過程中,主機業務線程隻需給GTM備機發送一個消息包,GTM備機接收到消息後建立一個服務線程,并将事務xid寫入本地檔案,回複消息,主機的一次同步便完成。GTM在記憶體中xid每加2000時會向備機同步一次。 如果GTM主機永久故障,GTM備機升主後,隻需要重新初始化一個GTM執行個體出來然後和主機同步xid即可
2.2 CN高可用
通常一個叢集中會部署多個CN,多個CN互為主備。如果一個CN故障,那麼用戶端可以使用其他CN。 由于CN隻存儲元資訊資料(即每張使用者表資料分布在哪幾個DN),是以隻有DDL操作時才設計到CN存儲資料,DML時CN并不需要寫資料。在DDL操作時,接受業務的CN會把該SQL發送到所有其他CN與所有DN,通過兩階段送出來保證各個CN的資料一緻性。這裡也有一個設計缺陷,即當一個CN故障時,那麼叢集便無法操作DDL,此時隻能手動從叢集中删除該CN才能使用。 如果叢集中一個CN永久故障,那麼需要重新初始化一個CN,然後使用gs_dump從另一個CN到處中繼資料再導入到該新CN上。
2.3 DN高可用
由于所有使用者表資料通過sharding的方式存儲在各個DN主上,各個DN資料完全沒有分叉,如果主機故障後,那麼資料将丢失,并無法提供服務,是以DN的高可用尤為重要,必須給DN主備配置一個或多個備機。 MPPDB中的DN的高可用主要包含兩大塊設計,第一:主、備、從高可用設計;第二:資料複制。
2.3.1 主、備、從高可用設計
主備從中,其中主和備各有一份完整的資料,從備上不存儲資料。由于分布式環境,一份資料分片在多個DN上,那麼必須要求各個DN主與備必須強同步,如果不是強同步的話,主機故障,備機升主後,備機可能沒有主機的部分資料,這樣在分布式環境下就會産生有的DN上有資料,有的沒有,會造成叢集的資料不一緻,是以DN的主備必須是強同步,事務送出時,資料必須已經寫到備機上才可以送出。 此時就會暴露另外一個問題,即如果叢集中有任意一個DN主或DN備故障後,那麼叢集将無法進行寫事務,當叢集中DN資料較多時,單節點故障場景在生産環境往往是不可避免的。是以為了解決單節點故障後叢集寫事務可用時,我們引入了從備這個執行個體,簡單來講就是備機故障後,資料将發送給從備,仍然保證了資料寫兩份的原則,事務照樣可以送出。如果備機和從備均故障後,那麼寫事務仍然無法進行。
當主備從正常時,資料隻發送給備機,從備空閑: 當備機故障時,資料會發送給從備,保證寫事務正常進行;備機故障修複後,繼續連接配接主機追趕故障過程中丢失的資料,并且此時主機資料不再發送給從備,直至備機追趕完主機達到同步狀态,那麼主機将發送指令,删除從備上所有資料。 當備機在追趕主機的時候,主機故障,那麼會觸發備機Failover,備機連接配接從備,接收資料,接收完成後,備機升主,資料同步給從備。
設計反思: 主備從當時設計的時候主要考慮的事避免資料的3份備援,因為硬體層面已經做了RAID,軟體層面再3份備援,存儲空間使用率很低,當時跟N9000配合,N9000就是賣存儲的,是以提了這樣一個方案。 實際上,從備,再進一步演化,可以變成oracle的far sync,oracle的far sync隻接受日志不redo Oracle far sync材料: http://www.oracle.com/technetwork/database/availability/farsync-2267608.pdf http://www.oracle.com/technetwork/database/availability/8395-data-guard-far-sync-1967244.pdf
另外,在TP裡面,資料量沒那麼大,對可用性要求更高,從備就顯得有點雞肋了。是以在TP V1R5的設計裡面,徹底去掉了從備。至少是1主2備。
2.3.2 資料複制
在PG單機時,主備資料同步通過XLOG事務日志同步。在大量寫事務場景下,會産生大量的XLOG日志,主機需要先将XLOG下盤,然後日志同步程序讀取XLOG發送給備機,備機收到XLOG日志後下盤,然後恢複程序讀取日志進行REDO。這個過程主備一共有兩次寫IO和兩次讀IO請求。 在OLAP場景中,普遍資料量都很大,并且很多場景往往隻需要查詢某張表中的某一列資料,這樣通常采用列式存儲格式。不僅有利于性能提升,并且按列存儲,資料格式一樣,非常利于壓縮,節省存儲空間。由于按列存儲時,如果再按行存儲方式去導入一行記錄一條日志,那麼性能将非常慢,如果沒有日志,将無法實作主備同步目的,是以需要探求一種新的資料同步方式。 基于上面兩方面考慮,我們設計了資料複制通道,即資料導入到DN後,組成一個個最小存儲單元(行存按頁面大小8K為機關,列存按CU大小8K為機關),然後發送給備機,備機接收到後,将資料寫盤,并回複主機寫盤資料邏輯位置(主機發送時,給每個資料單元設定一個uint64位單調遞增的偏移位置,類似于XLOG中的LSN),主機在事務送出前,如果該事務要求寫盤資料已經傳輸給備機,那麼即可送出。 主要設計架構:
主備複制過程中,XLOG複制和資料複制并行傳輸,備機接收後,并行寫盤,對于日志恢複drop table 或truncate table檔案類操作時,兩者通過表級鎖來控制并發。 日志複制:主機記錄XLOG後,會定期寫到磁盤上,WalSend線程會讀取磁盤上的日志,通過TCP網絡發送給備機WalReceiver線程,該線程接收後會寫到一個記憶體隊列中,WalRecWriter線程定時從隊列中取出來寫盤,并更新備機寫盤LSN,WalReceiver線程回複主機消息時把該值發送給主機。恢複日志線程定期讀取磁盤上XLOG對日志進行REDO。 資料複制:資料複制隻有在行存批量導入資料和列存導入資料時觸發,資料導入後,存儲層将多個資料tuple組成一個個資料最小存儲單元,并将其發到發送隊列中,DataSend線程将從發送隊列中取資料通過TCP網絡發送給備機DataReceiver線程,該線程接收資料後會寫到一個記憶體隊列中,由DataRecWriter回複主機消息時将該值發送給主機。資料複制過程中資料直接由DataRecWriter寫盤,不需要恢複日志線程去恢複資料
3. 叢集管理端高可用設計
3.1 CMserver高可用
CMServer在叢集中隻有一個,如果主機故障後,需要備機來接管服務,是以它和GTM類似,需要配置一個備機,避免單節點故障。 CMserver上存儲了目前叢集狀态資訊(執行個體主備狀态),這些資訊需要實時同步給備機,避免主機故障後,備機無法精确仲裁。CMserver主機與備機有常駐的心跳線程,叢集狀态資訊通過該線程同步。 由于叢集狀态資訊比較簡單,如果CMserver備機永久故障後,隻需要重新初始化一個備機出來,連接配接主機同步資訊即可。
3.2 CMagent高可用
CMagent負載收集本地實體機中核心端各個元件的狀态資訊,并上報給CMserver,由于CMagent制管理本地實體機,如果單節點故障(如斷電,機器故障)後,該實體機上執行個體均故障,無法管理,是以也不需要備機。且CMagent本地并不存儲任何資訊,是一個無狀态元件,程序故障後,可以立刻拉起。