天天看點

Greenplum在企業生産中的最佳實踐(上)

本文章轉自pivotal公衆号,在此感謝任振中和pivotal公司的分享,希望對更多的朋友有幫助~

gp是一個分布式x86架構,是把多台x86伺服器組合成一起做一個大的叢集。相比傳統單機版的oracle和mysql,它的特點是使用比較多的伺服器做海量資料處理。

一般在企業客戶中,把x86伺服器采集過來後會做上機安裝,如果企業使用的叢集規模比較大,比如國内客戶最大的有将近128個節點,資料量有1pb。在部署的時候,x86的伺服器會非常多,有超過100台的伺服器。為了保證它整個叢集的高可用、性能,在部署的時候一般是需要跨多個機櫃。

(雙機櫃為一組的部署方式)

對gp來說建議在部署的時候,把伺服器放在多個機櫃上面,如果企業客戶機器非常多,往往是以兩個機櫃為一組。

對于x86伺服器上架之後,接下來就要把x86伺服器組網。對于目前市面上看到的2u的伺服器,在一個機架裡一般都會部署兩個萬兆交換機。對于單台伺服器來說,一塊網卡網口出來都會接入相應的交換機裡面,那麼在主機x86伺服器上一般會使用moved4,也就是雙active的方式做綁定。當任意的網絡故障,就是網口出現故障或者交換機出現故障的時候,都不會對叢集的可用性造成影響。

另外,當叢集規模比較大的時候,在接入組交換機端口可能是有限的,會把接入層的交換機接入到彙聚層,在彙聚層交換機接入的方式和底下的接入方式是比較像的。在接入層交換機上會分出兩個口,分别接入到上層的彙聚層交換機,彙聚層交換機之間也會采用跨裝置鍊路聚合這種方式做綁定。這樣就保證了性能和可靠性。

在企業客戶現有的案例中,目前可以看到的交換機基本上都是支援雙active的綁定方式,一般要在交換機上簡單的把端口做一下設定就可以達到這種模式。

(單個機櫃的部署方式)

對單個的機櫃來說,一般的機櫃是44u,在部署的時候三個機櫃一般會放16台2u的x86伺服器,對于gp架構,需要控制節點,因為它隻是負責中繼資料的存放和請求的解析、分發,是以它一般不需要有非常大的空間,一般建議可以有6塊600g的sas盤,可以做raid10,也可以做raid5,做中繼資料的存放。

對于底下的資料節點,就gp資料庫來說,一般會做海量資料的處理和分析,是以資料節點往往需要承擔大量的資料存儲和計算。建議對于計算節點一般采用2u的伺服器,可以采用24塊600gb或者900gb的sas 10k或者15k轉的盤,根據企業中自己的實際資料去選用磁盤類型。

目前在國内客戶用900g的sas盤居多一些,在一些電信行業,資料量往往比較大,也有一些客戶采用單塊2t的硬碟。一個機櫃裡面也會放兩台萬兆交換機,用于内部的資料互聯,同時也會加一台千兆交換機,用于對于伺服器進行管理。

在劃分網絡的時候,千兆和萬兆的交換機一般都會劃分成不同的網段。對于萬兆交換機的接入,一般采用雙active這種方式,隻給配置設定一個ip段就可以。

在gp底層實際是使用了資料庫,并行的機制是采用了在x86伺服器上部署多台資料庫,然後通過軟體對它們互聯組網,完成整個執行。對于gp來說,它的高可用在企業裡面首先是要保證資料的安全可靠。在規劃時,在gp預設情況下,可以選擇有沒有備份的資料,就是有沒有mirror。gp隻有兩種方式,要麼有mirror,要麼沒有mirror。有mirror的話,資料擺放的時候就可以指定mirror具體的擺放方式。對于gp來說,預設的擺放方式是采用group的方式。

舉個例子,假如有兩個機櫃,每個機櫃上面有六台x86伺服器,在存放的時候,假如在第一台伺服器上部署了四個primary執行個體,會把對應的mirror節點放在相鄰的伺服器上。第二台primary備份執行個體就會放在第三台節點。那它就是采用這種輪訓打散的方式來做gp的高可用。當任意一台機器挂掉之後,都不會對gp的可用性産生很大的影響。但是帶來的問題是,gp在正常情況下,隻有primary對外提供服務,假如說這個機器挂掉之後,那它對應的mirror就全部切到另外一台伺服器上。這樣對于mpp資料庫,相當于有一台機器要承擔比平時多兩倍的計算工作量。

由于mpp這樣的短闆效應,尤其是在壓力比較大的時候,就會發現整個叢集因為挂了一個節點,就會對整個叢集性能下降40%到50%的影響,因為它受最慢的節點影響。其他節點都已經計算完了,但這個節點沒有計算完,它就受這個節點的影響。

另外還有一種方式,這個機器上有四個primary執行個體,可以把每一個primary執行個體打散在接下來的四個節點上,相當于每一個機器上隻放第一台機器的一個備份資料。這樣的好處在于,當這台機器挂了之後,相當于有四台機器分開承擔原來一台機器的工作點。整個叢集的性能最多情況下相比原來,可能就下降了25%。但是對它來說,采用這種方式,在挂了一個節點之後,如果這四個機器裡面再有任意一個節點挂掉,那整個叢集就不可用了。就是在gp裡面如果是主備資料同時挂掉,那整個叢集就會報錯,我們發的所有sql都會異常退出。

一般在企業裡面部署的時候,這麼去考慮的話,會采用group+spread的方式去部署。舉個例子,p1、p2、p3、p4,放在第一個機櫃的第一台x86伺服器上,可能就是以兩個為一組,分開部署在第二個機櫃的這兩台機器上。這樣的話,假如說當第一個機櫃的一台伺服器挂掉之後,在這邊會有兩台伺服器完成原來有一台機器的工作,對整個叢集的性能下降不會造成很大的影響,同時也兼顧了高可用性。

目前在一些大的銀行裡面,尤其是當叢集規模比較多的時候,一般都是采用group+spread的方式。但是在一些隻有十幾個節點的客戶裡面,一般還是采用group的方式去做執行個體的規劃。

剛剛講過,在x86伺服器裡,一般企業客戶都會采用sas盤或者sata盤去做,因為容量會比較大。gp主要的場景是做海量資料的分析。一些電信客戶裡面也會涉及到一些明細資料的查詢,比如說在某省的移動客戶,會涉及到使用者的一些詳單的查詢。因為在底層硬體上選用了sata盤,即使用了24塊,它的iops還是比較低的,一般sata盤的iops隻有100到200左右,當并發的分析,比如跑報表的分析應用和小的并發的查詢過來之後,就會發現對于使用者詳單查詢會有很大的影響。當時它做了很多的調優工作,包括底層用了gp的資源隊列,甚至還用了作業系統的cgroup,對io做了限制。但是效果都不太理想。因為cgroup也是通用采樣的方式,在一個周期裡面會控制io使用。但是對于一些大的查詢,如果把io占滿之後,還是會對整個叢集使用造成比較大的影響。

一般推薦客戶使用一些比較高的并發查詢,就是小的io查詢時,一般會推薦使用ssd的裝置,在gp層面在建表的時候可以指定哪些表放在ssd上,哪些表放在sata盤上,真正實作底層的io隔離,以避免不同的業務之間造成影響。

Greenplum在企業生産中的最佳實踐(上)

硬體選擇--磁盤

底下這兩個就是ssd和sata盤,在iops尤其是在小的io上面,ssd比sata盤有非常大的優勢,一般情況下來看對于ssd的裝置,它的iops往往是sata盤的幾十倍甚至到一百倍,但是對于這樣一個大的io查詢,比如像海量資料掃描來說,相比傳統的sata盤并沒有非常大的提高。對這個資料來說ssd性能比較差,也是屬于比較老的ssd裝置。

目前在企業裡看到的一般的ssd的吞吐能到600mb/s到900mb/s的速度,但是iops基本上在30萬左右。如果企業裡面确實有對于小io的高并發的查詢類的場景,建議在x86伺服器裡采用ssd和sata混搭的方式,然後在gp層面真正在底層硬體上隔離實體資源。

對pcieflash這種裝置,在企業裡面、在數倉裡面用到的還不多,因為一個是插槽有限,另外成本也非常高。對于網絡互聯裝置來說,gp一般建議使用普通的以太網絡,通過使用萬兆交換機,把多台伺服器組合在一起來使用。

有的客戶,比如某電信使用者,已經采購了這樣的裝置,就想看看能不能在數倉系統裡把gp接入進來,當時遇到的情況是,因為gp在底層是使用的tcp/ip通信協定,是以即使有高速網絡互聯裝置,要去接入的話,還需要用一層ipoip的一些協定去做轉換。一方面是會帶來一些性能的損耗,另外一方面當時的測試也不是特别穩定,因為網卡驅動的問題,導緻伺服器經常當機。是以說在gp裡面一般都是根據具體的業務場景,主要的場景就是這種海量資料的大的順序io的讀寫操作,一般是建議采用24塊盤的sas盤或者sata盤,做底層的存儲。對于有這種海量的小的并發查詢的時候,也可以采用ssd。

磁盤選完之後,就要涉及到raid的劃分,在gp軟體層面本身的高可用隻是保證了最多有一份資料備援。在底層,gp和hadoop不一樣,gp一般會建議底層的資料節點采用raid的方式,在企業裡面往往使用最多的兩個raid方式,raid5和raid10。

在容量上來說,舉個例子,下圖是某銀行客戶當時做了非常詳細的raid組的測試,這是在十塊sas盤做了大的raid5,另外一個是做了raid10。raid5和raid10相比最大的優勢,一個是在容量方面,因為raid5假如有10塊900gb的盤,那隻需要丢掉一塊盤的容量,還有9t的空間。對于raid10來說,基本上是需要丢掉一半的存儲空間。在具體的性能上來看具體的資料,在讀寫性能上正常情況下十塊盤讀寫資料raid5都要好于raid10。

Greenplum在企業生産中的最佳實踐(上)

raid5 vs raid10 順序io測試對比

但是在真實的業務場景當中就會發現磁盤io往往不會一直持續100%,繁忙程度不會到100%的程度,是以說根據在企業裡具體的觀察,跑真正的sql查詢的時候,raid5和raid10并沒有非常大的明顯的差異。

在空間使用率上來說,在底下的磁盤空間,使用率占到70%之後再通過gp check做磁盤性能的檢測,就會發現它的性能大概下降了有20%左右,包括讀寫性能。這是因為在空間使用非常多之後,可能磁盤外側空間已經使用完,另外一方面,在檔案配置設定上面也會有一些性能的損耗,是以說當你空間使用超過70%之後,對于數倉類的應用也會造成一些影響。是以建議企業客戶伺服器磁盤空間不要超過70%,一方面是從性能考慮,另外一方面在查詢的時候,還會有一些中間的結果也會用一些臨時的空間。

對于做raid之後,尤其是對企業的性能還是有非常大的影響的,因為raid卡本身在資料寫入的時候,會先寫入到raid卡的cache裡面,後面就是通過raid卡硬體再把它刷到真正的底下的磁盤裡面。如果沒有raid卡cache的話,對不管是raid5還是raid10,對寫的性能都會造成比較大的影響。

比如一個客戶它的資料規模比較小,從兩個節點擴到四個節點,完成擴容之後發現機器數增加了,并且每個機器上的資料量減少了,但是性能還沒有之前兩個節點跑得好。原因在于他們新采購的機器沒有raid卡cache,導緻新的機器io性能下降非常嚴重。因為這個就是mpp短闆效應造成了整個叢集的性能比較大的下降。

對于raid5和raid10來說在壞掉一塊盤的情況下,由于在讀的時候,raid5需要通過其他盤去重新建構資料,是以當壞掉一塊盤之後,raid5比raid10性能會下降非常多。對寫的性能也會有一些下降,但沒有讀的性能下降得厲害。

另外,比如壞了一塊盤,又拿了一塊新盤頂上去之後,在review的過程當中,對raid5讀和寫的性能也會有一些比較大的影響。現在一般的raid卡做得比較智能,前台有正常的io操作,背景就會把review的操作暫停掉,等正常的io下來之後,背景再做。但是對于raid5和raid10,以具體的測試情況,大的順序io來說,raid5的讀寫性能還是要好于raid10,但在異常情況下,它的性能會掉得比較厲害。是以具體到企業客戶,還是根據這樣的場景去選擇raid5和raid10。

如果對性能包括容錯性要求比較高,不管在任何情況下都要對性能不會造成非常大的影響,這時候一般建議還是用raid10;如果沒有這樣嚴格的要求,往往是從成本和容量、性能來考慮的話,在gp這邊還是推薦使用raid5。目前國内客戶中,采用raid5是最多的方式。

剛剛對于底層磁盤raid5和raid10的性能進行了比較,對于gp來說,具體可以看一下在不同的故障場景下,對性能到底有多大的影響。

Greenplum在企業生産中的最佳實踐(上)

raid5 vs raid10 故障場景下對gp性能的影響

對于在cache失效的情況下,對于raid10來說,它的性能大概隻有3%、4%的性能下降。但是對于一塊硬碟壞掉之後,因為它對讀的性能會有一些影響。當raid10有一塊硬碟壞掉的話,它的性能大概下降了20%左右。對于raid5來說,一塊盤壞掉之後,有這樣大量的io讀寫的話,整個叢集的性能将近下降了一倍還要多一點。

在36個節點上有60萬張表,做的測試是分别模拟,先把mirror的事例給停掉,測了一下它的性能,隻是把mirror停掉的話,對性能影響基本上沒有太大的影響。但當一個節點挂掉之後,如果采用group這種方式,因為它的壓力完全會有另外一台機器去承擔。當這個叢集本身的負載非常高的時候,就會看到整個叢集的性能可能就要下降一半還要多一點。

很多客戶認為在硬體異常的過程當中發現底下的資料節點不同步,要執行gprecoverseg的話,還要跑作業。因為在做recoverseg時,底下的節點已經有一些問題了,那它在做同步時,本身也會有一些大的io和資源的消耗,是以它對叢集的性能會下降得比較多。是以在真實的生産環境裡面,比如說節點挂掉之後,一般會建議客戶在有空閑的時間視窗,比如大的批量跑完之後,再去趕緊把gprecoverseg做一下同步。因為gp底層是做的增量塊的複制,同步的速度還是比較快的。

當有一個節點當機之後,在跑的性能。整個建議是,在真實的業務場景中,raid5在跑數倉類的場景裡面,真實的業務io不會一直持續100%,是以raid5和raid10對真實的業務影響并不是特别大。但是當硬體壞掉之後,raid5的性能下降比較多,會對叢集有比較大的影響。另外,系統空間使用盡量不要超過70%,超過70%之後也會有一些影響。

對于raid卡的cache來說,建議在采購的時候,還是要采購有cache的raid卡裝置。另外,盡量要使用壓縮表,因為在gp裡面使用壓縮表的話,一般情況下根據資料的規律性,壓縮級别一般是在3到5左右,這樣的話就可以通過cpu換io的方式去節省底下的一些io。在企業中基本上使用這種壓縮表在大的查詢裡面,往往會帶來性能的提升,因為cpu的計算性能相比io是要快很多很多倍的。

下面重點講gp的同步原理。這個圖是用了阿裡雲之前的blog裡面的一個圖案。在gp裡面它是有master這種架構,在master節點上,使用者連到gp之後,背景會起相應的back程序的處理使用者的請求。當比如有建表或者删表或者更新資料字典的操作的時候,是通過postgres的wal日志流複制的方式,比如說建立一個表,就會先把這個日志寫到buffer裡面,然後再刷盤。這邊會有新的程序然後同步到standby節點,standby節點也會把日志刷到磁盤上。

Greenplum在企業生産中的最佳實踐(上)

greenplum資料同步原理

對于gp中繼資料的同步,是采用了postgres原生的流複制的方式,是強同步的方式,就是中繼資料這種變更的時候,一定是它這邊真正刷盤成功之後,才會認為寫入的動作成功。是以在中繼資料這塊,是能保證絕對的可靠性,假如master挂掉之後,那這個standby程序會讀postgres程序,做回訪,應用到standby資料。當異常情況的時候,叢集會重新拉起來的時候,也會用xlog做恢複,這樣就保證了中繼資料的安全和可靠。

對于底下節點來說,gp是采用自己的一套塊資料的複制方式,怎麼來了解呢?當有資料插入或者變更的時候,當這個資料要真正刷盤之前,在寫入磁盤之前,它會截獲到資料的變化,然後會把這個變化同樣是通過這個程序發到對應的mirror節點,mirror節點背景會有相應的consumer的程序,包括heap表,來做相應的寫盤動作。對于整個來說,隻有mirror節點,把這個資料寫成功之後,才會傳回給primary節點,告訴它資料已經寫成功了,就是真正背景會有一個刷盤的動作。

在gp整個的資料庫裡面,不管是從master節點還是底下的資料計算節點,是能保證資料的強一緻性的。在任何情況下,比如機器突然掉電的情況下,不會出現切到mirror之後發現已經送出的事物丢失的情況。後面具體講一下它背景的程序。

Greenplum在企業生産中的最佳實踐(上)

greenplum主節點同步原理

這個就是說對于master和standby節點,當一個事物在提、把wal刷盤的時候,它就會先把資料同步到standby節點,standby節點會寫到本地盤上,然後再傳回,告訴它表示已經寫成功了,最後會傳達到用戶端請求已經成功,整個在中繼資料這塊是通過wal的流複制保證資料的安全可靠。

對于底下的計算節點,同樣是當有大的資料插入或者更新來說,有一個wal replication的程序,當這個資料要寫盤的過程當中,會根據ao表還是heap表,會從不同的buffer裡面會納入到塊的變化。比如說要刷盤的時候,這個replication的程序會通過新的程序把資料通過tcp/ip這個協定發到mirror節點,mirror節點拿到這個資料之後,也會先把它放到它的記憶體裡面,然後有相應的consumer程序把它寫到對應的底下的檔案系統上,之後會有一個act程序,告訴primary節點,說資料已經寫入成功了,通過這樣的一個完整的鍊路,告訴primary節點,說這個時候也可以把事物送出,完成整個的動作。

Greenplum在企業生産中的最佳實踐(上)

greenplum資料節點同步原理

它就是通過這種方式,類似管道的方式,在資料真正寫盤之前,在primary節點寫盤之前,就是通過這種強一緻的刷盤的動作,不管是ao表還是heap表,都會通過強制的刷盤動作,保證資料的絕對安全、可靠,就是任何情況下機器斷電等等情況下都不會造成資料的丢失。這也是為什麼gp在金融客戶有非常非常多的應用案例的原因,就是它不管是從原資料還是底下的資料節點,都能保證資料的絕對的安全可靠。

在一個節點上看一下它對應的mirror節點。mirror節點是它隻負責底下計算的資料的備援,正常情況下是不承擔任何的計算負載,隻有當primary節點挂掉之後,它會自動切到這邊做相應的激活,就是切換成primary的角色。

它其實有三個最重要的程序:

mirror consumer process主要負責xlog的寫入和控制檔案,因為在寫入之後,比如做檢查點之後,會更新相應的控制檔案。它主要是負責xlog的寫入。

負責heap表的寫入,對于heap表的寫入是通過xlog日志,就是通過xlogdump提供的工具,當資料寫入之後,比如在heap表裡插入之後,會解析它背景到底是做了什麼樣的動作。解析後可以看到當有heap表插入時,會馬上在對應的mirror把wal日志寫到相應的磁盤上。對于底下來說,去跟蹤剛剛提到的heap表的consumer程序,真正的資料檔案的寫入,在write的時候,底下并沒有看到有think的動作。因為write的時候,它隻是把資料從buffer裡寫到檔案系統cache裡面,并沒有确定資料一定是刷到磁盤上的。

對于heap表的寫入,隻是保證了xlog在mirror節點的寫入,但是對于真正的資料檔案并不是一個強同步的過程。但是在做checkpoint時會發現heap表也會刷到這個磁盤上,但是通過這種方式已經能保證對于heap表的寫的操作一定是一緻的,因為對于heap表的xlog已經寫到磁盤上,那就是挂掉之後,大不了再用xlog做一下恢複就可以了。這樣的話,對于heap表寫入操作完成之後,資料在mirror上絕對是不會丢掉的。

負責ao表的寫入動作。ao表的插入跟heap表有不一樣的地方。因為在gp裡面,ao是用了自己另外一套機制去實作的,是以它可以做壓縮等等。但是它裡面對于appendonly表另外還有一些heap表作為輔助的資料字典,比如pg-fastsequence和aoseg,就是它上面的一些索引和原資料的記錄資訊。對于ao表的這些輔助的一些資料結構,在gp裡面也是采用heap的存儲方式。

當在ao表裡面去插入的時候,去跟蹤一下剛剛提到的xlog的寫入程序會發現它也會寫xlog日志,但是它寫入的是ao表,就是appendonly表對應的heap的資料字典的一些資訊,真正的資料是通過mirror consumer appendonly process去寫到磁盤上的。就是對于ao表的寫入,比heap表要稍微複雜一點,就是它在寫入的過程當中,同步是要包括一些xlog的一些寫入,同時也包括一些本身的資料寫入。

對于ao表來寫入的話,把ao表插入的時候不用做commit去跟一下程序,它在寫入的時候,把資料檔案寫到檔案系統cache之上,會馬上調一個fsync,這樣的話對于ao表的資料是會馬上寫到底下的磁盤上的。是以對于ao表來說,它也是通過自己内部的機制,保證了資料在寫入的過程當中是強同步的刷盤動作,保證了資料的可靠。

另外,對于剛剛提到的寫xlog的consumer程序,不管是對heap表還是ao表寫入,都會有相應的寫入,寫入之後緊接着會有一個fsync的動作。對于ao表的話,也是寫入之後馬上就會有一個fsync的動作。是以說對于gp來說,對于底層的資料存儲,不管是heap表還是ao表,通過xlog日志和本身的appendonly表的寫入機制,保證了兩邊資料的絕對安全可靠。

對于gp來說,一般遇到的問題歸納起來主要可以分為兩類。一類就是性能的下降,還有一類是異常情況。比如說在做一些操作報錯的情況。一般情況下在做問題定位分析,相比傳統的oracle、mysql的單機的資料庫來說,因為它的叢集規模比較大,往往涉及到幾十甚至上百台規模,定位起來可能還是需要一些技巧。比如這個叢集突然慢了,原來跑十幾分鐘的sql,現在跑一個小時都還沒有結束。那這個時候怎麼去定位分析這個問題呢?

第一步就是首先要确認這個慢到底是慢在什麼地方,在檢查的時候,因為有的節點執行快的話,最後的程序的狀态是不一樣的。通過outsql的視圖檢視一下,看這個sql還有哪個節點沒有執行結束,或者通過gpssh也可以跳到所有的節點上,去看一下它的負載,看一下它的連接配接狀态。就先定位到哪個也點慢了,影響到機器。

接下來可以看一下這個圖上的工具,基本上是自帶的一些工具,比如說通過vmstat看記憶體,通過top看程序,通過iostat看io的,就是通過linux系統的一些指令,再具體的去分析,這個程序hang是因為什麼,是不是底下硬體損壞導緻性能下降,還是其他的一些情況導緻的。

另外,比如跑了一段時間,發現跑所有的sql都會有這樣的性能下降,在叢集跑了一段時間之後,可以用gp自帶的一些工具,比如說gpcheckperf、gpcheckcat等工具檢查一下整個叢集之間的性能,包括網絡、磁盤、io等等,去定位是不是有硬體性能的下降。