在本系列文章的前兩篇對高可用性的意義和單實例下的高可用性做了闡述。但是當隨着數據量的增長,以及對RTO和RPO要求的嚴格,單實例已經無法滿足HA/DR方面的要求,因此需要做多實例的高可用性。本文着重對SQL Server的復制進行闡述。
復制?
復制起初並不是用於作為高可用性功能而設計的,實際上復制的概念就像其名稱一樣,用於復制數據。比如將某個庫中的數據“復制”到另一個庫,到另一個實例中,由OLTP復制到OLAP環境中,由某數據中心復制到位於地球另一側的另外一個數據中心中。因此,由於復制所提供的功能,復制可用被用來剝離負載,用於做數據冗余,直至把復制用於作為高可用性拓撲中的一個環節。(切記,復制的功能可以被用做高可用性,而不是復制是高可用性功能。)
不同於其它SQL Server可以被用作高可用性的特性,復制可以做的非常靈活。您可以復制某些列,過濾某些行,復制表中的部分數據。復制是基於數據庫對象的,而不像日志傳送、鏡像、集群、AlawysOn等需要以庫和實例作為基本對象,此外更新的訂閱還允許訂閱端合並數據,沒有任何一種其它的高可用性技術能做到這一點。
復制的基本概念
關於復制的基本概念,我在之前已經有一篇文章進行了闡述:http://www.cnblogs.com/CareySon/archive/2012/06/20/IntroductToSQLServerReplicationPart1.html。但這里我還是想再次對基本的概念進行闡述。
復制的模型參考的雜志發布的模型,由出版社發型雜志,由經銷商分發雜志,由訂戶來消費這些雜志。這個概念看似簡單,但可以歸結出復制下面一些特點:
- 雜志社是否大,比如說全國發行的雜志需要總代理(單獨分發服務器),而一個機關內部發型的文章直接在雜志社(發布服務器和分發服務器在同一台服務器)消費
- 是由訂戶去經銷商自取(訂閱服務器去分發服務器請求訂閱),還是由經銷商送到訂戶那里(分發服務器推送到訂閱服務器)
- 是一次性訂閱一本書(快照發布),還是每當有新的文章后就發給訂戶(事務訂閱)
- 雜志會首先到達經銷商那里,然后再給訂戶(數據會在分發服務器那里轉存,一定時間過后,則丟棄暫存的數據)
- 經銷商保留多久就處理掉過期期刊(分發服務器數據保留時間)
- 出版社不可能僅僅將雜志發布給某個訂戶看,而是會給多個訂戶看(一個發布可以允許多個訂閱,但要考慮性能問題)
- 從出版社發型文章到經銷商再到訂戶需要一定時間(發布服務器到分發服務器到訂閱服務器可能存在5秒10秒15秒等延遲,因此事務復制不能用於做熱備,只能用於做冷備和暖備)
- 出版社到經銷商到訂戶中間可能存在雜志丟失的問題,原因可能是由於出版社的問題,快遞的問題,經銷商的問題,由於環節比較多,不太容易找出問題(復制相對難以調錯)
復制的幾種類型
下面來簡單介紹幾種復制類型在高可用性中可以作為的角色。
快照發布
快照復制本質上就是通過快照目錄(共享目錄)共享一堆文件(因為需要多個訂閱端共享),在早起版本,快照復制僅僅是一個文件,而相對更新的版本,復制會將文件分為多個。快照就是文章某一時間點發布的Article
是一種創建報表數據庫的好方式。
對於快照復制的簡單概念,如圖1所示。
圖1.快照發布的概念
事務復制
在初始化訂閱后(可通過快照初始化,或者由備份初始化,請參閱:http://www.sql-server-performance.com/2012/replication-without-creating-snapshot/),由發布服務器上將需要被復制的部分的日志標記為復制.由分發服務器的log reader agent來讀取發布服務器上這部分日志,當分發服務器將所有的日志傳遞給訂閱服務器,則發布服務器上的日志就可以清空了
通過原理不難看出,每個數據庫只能有一個log reader agent,因此數據庫中發布內容過多,或者重復發布,則會產生嚴重的性能問題。此外log reader agent需要讀取所有的日志,不會有任何奇跡發生來跳過那些沒有被標記為復制的日志.因此當對復制的文章進行了篩選的話,會影響性能(這里可不像索引,設置了篩選條件能夠提高查詢速度)。
性能因素取決於很多地方,發布服務器的速度,更改頻率,分發服務器的速度等等。
通常可以用於做實時報表,雖然會有些許延遲,但效果非常好。
合並復制
合並復制可以實現數據的多處更新,當更新沖突時,可以設置規則,比如北京和上海的服務器,我可以設置北京的服務器永遠贏。
Peer-To-Peer復制
P2P復制是基於事務日志之上的一種復制類型,他允許每個節點都成為對等的實體。因此可以非常好的用於HA和負載均衡,即使某一個節點宕機,完全不會影響其它節點的可用性。
自SQL Server 2012以來,PeerToPeer復制已經成為了一種單獨的發布類型。
一個Peer-To-Peer的簡單例子如圖2所示。
圖2.對等復制
從圖2中可以看出,節點A、B、C、D分別對同一份數據保存相同的副本,並且每個節點上都可以進行讀寫操作。我們可以假設每個節點都是在不同的地理位置,因此假如說節點A宕機,則可以直接將應用程序連接字符串重定向到其它節點,實現了高可用性。從圖2中還可以看出,對於任一節點我們都可以進行讀寫操作,因此實現了負載均衡的效果。此外,NodeB進一步將數據發布到只讀服務器上,進一步實現了讀寫分離。
因此,這種方式具有極大的靈活性,和其它高可用性技術結合可以實現多種數據庫拓撲。
在SQL Server 2008之后的版本,當遇見數據更新沖突時,可以通過沖突查看器進行查看並解決沖突,還可以在數據更新沖突出現后,進行報警。
為什么選用復制
每一種高可用性技術都有其自身的優點和缺陷,如果某種技術相較與其它技術只有有點,沒有缺陷,那”其它技術“一定會被淘汰。
相比較其它高可用性技術而言,復制有如下好處:
- 復制是對象級別,您可以僅復制您需要復制的內容
- 復制可以工作在簡單恢復模式下。
- 您可以擁有無限多個訂閱(日志傳送也可以實現,但要考慮到網絡帶寬和性能問題,通常來說,訂閱數量稍微多一點就要考慮請求訂閱,將Distribution Agent的負載OffLoad到訂閱服務器)
- 復制允許在高可用的另一端(也就是用於冗余的一端)進行更新,沒有其它高可用性技術可以做到這一點
- 在故障轉移的時候,不需要Redo或Rollback日志,只需要將應用重定向到仍然在線的節點
但同樣,復制也有其自身局限性,比如:
- 復制建立、調錯都相對比較復雜
- 復制是對象級別(沒錯,這一點既可以是優勢,同樣也是劣勢,基於不同的場景)
- 分發庫上不能建立鏡像,因此分發庫有可能成為Single-Point-Of-Failure
- 復制很容易影響發布服務器的性能
- 不能進行熱備,這意味着就不能進行故障檢測和故障排除
- 對於復制來說,故障轉移容易,想轉移回來就比較麻煩,因此這種情況下可以考慮P2P復制
但不得不說,復制的確是非常的強大,套用京東“首席DB Replicationor(自造詞)”陳璟的話說就是:“想復制什么復制什么,想復制多遠復制多遠,想怎么復制就怎么復制,想復制的多復雜就多復雜”,同時結合其它技術可以實現很多有意思的拓撲,比如圖3(同樣來自陳璟同學)。
圖3.利用復制分發寫數據,同時實現高可用性
通過圖3這種方式,分發了寫壓力,同時相同的讀庫實現了負載均衡以及高可用性,當某個讀庫宕機后,會有足夠的時間進行修復。
小結
本篇文章對復制在高可用架構的角色做了一個概述。復制作為高可用性中最為靈活的技術,與其它技術結合,可以實現很多有意思的拓撲。