首先介紹一下在replica set裡分為三種節點類型:
1<b> primary </b> 負責client的讀寫。
2 <b>secondary</b> 作為熱備節點,應用Primary的oplog讀取的記錄檔,和primary保持一緻,不提供讀寫操作!
secondary有兩種類型:
1)normal secondary 随時和Primay保持同步,
2)delayed secondary 延時指定時間和primary保持同步,防止誤操作.
3 <b>arbiter</b>.它不負責任何讀寫,隻作為一個仲裁者,負責primary down的時候剩餘節點的選舉操作.
在Replica Set 如果主庫down了,要進行故障切換,叢集的選舉政策:
當primary當了之後,剩下的節點會選擇一個primary節點,仲裁節點也會參與投票,避免僵局出現(如果沒有仲裁節點,對于兩節點的replica set 從節點down,主節點會變為secondary,導緻整個replica set 不可用)選擇依據為:優先級最高的且資料新鮮度最新的!
primary 節點使用心跳來跟蹤叢集中有多少節點對其可見。如果達不到1/2,活躍節點會自動降級為secondary。這樣就能夠防止上面說的僵局狀态或者當網絡切割後primary已經與叢集隔離的時候!
<b>來自官方文檔的例子:</b>
<b>初始狀況:</b>
server-a: secondary oplog: ()
server-b: secondary oplog: ()
server-c: secondary oplog: ()
<b>主庫寫入資料</b>
server-a: primary oplog: (a1,a2,a3,a4,a5)
<b>secondary庫應用資料</b>
server-b: secondary oplog: (a1)
server-c: secondary oplog: (a1,a2,a3)
…
<b>主庫</b><b>server-a</b><b>down</b>
...
server-c: primary oplog: (a1,a2,a3) // c 具有最新的資料被選擇為primary庫
server-b: secondary oplog: (a1,a2,a3)
server-c: primary oplog: (a1,a2,a3,c4)
<b>server-a 恢複或者起來</b>
server-a: recovering oplog: (a1,a2,a3,a4,a5) --做資料恢複
<b>…應用從server-c中的資料,此時 資料a4,a5丢失</b>
server-a: recovering oplog: (a1,a2,a3,c4)
server-b: secondary oplog: (a1,a2,a3,c4)
<b>新的主庫server-c進行資料寫入。</b>
server-a: secondary oplog: (a1,a2,a3,c4)
server-c: primary oplog: (a1,a2,a3,c4,c5,c6,c7,c8)
server-a: secondary oplog: (a1,a2,a3,c4,c5,c6,c7,c8)
server-b: secondary oplog: (a1,a2,a3,c4,c5,c6,c7,c8)
從上面的過程中可以看出server-c 變為主庫,其他節點則應用從server-c的日志。資料a4,a5 丢失。
當選出新的primary之後,此資料庫的資料就會被假定為整個叢集中的最新資料,對其他節點(原來的活躍節點)的操作都會復原,即便之前的主庫已經恢複工作了。為了完成復原,所有節點連接配接新的主庫後都要重新進行同步。此過程如下:
<b>這些節點會檢視自己的oplog日志,找到還沒應用的主庫操作,然後向主庫請求這些操作影響的文檔的最新副本,進行資料同步。</b>