為什么說心跳機(jī)制是分布式系統(tǒng)的守護(hù)神?
在很多分布式系統(tǒng)中,我們經(jīng)??吹剿鼈兪褂眯奶鴻C(jī)制,為什么這么多的分布式系統(tǒng)使用心跳機(jī)制?心跳機(jī)制到底是什么?今天一起來聊一聊。
一、什么是心跳機(jī)制?
在分布式系統(tǒng)中,心跳其實(shí)就是從一個(gè)組件發(fā)送到另一個(gè)組件的定期消息,用于交換數(shù)據(jù)或者健康狀態(tài),心跳可以是單向的,也可以是雙向的。
1.單向心跳包
單向心跳包是由一個(gè)節(jié)點(diǎn)(發(fā)送者)定期向另一個(gè)節(jié)點(diǎn)(接收者)發(fā)送消息,而不要求接收者回復(fù)。這種方式簡單而高效,適用于一些基本的健康檢查和狀態(tài)監(jiān)控。
優(yōu)點(diǎn):
- 實(shí)現(xiàn)簡單:發(fā)送者只需定期發(fā)送心跳包,不需要處理回復(fù)邏輯。
- 低延遲:減少了通信的往返時(shí)間,適合低延遲應(yīng)用場景。
缺點(diǎn):
- 缺乏確認(rèn):接收者的狀態(tài)信息是單向的,發(fā)送者無法確定接收者是否收到心跳包。
- 誤報(bào)風(fēng)險(xiǎn):如果網(wǎng)絡(luò)臨時(shí)中斷,接收者無法通知發(fā)送者,可能導(dǎo)致誤報(bào)。
使用場景:
- 基礎(chǔ)監(jiān)控:如定期發(fā)送服務(wù)器狀態(tài)信息到監(jiān)控系統(tǒng)。
- 簡單的健康檢查:如負(fù)載均衡器檢查后端服務(wù)器是否存活。
2.雙向心跳包
雙向心跳包涉及兩個(gè)節(jié)點(diǎn)之間的雙向通信。一個(gè)節(jié)點(diǎn)發(fā)送心跳包,接收者收到后回復(fù)確認(rèn)消息。這種方式能夠提供更可靠的狀態(tài)信息。
優(yōu)點(diǎn):
- 確認(rèn)機(jī)制:發(fā)送者能確認(rèn)接收者是否收到心跳包,提高了通信的可靠性。
- 狀態(tài)同步:雙方可以交換狀態(tài)信息,確保數(shù)據(jù)的一致性和同步。
缺點(diǎn):
- 實(shí)現(xiàn)復(fù)雜:需要處理發(fā)送和接收的邏輯,增加了系統(tǒng)的復(fù)雜性。
- 潛在延遲:增加了通信的往返時(shí)間,可能引入一些延遲。
使用場景:
- 故障檢測:如數(shù)據(jù)庫主從同步,確保數(shù)據(jù)一致性。
- 高可靠性應(yīng)用:如分布式文件系統(tǒng),確保各節(jié)點(diǎn)間的狀態(tài)同步。
如下圖:Server1 向 Server2 發(fā)送一條單向心跳消息:
二、為什么需要心跳機(jī)制?
因?yàn)榉植际较到y(tǒng)可能包含很多服務(wù)器,形成錯(cuò)綜復(fù)雜的網(wǎng)絡(luò)交互,產(chǎn)生的問題也是形形色色,假如沒有心跳機(jī)制,可能會(huì)出現(xiàn)以下問題:
- 無法及時(shí)感知故障檢測
- 服務(wù)器停機(jī)時(shí)間和錯(cuò)誤會(huì)增加
- 整體分布式系統(tǒng)的可靠性會(huì)降低
增加心跳機(jī)制后,可以實(shí)現(xiàn)以下功能:
- 監(jiān)控:心跳消息有助于監(jiān)控分布式系統(tǒng)不同部分的運(yùn)行狀況和狀態(tài)。
- 檢測故障:心跳機(jī)制使系統(tǒng)能夠識(shí)別組件何時(shí)無響應(yīng)。如果節(jié)點(diǎn)錯(cuò)過了幾個(gè)預(yù)期的心跳信號(hào),則表明可能存在問題。
- 觸發(fā)恢復(fù)操作:心跳機(jī)制允許系統(tǒng)采取糾正措施,如將任務(wù)移動(dòng)到正常運(yùn)行的節(jié)點(diǎn)、重新啟動(dòng)故障組件或通知系統(tǒng)管理員介入。
- 負(fù)載均衡:通過監(jiān)控不同節(jié)點(diǎn)的心跳信號(hào),負(fù)載均衡器可以根據(jù)每個(gè)節(jié)點(diǎn)的響應(yīng)能力和運(yùn)行狀況,更有效地在網(wǎng)絡(luò)中分配任務(wù)。
三、心跳機(jī)制是如何工作的?
心跳機(jī)制主要涉及兩個(gè)主要組件:
- 心跳發(fā)送者(節(jié)點(diǎn)):定期發(fā)送心跳信號(hào)的節(jié)點(diǎn)。
- 心跳接收器(監(jiān)視器):接收并監(jiān)視心跳信號(hào)的組件。
心跳機(jī)制整個(gè)過程包含以下幾個(gè)步驟:
- 節(jié)點(diǎn)定期向監(jiān)視器發(fā)送心跳包,比如每 5/10/30秒發(fā)送一次心跳包。
- 監(jiān)視器接收心跳包,并更新節(jié)點(diǎn)的狀態(tài),比如“活動(dòng)”或“可用”。
- 如果監(jiān)視器在規(guī)定的時(shí)間范圍內(nèi)未收到節(jié)點(diǎn)的心跳包,則會(huì)將節(jié)點(diǎn)標(biāo)記為“不可用”或“故障”。
- 系統(tǒng)檢測到有異常的節(jié)點(diǎn),需要采取適當(dāng)?shù)牟僮?,例如重定向流量、啟?dòng)故障轉(zhuǎn)移過程或向管理員發(fā)出警報(bào)。
心跳包的發(fā)送機(jī)制通常上有 2種方式:
- Push方式:節(jié)點(diǎn)主動(dòng)向監(jiān)視器發(fā)送心跳包
- Pull方式:監(jiān)視器會(huì)定期查詢節(jié)點(diǎn)的狀態(tài)
如下圖為一個(gè)簡單的心跳健康檢查機(jī)制:
四、心跳包類型
心跳包在分布式系統(tǒng)中本質(zhì)上就是一條信息,只不過會(huì)根據(jù)不同的業(yè)務(wù)場景定義成不同的類型,以下是常見的心跳包類型:
(1) 簡單心跳包
- 用途:基本的存在檢測。
- 內(nèi)容:通常包含節(jié)點(diǎn)ID和時(shí)間戳。
- 示例:節(jié)點(diǎn)每隔一段時(shí)間發(fā)送一個(gè)簡單消息,告知其仍在運(yùn)行。
(2) 狀態(tài)心跳包
- 用途:不僅檢測節(jié)點(diǎn)存在,還報(bào)告節(jié)點(diǎn)狀態(tài)。
- 內(nèi)容:包含節(jié)點(diǎn)ID、時(shí)間戳、CPU使用率、內(nèi)存使用率、磁盤狀態(tài)等。
- 示例:節(jié)點(diǎn)發(fā)送詳細(xì)的狀態(tài)信息,使監(jiān)視器可以評(píng)估其健康狀況。
(3) 負(fù)載心跳包
- 用途:報(bào)告節(jié)點(diǎn)當(dāng)前負(fù)載,以便于負(fù)載均衡。
- 內(nèi)容:包含節(jié)點(diǎn)ID、時(shí)間戳、當(dāng)前負(fù)載指標(biāo)(如當(dāng)前連接數(shù)、任務(wù)隊(duì)列長度等)。
- 示例:負(fù)載均衡器根據(jù)負(fù)載心跳包的信息來調(diào)整任務(wù)分配。
(4) 自檢心跳包
- 用途:節(jié)點(diǎn)自行檢查并報(bào)告其健康狀態(tài)。
- 內(nèi)容:包含節(jié)點(diǎn)ID、時(shí)間戳、自檢結(jié)果(如服務(wù)健康檢查結(jié)果、錯(cuò)誤日志摘要等)。
- 示例:節(jié)點(diǎn)定期運(yùn)行自檢腳本,并將結(jié)果發(fā)送給監(jiān)視器。
(5) 同步心跳包
- 用途:用于多節(jié)點(diǎn)之間的狀態(tài)同步。
- 內(nèi)容:包含節(jié)點(diǎn)ID、時(shí)間戳、同步狀態(tài)、最新數(shù)據(jù)版本等。
- 示例:數(shù)據(jù)庫集群中的主節(jié)點(diǎn)與從節(jié)點(diǎn)之間使用同步心跳包來確保數(shù)據(jù)一致性。
(6) 事件心跳包
- 用途:通知監(jiān)視器特定事件的發(fā)生。
- 內(nèi)容:包含節(jié)點(diǎn)ID、時(shí)間戳、事件類型和事件詳細(xì)信息。
- 示例:節(jié)點(diǎn)在發(fā)生重要事件(如重新啟動(dòng)、故障修復(fù))時(shí)發(fā)送事件心跳包。
(7) 安全心跳包
- 用途:增強(qiáng)安全性,確保心跳消息的真實(shí)性和完整性。
- 內(nèi)容:包含節(jié)點(diǎn)ID、時(shí)間戳、簽名信息或加密數(shù)據(jù)。
- 示例:節(jié)點(diǎn)發(fā)送的心跳包經(jīng)過數(shù)字簽名,監(jiān)視器驗(yàn)證簽名以確保消息未被篡改。
五、心跳機(jī)制面臨的問題
因?yàn)榉植际较到y(tǒng)包含了比較多的服務(wù)器,而心跳又是在這些服務(wù)器之間通過網(wǎng)絡(luò)傳播的,因此,使用心跳包也面臨一些挑戰(zhàn):
- 網(wǎng)絡(luò)擁塞:如果管理不當(dāng),心跳信號(hào)的持續(xù)流動(dòng)可能會(huì)導(dǎo)致網(wǎng)絡(luò)擁塞。
- 誤報(bào):心跳信號(hào)間隔配置不當(dāng)可能會(huì)導(dǎo)致故障檢測出現(xiàn)誤報(bào),誤將運(yùn)行緩慢但正常的組件標(biāo)識(shí)為故障組件。
- 資源使用:持續(xù)監(jiān)控需要計(jì)算資源,必須優(yōu)化以防止對(duì)系統(tǒng)造成不必要的壓力。
- 腦裂場景:在極少數(shù)情況下,網(wǎng)絡(luò)故障可能會(huì)將系統(tǒng)分區(qū),導(dǎo)致雙方節(jié)點(diǎn)互相宣布對(duì)方死亡,這需要更復(fù)雜的故障處理機(jī)制。
六、心跳機(jī)制的使用場景
心跳機(jī)制在分布式系統(tǒng)中有著大量的使用場景,這里列舉幾個(gè)實(shí)際工作中最常見的例子:
(1) 消息中間件
在消息中間件 RocketMQ中,Broker會(huì)通過心跳包和注冊(cè)中心 NameServer保持交互,這樣注冊(cè)中心就能監(jiān)控到 Broker的狀態(tài),從而給生產(chǎn)者和消費(fèi)者提供比較實(shí)時(shí)的 Broker集群列表。
(2) Kubernetes
在 Kubernetes容器編排平臺(tái)中,每個(gè)節(jié)點(diǎn)都會(huì)定期向控制平面發(fā)送心跳,以指示其可用性。控制平面使用這些檢測信號(hào)來跟蹤節(jié)點(diǎn)的運(yùn)行狀況,并相應(yīng)地做出調(diào)度決策。
(3) Elasticsearch
在 Elasticsearch集群中,節(jié)點(diǎn)交換心跳以形成八卦網(wǎng)絡(luò)。此網(wǎng)絡(luò)使節(jié)點(diǎn)能夠相互發(fā)現(xiàn)、共享集群狀態(tài)信息并檢測節(jié)點(diǎn)故障。
(4) Redis Cluster
Redis Cluster集群中的心跳包實(shí)現(xiàn)基于 Gossip協(xié)議,它是一種分布式通信協(xié)議,允許節(jié)點(diǎn)周期性地與隨機(jī)選擇的其他節(jié)點(diǎn)交換狀態(tài)信息。Redis Cluster的心跳包稱為 PING和 PONG消息,主要結(jié)構(gòu)如下:
- PING 消息:用于發(fā)送節(jié)點(diǎn)的狀態(tài)信息,包括節(jié)點(diǎn)ID、節(jié)點(diǎn)角色(主節(jié)點(diǎn)或從節(jié)點(diǎn))、槽位信息等。
- PONG 消息:用于響應(yīng) PING 消息,確認(rèn)接收到的狀態(tài)信息。
七、總結(jié)
心跳機(jī)制在分布式系統(tǒng)中起到了重要的作用,因此,了解和掌握心跳機(jī)制,對(duì)于掌握分布式系統(tǒng)之間如何交互信息和服務(wù)器探活有著重要的意義。