2005 年 12 月 28 日 在IBM WebSphere Information Integrator產(chǎn)品系列中提供了新的數(shù)據(jù)庫復(fù)制產(chǎn)品--Q復(fù)制,Q復(fù)制的架構(gòu)提供了數(shù)據(jù)復(fù)制所需要的高性能(高事務(wù)量,低延時(shí))。本文是作者在實(shí)施Q復(fù)制項(xiàng)目的經(jīng)驗(yàn)積累,希望能夠?qū)?zhǔn)備實(shí)施Q復(fù)制的用戶們有所幫助。 在IBM WebSphere Information Integrator產(chǎn)品系列中提供了新的數(shù)據(jù)庫復(fù)制產(chǎn)品,因?yàn)槠洳捎昧薓Q所以稱為隊(duì)列復(fù)制或Q復(fù)制,Q復(fù)制的架構(gòu)提供了數(shù)據(jù)復(fù)制所需要的高性能(高事務(wù)量,低延時(shí))。 盡管IBM有相應(yīng)的紅皮書對(duì)Q復(fù)制的配置和性能調(diào)優(yōu)進(jìn)行了闡述,但在實(shí)際的Q復(fù)制項(xiàng)目實(shí)施或技術(shù)支持過程中筆者積累了不少的實(shí)際經(jīng)驗(yàn),有些是書中未提及的,在此筆者做一個(gè)小的總結(jié),希望能夠?qū)?zhǔn)備實(shí)施Q復(fù)制的用戶們有所幫助,同時(shí)本文也闡述了一些Q復(fù)制的技術(shù)底層細(xì)節(jié),能更好的幫助大家理解Q復(fù)制。另外對(duì)DBA來講可能對(duì)MQ有些陌生,所以最后列出了一些Q復(fù)制中常見的MQ錯(cuò)誤,希望能有所幫助。 Q復(fù)制是一種高吞吐量、低延遲的復(fù)制方法,它使用WebSphere MQ的消息隊(duì)列在源數(shù)據(jù)庫與目標(biāo)數(shù)據(jù)庫之間,或者在源子系統(tǒng)與目標(biāo)子系統(tǒng)之間傳遞事務(wù)。Q Capture程序通過讀取DB2的恢復(fù)日志來獲取你所指定的復(fù)制源表的變化情況;繼而,Q Capture程序?qū)⑹聞?wù)作為消息,通過隊(duì)列發(fā)送;最后,Q Apply程序從隊(duì)列中讀取這些消息,并將其應(yīng)用于目標(biāo)表。 Q復(fù)制具有以下幾個(gè)優(yōu)點(diǎn):
Q復(fù)制系統(tǒng)在性能方面具有很大的伸縮性,在不同的配置方案下Q復(fù)制系統(tǒng)的吞吐量和端到端的延遲都有很大變化。IBM的Redbook-《Integrator Tuning for Replication and Event Publishing Performance》中對(duì)Q復(fù)制系統(tǒng)的性能調(diào)優(yōu)進(jìn)行了詳細(xì)的闡述,有興趣的讀者可以參閱,不過筆者在實(shí)際實(shí)施Q復(fù)制的項(xiàng)目中發(fā)現(xiàn),還有一些因素也影響著Q復(fù)制的配置及性能調(diào)優(yōu),書中并未提及或給予詳盡的討論,在這里筆者就如下方面進(jìn)行一些討論,算是一點(diǎn)補(bǔ)充供大家參考:
Q復(fù)制系統(tǒng)拓?fù)浣Y(jié)構(gòu)與性能 提高Q復(fù)制性能最顯著的手段,根據(jù)我們前面提到的白皮書里所論述,是啟用多實(shí)例的Q復(fù)制,尤其是在在多CPU的系統(tǒng)中,據(jù)官方測(cè)試數(shù)據(jù)表明,每增加一個(gè)Q Capture實(shí)例會(huì)帶來50-70% 的性能提高,可見其效果還是非常明顯的。但實(shí)施多實(shí)例Q復(fù)制需要遵循如下的原則:
可見啟用多個(gè)實(shí)例的Q復(fù)制最重要的一個(gè)前提是需要根據(jù)你的事物交易組織你的源數(shù)據(jù),即將源端的數(shù)據(jù)表按照交易分組,每一組數(shù)據(jù)表只能屬于一個(gè)Q Capture實(shí)例,用同一個(gè)復(fù)制隊(duì)列圖進(jìn)行復(fù)制,對(duì)應(yīng)的唯一的Q Apply端接收消息并處理同一個(gè)事物交易信息。 Q復(fù)制系統(tǒng)的最小復(fù)制單元是單個(gè)的交易,對(duì)于單個(gè)交易的Q復(fù)制性能來講,多實(shí)例系統(tǒng)對(duì)其是沒有作用的,啟用多實(shí)例提高的是Q復(fù)制系統(tǒng)處理多個(gè)交易的并行性。多實(shí)例的Q復(fù)制系統(tǒng)實(shí)施需要了解數(shù)據(jù)庫的邏輯結(jié)構(gòu)和應(yīng)用的業(yè)務(wù)邏輯,這在實(shí)際實(shí)施中需要額外的計(jì)劃成本。在筆者實(shí)施的一個(gè)Q復(fù)制系統(tǒng)中,源和目的端都只有一個(gè)數(shù)據(jù)庫,系統(tǒng)中運(yùn)行著多個(gè)業(yè)務(wù)系統(tǒng),某些表在業(yè)務(wù)A中沒有聯(lián)系,但在業(yè)務(wù)B中卻關(guān)聯(lián)在某個(gè)交易中,這樣按照業(yè)務(wù)交易分組就很難實(shí)現(xiàn),所以經(jīng)權(quán)衡決定建立單個(gè)實(shí)例的Q復(fù)制系統(tǒng),并將性能調(diào)整集中在單實(shí)例的Q復(fù)制程序和MQ的配置上面。
在實(shí)施Q復(fù)制系統(tǒng)期間,筆者發(fā)現(xiàn)在某一特定時(shí)間內(nèi)系統(tǒng)端到端的延遲很高,無論怎么調(diào)整commit_interval、memory_limit等參數(shù),系統(tǒng)延遲依然居高不下,查看監(jiān)控表發(fā)現(xiàn)此時(shí)系統(tǒng)的單個(gè)交易達(dá)到了最大值,調(diào)研業(yè)務(wù)系統(tǒng)后知道此時(shí)系統(tǒng)運(yùn)行的是一個(gè)刪除數(shù)百萬條記錄的單個(gè)超大交易,此前在紅皮書中已經(jīng)提到,Q復(fù)制的相關(guān)參數(shù)調(diào)整對(duì)單個(gè)交易的復(fù)制性能是沒有作用的,盡管我們可以增大內(nèi)存,但是收效甚微。是不是對(duì)這樣的交易我們就沒有辦法了呢,分析對(duì)應(yīng)得數(shù)據(jù)表的結(jié)構(gòu)我們發(fā)現(xiàn)數(shù)據(jù)表沒有索引,在WII Q Rep V8.2.2(FixPack9)之前,如果一個(gè)數(shù)據(jù)表沒有唯一索引那么它是無法建立Q預(yù)定進(jìn)行復(fù)制的,在V8.2.3(FixPaxk10)后去掉了此限制,表有沒有索引對(duì)Q復(fù)制性能的影響是怎樣的呢?我們先做一個(gè)測(cè)試(這里我們暫且只考慮一般的索引,并不是每個(gè)表都會(huì)有唯一索引的): 給定一個(gè)數(shù)據(jù)表RYAN.T1在源數(shù)據(jù)庫和目的庫,結(jié)構(gòu)如下: ![]() 兩邊的表都有一萬條記錄并且相同,在源數(shù)據(jù)庫端用DELETE命令清空數(shù)據(jù)表,用Q復(fù)制系統(tǒng)來復(fù)制這樣一個(gè)大的交易,然后在兩端的數(shù)據(jù)表SID列上加上索引,重復(fù)上述復(fù)制過程,對(duì)比兩種情況下的延遲信息,測(cè)試結(jié)果如下圖: 圖1 索引對(duì)延遲的影響對(duì)比圖 ![]() 加上索引后系統(tǒng)端到段的延遲提高了11倍之多,其中最顯著的是APPLY的延遲大大降低了,這是為什么呢?我們?cè)僮饕淮卧囼?yàn),再復(fù)制的同時(shí)截取兩種情況下的MQ中的消息進(jìn)行對(duì)比,下圖是兩種情況下的MQ消息片斷: 圖2 帶索引的數(shù)據(jù)表在Q復(fù)制中的MQ消息 ![]() 圖3 沒有索引的數(shù)據(jù)表在Q復(fù)制中的MQ消息 ![]() ![]() 從表1的對(duì)比我們就可以得出結(jié)論,如果數(shù)據(jù)表具有索引,盡管交易是大小一樣的,但在有索引的情況下,對(duì)于每一行刪除的記錄只需在消息中記錄該行的索引信息,而對(duì)于沒有索引的數(shù)據(jù)表,Q復(fù)制系統(tǒng)將其該行的所有記錄都記錄下來作為索引信息,這樣單個(gè)記錄的大小就增大了許多。在同樣大小的消息體中,有索引的情況下每條消息包含了2339條記錄信息,而沒有索引的情況下只僅包含528條記錄,所以前者只需5條消息就復(fù)制了整個(gè)交易,而后者需要20條之多。 在有索引的情況下,復(fù)制單個(gè)交易所需要的消息個(gè)數(shù)減小了許多,這樣MQ的延遲就會(huì)降低,再Q(mào) Apply端一方面需要處理的消息減少了,同時(shí)Q Apply根據(jù)索引消息去更新目標(biāo)表,速度無疑又快了很多,這也就是Apply的延遲顯著降低的原因。 在一個(gè)交易吞吐量比較大的系統(tǒng)中,如果對(duì)Q復(fù)制系統(tǒng)和MQ進(jìn)行調(diào)優(yōu)還是無法降低延遲,這時(shí)你可以考慮是否系統(tǒng)中是否存在單個(gè)大尺寸的交易,并通過增加索引等相應(yīng)手段降低單個(gè)大交易的復(fù)制延遲,從而在降低整體Q復(fù)制系統(tǒng)的延遲。 另外,調(diào)整目的數(shù)據(jù)庫端和數(shù)據(jù)庫性能有關(guān)的參數(shù),提高Q Apply應(yīng)用事務(wù)的效率,例如調(diào)整目的端數(shù)據(jù)庫的緩沖池,Q Apply程序?qū)δ繕?biāo)數(shù)據(jù)庫有大量的寫操作,所以在目標(biāo)數(shù)據(jù)庫上需要建立滿足性能需要的足夠多,足夠大的緩沖池。而且最好為Q Apply 控制表所在的表空間建立單獨(dú)的緩沖池,這樣無疑會(huì)收獲更好的性能。
Q復(fù)制選擇MQ 是因?yàn)镸Q可以提供可靠性的消息傳輸,MQ有兩種類型的消息,永久性的消息是通過MQ的日志記錄在磁盤上的,而非永久性的消息是存儲(chǔ)在內(nèi)存當(dāng)中的,采用非永久性的消息性能會(huì)高很多,但采用永久性的消息才會(huì)有可靠性的保證,在系統(tǒng)出故障或隊(duì)列管理器重啟后消息不會(huì)丟失,這對(duì)于數(shù)據(jù)庫復(fù)制系統(tǒng)的數(shù)據(jù)一致性是非常重要的。 嚴(yán)格來講DEFPSIST是消息的屬性而不是隊(duì)列的屬性,不論你是否將隊(duì)列設(shè)置成為永久的,只要消息類型是永久的,MQ就會(huì)將消息存儲(chǔ)在磁盤日志文件中。Q復(fù)制系統(tǒng)采用的是永久類型的消息,Q復(fù)制的消息的不會(huì)因?yàn)殛?duì)列管理器的重啟或隊(duì)列故障而丟失,這里我們可以做個(gè)試驗(yàn)進(jìn)行驗(yàn)證: 1. 建立好一個(gè)Q復(fù)制系統(tǒng),其使用的發(fā)送和接收隊(duì)列、通道設(shè)置為非永久性的,并驗(yàn)證Q復(fù)制系統(tǒng)工作是否正常。 2. 停止Q Apply程序,然后在源數(shù)據(jù)庫已經(jīng)建立Q預(yù)定的數(shù)據(jù)表RYAN.T3中插入一條記錄,因?yàn)镼 Apply程序停止,消息將保留在接收隊(duì)列中,從MQ資源管理器可以看到接收隊(duì)列的深度為1,即有一條消息,如下圖所示: ![]() ![]() 3. 用AMQSPUT命令在向發(fā)送隊(duì)列壓入一條字符串消息"ok",這時(shí)接收隊(duì)列的隊(duì)列深度增加1,有兩條消息,用MQ 資源管理器瀏覽接收隊(duì)列的消息,一條是Q復(fù)制的消息,(Q復(fù)制的消息是壓縮(COMPACT)的格式,其內(nèi)容不可見),另一條是用MQ 命令壓入得消息字符串"ok"見下圖所示: ![]() ![]() 4. 重新啟動(dòng)接收端的隊(duì)列管理器,啟動(dòng)后查看接收隊(duì)列的深度,發(fā)現(xiàn)比重啟前減少了1,這表明隊(duì)列重啟后有消息丟失,查看其內(nèi)容,Q復(fù)制的消息依然存在,丟棄的是使用AMQSPUT命令壓入的消息字符串"ok",因?yàn)槠洳]有將消息設(shè)置成永久性的,見下圖所示: ![]() 5. 再次啟動(dòng)Q Apply,接收隊(duì)列的消息被接收處理,查看目的端的數(shù)據(jù)表RYAN.T3,盡管接收端的隊(duì)列管理器被重新啟動(dòng)過,源端RYAN.T3表新增加的一條記錄還是被正確的復(fù)制了過來,如下圖所示: ![]() ![]() ![]() 通過以上測(cè)試我們即驗(yàn)證了消息的永久性是和隊(duì)列的永久性無關(guān)的,同時(shí)也體現(xiàn)了MQ的可靠性傳輸特點(diǎn),當(dāng)然最好將Q復(fù)制使用的相關(guān)隊(duì)列都設(shè)置成永久性的,這樣隊(duì)列里的消息都會(huì)記錄日志,即所有的消息都是永久性的。
上面我們提到了Q復(fù)制系統(tǒng)中的消息都是永久性的,所有的消息都記錄日志,這樣MQ的日志性能就很重要,首先在存儲(chǔ)上考慮將隊(duì)列管理器的數(shù)據(jù)和日志分開,并為其創(chuàng)建單獨(dú)的文件系統(tǒng)可以提高性能,例如: ![]() 并盡可能的讓上述文件系統(tǒng)分配在不同的磁盤上,這樣可以充分利用I/O的并行性。 MQ日志的相關(guān)配置參數(shù)在紅皮書中已有所討論,這里給出更詳細(xì)的優(yōu)化配置參考:
使用線性日志增加了日志維護(hù)的管理負(fù)擔(dān),在筆者實(shí)施的Q復(fù)制系統(tǒng)中,目的數(shù)據(jù)庫是由源數(shù)據(jù)庫備份恢復(fù)而來的,一旦系統(tǒng)出現(xiàn)故障導(dǎo)致同步復(fù)制中斷,可以采用備份數(shù)據(jù)庫恢復(fù)目的庫并重新建立Q復(fù)制系統(tǒng),所以MQ采用循環(huán)日志,并且主輔日志文件的個(gè)數(shù)分別設(shè)置為30、20。
Q復(fù)制系統(tǒng)中最常見的錯(cuò)誤一般都是由MQ引起的,以下列出一些常見的導(dǎo)致Q復(fù)制中斷的MQ錯(cuò)誤及解決措施,以供參考: 1. MQ ERROR 2045:Q Capture 發(fā)出 MQOPEN調(diào)用時(shí)出錯(cuò),即打開隊(duì)列出錯(cuò)??赡艿脑颍?/p>
2. MQ ERROR 2056:Q Capture 發(fā)出MQPUT命令調(diào)用時(shí)發(fā)現(xiàn)隊(duì)列所在磁盤上沒有空間了,一般是因?yàn)槲募到y(tǒng)沒有可用的空間導(dǎo)致,檢查MQ相關(guān)的文件系統(tǒng),如果空間滿了請(qǐng)?jiān)龃罂臻g或刪除不用的文件釋放空間。 3. MQ ERROR 2053:Q Capture 發(fā)出MQPUT調(diào)用時(shí)失敗,原因是隊(duì)列滿了,解決方法: a) 檢查隊(duì)列的最大深度參數(shù)MAXDEPTH,并增大該值。 b) 如果隊(duì)列深度的配置已經(jīng)很大了,請(qǐng)查找隊(duì)列堵塞得原因,一般是因?yàn)镼 Apply的異常導(dǎo)致停止接收消息導(dǎo)致隊(duì)列擁堵。 4. MQ ERROR 2009:與MQ隊(duì)列管理器的連接丟失,隊(duì)列管理器未啟動(dòng)或者異常停止,請(qǐng)檢查MQ隊(duì)列管理器是否正常運(yùn)行。 5. MQ ERROR 2162:當(dāng)進(jìn)行一個(gè)MQI調(diào)用時(shí)失敗了,因?yàn)殛?duì)列管理器正在停止。請(qǐng)檢查MQ隊(duì)列管理器運(yùn)行狀態(tài)。 6. 在某些情況下重新啟動(dòng)了Q復(fù)制系統(tǒng)卻發(fā)現(xiàn)系統(tǒng)不復(fù)制數(shù)據(jù),查看日志也沒有報(bào)錯(cuò),這時(shí)請(qǐng)查看MQ系統(tǒng)的通道狀態(tài)是否正常,一般是因?yàn)镸Q通道的錯(cuò)誤導(dǎo)致無法傳輸數(shù)據(jù)。
|
聯(lián)系客服