天天看點

Redis Sentinel 機制與用法(二)

Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案,當用Redis做Master-slave的高可用方案時,假如master當機了,Redis本身(包括它的很多用戶端)都沒有實作自動進行主備切換,而Redis-sentinel本身也是一個獨立運作的程序,它能監控多個master-slave叢集,發現master當機後能進行自懂切換。

它的主要功能有以下幾點

不時地監控redis是否按照預期良好地運作;

如果發現某個redis節點運作出現狀況,能夠通知另外一個程序(例如它的用戶端);

能夠進行自動切換。當一個master節點不可用時,能夠選舉出master的多個slave(如果有超過一個slave的話)中的一個來作為新的master,其它的slave節點會将它所追随的master的位址改為被提升為master的slave的新位址。

<br/>

即使目前沒有failover正在進行,sentinel依然會使用目前配置去設定監控的master。特别是:

根據最新配置确認為slaves的節點卻聲稱自己是master(參考上文例子中被網絡隔離後的的redis3),這時它們會被重新配置為目前master的slave。

如果slaves連接配接了一個錯誤的master,将會被改正過來,連接配接到正确的master。

當一個sentinel準備好了要進行failover,并且收到了其他sentinel的授權,那麼就需要選舉出一個合适的slave來做為新的master。

slave的選舉主要會評估slave的以下幾個方面:

與master斷開連接配接的次數

Slave的優先級

資料複制的下标(用來評估slave目前擁有多少master的資料)

程序ID

如果一個slave與master失去聯系超過10次,并且每次都超過了配置的最大失聯時間(<code>down-after-milliseconds option</code>),并且,如果sentinel在進行failover時發現slave失聯,那麼這個slave就會被sentinel認為不适合用來做新master的。

更嚴格的定義是,如果一個slave持續斷開連接配接的時間超過

就會被認為失去選舉資格。

符合上述條件的slave才會被列入master候選人清單,并根據以下順序來進行排序:

sentinel首先會根據slaves的優先級來進行排序,優先級越小排名越靠前(?)。

如果優先級相同,則檢視複制的下标,哪個從master接收的複制資料多,哪個就靠前。

如果優先級和下标都相同,就選擇程序ID較小的那個。

一個redis無論是master還是slave,都必須在配置中指定一個slave優先級。要注意到master也是有可能通過failover變成slave的。

如果一個redis的slave優先級配置為0,那麼它将永遠不會被選為master。但是它依然會從master哪裡複制資料。

當一個master配置為需要密碼才能連接配接時,用戶端和slave在連接配接時都需要提供密碼。

master通過<code>requirepass</code>設定自身的密碼,不提供密碼無法連接配接到這個master。

slave通過<code>masterauth</code>來設定通路master時的密碼。

但是當使用了sentinel時,由于一個master可能會變成一個slave,一個slave也可能會變成master,是以需要同時設定上述兩個配置項。

Sentinel預設運作在26379端口上,sentinel支援redis協定,是以可以使用redis-cli用戶端或者其他可用的用戶端來與sentinel通信。

有兩種方式能夠與sentinel通信:

一種是直接使用用戶端向它發消息

另外一種是使用釋出/訂閱模式來訂閱sentinel事件,比如說failover,或者某個redis執行個體運作出錯,等等。

sentinel支援的合法指令如下:

<code>PING</code> sentinel回複<code>PONG</code>.

<code>SENTINEL masters</code> 顯示被監控的所有master以及它們的狀态.

<code>SENTINEL master &lt;master name&gt;</code> 顯示指定master的資訊和狀态;

<code>SENTINEL slaves &lt;master name&gt;</code> 顯示指定master的所有slave以及它們的狀态;

<code>SENTINEL get-master-addr-by-name &lt;master name&gt;</code> 傳回指定master的ip和端口,如果正在進行failover或者failover已經完成,将會顯示被提升為master的slave的ip和端口。

<code>SENTINEL reset &lt;pattern&gt;</code> 重置名字比對該正規表達式的所有的master的狀态資訊,清楚其之前的狀态資訊,以及slaves資訊。

<code>SENTINEL failover &lt;master name&gt;</code> 強制sentinel執行failover,并且不需要得到其他sentinel的同意。但是failover後會将最新的配置發送給其他sentinel。

從redis2.8.4開始,sentinel提供了一組API用來添加,删除,修改master的配置。

需要注意的是,如果你通過API修改了一個sentinel的配置,sentinel不會把修改的配置告訴其他sentinel。你需要自己手動地對多個sentinel發送修改配置的指令。

以下是一些修改sentinel配置的指令:

<code>SENTINEL MONITOR &lt;name&gt; &lt;ip&gt; &lt;port&gt; &lt;quorum&gt; </code>這個指令告訴sentinel去監聽一個新的master

<code>SENTINEL REMOVE &lt;name&gt;</code> 指令sentinel放棄對某個master的監聽

<code>SENTINEL SET &lt;name&gt; &lt;option&gt; &lt;value&gt;</code> 這個指令很像Redis的<code>CONFIG SET</code>指令,用來改變指定master的配置。支援多個&lt;option&gt;&lt;value&gt;。例如以下執行個體:

<code>SENTINEL SET objects-cache-master down-after-milliseconds 1000</code>

隻要是配置檔案中存在的配置項,都可以用<code>SENTINEL SET</code>指令來設定。這個還可以用來設定master的屬性,比如說quorum(票數),而不需要先删除master,再重新添加master。例如:

由于有sentinel自動發現機制,是以添加一個sentinel到你的叢集中非常容易,你所需要做的隻是監控到某個Master上,然後新添加的sentinel就能獲得其他sentinel的資訊以及masterd所有的slave。

如果你需要添加多個sentinel,建議你一個接着一個添加,這樣可以預防網絡隔離帶來的問題。你可以每個30秒添加一個sentinel。最後你可以用<code>SENTINEL MASTER mastername</code>來檢查一下是否所有的sentinel都已經監控到了master。

删除一個sentinel顯得有點複雜:因為sentinel永遠不會删除一個已經存在過的sentinel,即使它已經與組織失去聯系很久了。

要想删除一個sentinel,應該遵循如下步驟:

停止所要删除的sentinel

發送一個<code>SENTINEL RESET * </code>指令給所有其它的sentinel執行個體,如果你想要重置指定master上面的sentinel,隻需要把*号改為特定的名字,注意,需要一個接一個發,每次發送的間隔不低于30秒。

檢查一下所有的sentinels是否都有一緻的目前sentinel數。使用<code>SENTINEL MASTER mastername</code> 來查詢。

sentinel永遠會記錄好一個Master的slaves,即使slave已經與組織失聯好久了。這是很有用的,因為sentinel叢集必須有能力把一個恢複可用的slave進行重新配置。

并且,failover後,失效的master将會被标記為新master的一個slave,這樣的話,當它變得可用時,就會從新master上複制資料。

然後,有時候你想要永久地删除掉一個slave(有可能它曾經是個master),你隻需要發送一個<code>SENTINEL RESET master</code>指令給所有的sentinels,它們将會更新清單裡能夠正确地複制master資料的slave。

用戶端可以向一個sentinel發送訂閱某個頻道的事件的指令,當有特定的事件發生時,sentinel會通知所有訂閱的用戶端。需要注意的是用戶端隻能訂閱,不能釋出。

訂閱頻道的名字與事件的名字一緻。例如,頻道名為sdown 将會釋出所有與SDOWN相關的消息給訂閱者。

如果想要訂閱所有消息,隻需簡單地使用<code>PSUBSCRIBE *</code>

以下是所有你可以收到的消息的消息格式,如果你訂閱了所有消息的話。第一個單詞是頻道的名字,其它是資料的格式。

注意:以下的instance details的格式是:

&lt;instance-type&gt; &lt;name&gt; &lt;ip&gt; &lt;port&gt; @ &lt;master-name&gt; &lt;master-ip&gt; &lt;master-port&gt;

如果這個redis執行個體是一個master,那麼@之後的消息就不會顯示。

redis sentinel非常依賴系統時間,例如它會使用系統時間來判斷一個PING回複用了多久的時間。

然而,假如系統時間被修改了,或者是系統十分繁忙,或者是程序堵塞了,sentinel可能會出現運作不正常的情況。

當系統的穩定性下降時,TILT模式是sentinel可以進入的一種的保護模式。當進入TILT模式時,sentinel會繼續監控工作,但是它不會有任何其他動作,它也不會去回應<code>is-master-down-by-addr</code>這樣的指令了,因為它在TILT模式下,檢測失效節點的能力已經變得讓人不可信任了。

如果系統恢複正常,持續30秒鐘,sentinel就會退出TITL模式。

注意:該功能還未實作。

當一個腳本的運作時間超過配置的運作時間時,sentinel會傳回一個-BUSY 錯誤信号。如果這件事發生在觸發一個failover之前,sentinel将會發送一個SCRIPT KILL指令,如果script是隻讀的話,就能成功執行。

     本文轉自yzy121403725 51CTO部落格,原文連結http://blog.51cto.com/lookingdream/1812853:,如需轉載請自行聯系原作者

繼續閱讀