Redis Sentinel 源碼分析 - Sentinel 網絡連接和Tilt模式

作者:Wen Hui
轉載:中間件小哥

在上一篇文章中我們介紹了Sentinel的初始化和主循環,這一篇我們介紹Sentinel的網絡連接以及tilt模式。
Sentinel的網絡連接
在前面的文章曾經提到每個Sentinel實例會維護與所監測的主從實例的兩個連接,分別是命令連接(Command Connection)和發佈訂閱連接(Pub/Sub Connection)。但是需要注意的是,Sentinel和其他Sentinel之間只有一個命令連接。下面將分別介紹命令連接和發佈訂閱連接的作用。
命令連接
Sentinel維護命令連接是爲了與其他主從實例以及Sentinel實例通過發送接收命令的方式進行通信,例如:

  1. Sentinel會默認以每1s間隔發送PING 命令給其他實例以主觀判斷其他實例是否下線。
  2. Sentinel會通過Sentinel和主實例之間的命令連接每隔10s發送INFO命令給主從實例以得到主實例和從實例的最新信息。
  3. 在主實例下線的情況下,Sentinel會通過Sentinel和從實例的命令連接發送SLAVEOF NO ONE命令給選定的從實例從而使從實例提升爲新的主節點。
  4. Sentinel會默認每隔1s發送is-master-down-by-addr命令以詢問其他Sentinel節點關於監控的主節點是否下線。
    在sentinel.c中的sentinelReconnectInstance函數中,命令連接的初始化如下:

Redis Sentinel 源碼分析 - Sentinel 網絡連接和Tilt模式

發佈訂閱連接
Sentinel維護和其他主從節點的發佈訂閱連接作用是爲了獲知其他監控相同主從實例的Sentinel實例的存在,並且從其他Sentinel實例中更新對所監控的主從實例以及發送的Sentinel實例的認知。例如在主備倒換完成後,其他Sentinel通過讀取領頭的Sentinel的頻道消息來更新新的主節點的相關信息(地址,端口號等)。
Sentinel在默認每隔2秒鐘會發送Hello消息包到其對應的主從實例的sentinel:hello頻道中。Hello消息格式如下:
_sentinel:hello <sentinel地址> <sentinel端口號> <sentinel運行id> <sentinel配置紀元> <主節點名字 > <主節點地址> <主節點端口號> <主節點配置紀元>
當Sentinel通過訂閱連接收到其他Sentinel發送的的Hello包時,會更新對主從節點以及S發送Sentinel的認知,如果收到自己發送的Hello包,則簡單的丟棄不做任何處理。這部分代碼邏輯是在sentinel.c中的sentinelProcessHelloMessage函數中定義的,由於篇幅原因在這裏不做詳細介紹。
在sentinel.c中的sentinelReconnectInstance函數中,發佈訂閱連接初始化如下:

 

is-master-down-by-addr 命令
Sentinel會默認每隔1s通過命令連接發送is-master-down-by-addr命令以詢問其他Sentinel節點關於監控的主節點是否下線。另外,在主實例下線的情況下,Sentinel之間也通過is-master-down-by-addr命令來獲得投票並選舉領頭Sentinel。is-master-down-by-addr格式如下:
is-master-down-by-addr: <主實例地址> <主實例端口號> <當前配置紀元> <運行ID>
如果不是在選舉領頭Sentinel過程中, <runid>項總爲*,相反地,如果在Sentinel向其他Sentinel發送投票請求情況下,<runid>項爲自己的運行id。這部分代碼如下:

Redis Sentinel 源碼分析 - Sentinel 網絡連接和Tilt模式

is-master-down-by-addr的命令回覆格式如下:
1) <主節點下線狀態>
2) <領頭Sentinel運行ID >
3) <領頭Sentinel配置紀元>
Sentinel在收到其他Sentinel命令回覆後,會記錄其他Sentinel回覆的主實例在線狀態信息,以及在選舉領頭Sentinel過程中的投票情況,這部分的代碼邏輯定義在sentinel.c中的sentinelReceiveIsMasterDownByReply函數:

Redis Sentinel 源碼分析 - Sentinel 網絡連接和Tilt模式

Tilt模式
Sentinel的Tilt模式會在以下兩種情況下開啓:

  1. Sentinel進程被阻塞超過SENTINEL_TILT_TRIGGER時間(默認爲2s),可能因爲進程或系統I/O(內存,網絡,存儲)請求過多。
  2. 系統時鐘調整到之前某個時間值。
    Tilt模式是一種保護機制,處於該模式下Sentinel除了發送必要的PING及INFO命令外,不會主動做其他操作,例如主備倒換,標誌主觀、客觀下線等。但可以通過INFO 命令及發佈訂閱連接的HELLO消息包來獲取外界信息並對自身結構進行更新,直到SENTINEL_TILT_PERIOD時長(默認爲30s)結束爲止,我們可以認爲Tilt模式是Sentinel的被動模式。
    判斷Tilt模式的代碼邏輯定義如下:

Redis Sentinel 源碼分析 - Sentinel 網絡連接和Tilt模式

參考資料:
https://github.com/antirez/redis
https://redis.io/topics/sentinel
Redis設計與實現第二版黃健宏著

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章