從Ceph看分布式系統(tǒng)故障檢測
節(jié)點的故障檢測是分布式系統(tǒng)無法回避的問題,集群需要感知節(jié)點的存活,并作出適當?shù)恼{整。通常我們采用心跳的方式來進行故障檢測,并認為能正常與外界保持心跳的節(jié)點便能夠正常提供服務。一個好的故障檢測策略應該能夠做到:
- 及時:節(jié)點發(fā)生異常如宕機或網(wǎng)絡中斷時,集群可以在可接受的時間范圍內感知;
- 適當?shù)膲毫Γ喊▽?jié)點的壓力,和對網(wǎng)絡的壓力;
- 容忍網(wǎng)絡抖動
- 擴散機制:節(jié)點存活狀態(tài)改變導致的元信息變化需要通過某種機制擴散到整個集群;
不同的分布式系統(tǒng)由于其本身的結構不同,以及對一致性、可用性、可擴展性的需求不同,會針對以上幾點作出不同的抉擇或取舍。下面我們就來看看Ceph是怎么做的。
Ceph故障檢測機制
Ceph作為有中心的分布式結構,元信息的維護和更新自然的都由其中心節(jié)點Ceph Monitor來負責。節(jié)點的存活狀態(tài)發(fā)生改變時,也需要Monitor來發(fā)現(xiàn)并更新元信息并通知給所有的OSD節(jié)點。最自然的,我們可以想到讓中心節(jié)點Monitor保持與所有OSD節(jié)點之間頻繁的心跳,但如此一來,當有成百上千的OSD節(jié)點時Monitor變會有比較大的壓力。之前在Ceph Monitor and Paxos中介紹過Ceph的設計思路是通過更智能的OSD和Client來減少對中心節(jié)點Monitor的壓力。同樣的,在節(jié)點的故障檢測方面也需要OSD和Monitor的配合完成。下面的介紹基于當前***的11.0.0版本。
OSD之間心跳
屬于同一個pg的OSD我們稱之為伙伴OSD,他們會相互發(fā)送PING\PONG信息,并且記錄發(fā)送和接收的時間。OSD在cron中發(fā)現(xiàn)有伙伴OSD相應超時后,會將其加入failure_queue隊列,等待后續(xù)匯報。
參數(shù):
osd_heartbeat_interval(6): 向伙伴OSD發(fā)送ping的時間間隔。實際會在這個基礎上加一個隨機時間來避免峰值。
osd_heartbeat_grace(20):多久沒有收到回復可以認為對方已經(jīng)down
OSD向Monitor匯報伙伴OSD失效
1. OSD發(fā)送錯誤報告
- OSD周期性的檢查failure_queue中的伙伴OSD失敗信息;
- 向Monitor發(fā)送失效報告,并將失敗信息加入failure_pending隊列,然后將其從failure_queue移除;
- 收到來自failure_queue或者failure_pending中的OSD的心跳時,將其從兩個隊列中移除,并告知Monitor取消之前的失效報告;
- 當發(fā)生與Monitor網(wǎng)絡重連時,會將failure_pending中的錯誤報告加回到failure_queue中,并再次發(fā)送給Monitor。
2. Monitor統(tǒng)計下線OSD
Monitor收集來自OSD的伙伴失效報告;
當錯誤報告指向的OSD失效超過一定閾值,且有足夠多的OSD報告其失效時,將該OSD下線。
參數(shù):
osd_heartbeat_grace(20): 可以確認OSD失效的時間閾值;
mon_osd_reporter_subtree_level(“host”):在哪一個級別上統(tǒng)計錯誤報告數(shù),默認為host,即計數(shù)來自不同主機的osd報告
mon_osd_min_down_reporters(2): 最少需要多少來自不同的mon_osd_reporter_subtree_level的osd的錯誤報告
mon_osd_adjust_heartbeat_grace(true):在計算確認OSD失效的時間閾值時,是否要考慮該OSD歷史上的延遲,因此失效的時間閾值通常會大于osd_heartbeat_grace指定的值
OSD到Monitor心跳
- OSD當有pg狀態(tài)改變等事件發(fā)生,或達到一定的時間間隔后,會向Monitor發(fā)送MSG_PGSTATS消息,這里稱之為OSD到Monitor的心跳。
- Monitor收到消息,回復MSG_PGSTATSACK,并記錄心跳時間到last_osd_report。
- Monitor周期性的檢查所有OSD的last_osd_report,發(fā)現(xiàn)失效的節(jié)點,并標記為Down。
參數(shù):
mon_osd_report_timeout(900):多久沒有收到osd的匯報,Monitor會將其標記為Down;
osd_mon_report_interval_max(600):OSD最久多長時間向Monitor匯報一次;
osd_mon_report_interval_min(5):OSD向Monitor匯報的最小時間間隔
總結
可以看出,Ceph中可以通過伙伴OSD匯報失效節(jié)點和Monitor統(tǒng)計來自OSD的心跳兩種方式發(fā)現(xiàn)OSD節(jié)點失效?;氐皆谖恼麻_頭提到的一個合格的故障檢測機制需要做到的幾點,結合Ceph的實現(xiàn)方式來理解其設計思路。
- 及時:伙伴OSD可以在秒級發(fā)現(xiàn)節(jié)點失效并匯報Monitor,并在幾分鐘內由Monitor將失效OSD下線。當然,由于Ceph對一致性的要求,這個過程中客戶端寫入會不可避免的被阻塞;
- 適當?shù)膲毫Γ河捎谟谢锇镺SD匯報機制,Monitor與OSD之間的心跳統(tǒng)計更像是一種保險措施,因此OSD向Monitor發(fā)送心跳的間隔可以長達600秒,Monitor的檢測閾值也可以長達900秒。Ceph實際上是將故障檢測過程中中心節(jié)點的壓力分散到所有的OSD上,以此提高中心節(jié)點Monitor的可靠性,進而提高整個集群的可擴展性;
- 容忍網(wǎng)絡抖動:Monitor收到OSD對其伙伴OSD的匯報后,并沒有馬上將目標OSD下線,而是周期性的等待幾個條件:1,目標OSD的失效時間大于通過固定量osd_heartbeat_grace和歷史網(wǎng)絡條件動態(tài)確定的閾值;2,來自不同主機的匯報達到mon_osd_min_down_reporters。3,滿足前兩個條件前失效匯報沒有被源OSD取消。
- 擴散:作為中心節(jié)點的Monitor并沒有在更新OSDMap后嘗試廣播通知所有的OSD和Client,而是惰性的等待OSD和Client來獲取。以此來減少Monitor壓力并簡化交互邏輯。