一次ceph心跳機制異常的處理
部署使用ceph叢集的時候遇到一個情況,在大規模叢集的時候,有節點網路或者osd異常時,mon遲遲不把該異常的osd標down,一直等待900s後mon發現該節點的osd一直沒有更新pgmap才把異常的osd標down,並更新osdmap擴散出去。 |
現象:部署使用ceph叢集的時候遇到一個情況,在大規模叢集的時候,有節點網路或者osd異常時,mon遲遲不把該異常的osd標down,一直等待900s後mon發現該節點的osd一直沒有更新pgmap才把異常的osd標down,並更新osdmap擴散出去。但這個900s內,客戶端IO還是會一直往異常的osd上去下發,導致io超時,並進一步影響上次的業務。
我們在mon的日誌裡面也看到了和異常osd建立心跳的其他osd向mon報告該osd的異常,但mon確實在短時間內沒有這些osd標down。檢視了一些相關網路和書籍的資料後,才發現了問題。
首先我們關注osd配置中幾個相關的配置項:
(1)osd_heartbeat_min_peers:10
(2)mon_osd_min_down_reporters:2
(3)mon_osd_min_down_reporters_ratio:0.5
以上引數的之都可以在ceph叢集節點上執行ceph daemon osd.x config show檢視(x是你的叢集osd的id)。
問題出現的原因是什麼呢?
問題現場的叢集部署時每個osd會隨機選取10個peer osd來作為建立心跳的物件,但在ceph的機制中,這個10個osd不一定保證能夠全部分散在不同的節點上。故在有osd異常的時候,向mon報該osd down的reporter有機率不滿足ratio=0.5,即reporter數量未過叢集儲存host數量的一半,這樣異常osd就無法透過osd之間的心跳報活機制快速標down,直到900s後mon發現這個osd pgmap一直不更新才識別到異常(另一種機制,可以看做是給osd心跳保活機制做最後的保險),並透過osdmap擴散出來。而這個900s對於上層業務來說,往往是不可接受的。
但這個現象對於小規模叢集幾乎不會出現,比如以一個3節點ceph叢集為例:
如果與其他節點osd建立的peer數量小於了osd_heartbeat_min_peers,那麼osd會繼續選擇與自己較近的osd建立心跳連線(即使是和自己位於同一個節點上。)
對於osd心跳機制,網上有人總結過幾點要求:
(1)及時:建立心跳的osd可以在秒級發現其他osd的異常並上報monitor,monitor在幾分鐘內把該osd標down下線
(2)適當的壓力:不要以為peer越多越好,特別是現在實際應用場景中osd監聽和傳送心跳報文的網路鏈路都是和public network以及cluster network共用的,心跳連線建立過多會極大影響系統的效能。Mon有單獨與osd維持心跳的方式,但ceph透過osd之間的心跳保活,將這種壓力分散到各個osd上,極大減小了中心節點mon的壓力。
(3)容忍網路抖動:mon收集到osd的彙報之後,會經過週期的等待幾個條件,而不是貿然把osd標down。這些條件有目標osd的實效時間大於透過固定量osd_heartbeat_grace和歷史網路條件確定的閾值,以及上報的主機數是否達到min_reporters和min_reporters_ratio,以及在一定時間內,失效彙報沒有被源報告者取消掉等。
(4)擴散機制:2種實現,mon主動擴散osdmap,還有一種惰性的是osd和client自己來取。為了讓異常資訊及時讓client和其他osd感知到,一般是前一種實現比較好。
2個方向可以做出改變。
(1)對於原有機制中取叢集儲存節點數量的0.5作為min_reporter_ratio明顯不合理,應該採用的是這個osd與多少host上的osd建立心跳(取host數量),那就由0.5*建立心跳的host總數來作為判斷依據。
(2)一些場景下,我們會自己定義一些資料存放的邏輯區域,透過對crush的層級結構的利用,例如在一個ceph叢集中定義多個邏輯區域,一個資料的分片或者副本只存在於一個邏輯區域中,那相關osd建立心跳連線的範圍就需要相應精簡和準確。
現在ceph實現的osd心跳機制還是會有很多問題,不知道後面會不會有新的機制替換當前機制,讓我們拭目以待。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2651221/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Ceph心跳機制
- 異常處理機制
- java異常的處理機制Java
- Java 的異常處理機制Java
- Java異常處理機制Java
- 異常處理機制(二)之異常處理與捕獲
- SpringMVC異常的處理機制SpringMVC
- Java 中的異常處理機制Java
- Struts的異常處理機制 (轉)
- 08.異常處理機制
- C++異常處理機制C++
- Python異常處理機制Python
- 8.異常處理機制
- C#中的異常處理機制C#
- goang 錯誤&異常處理機制Go
- Asp.Net 異常處理機制ASP.NET
- 解析Oracle developer 異常處理機制OracleDeveloper
- C++ 異常處理機制詳解:輕鬆掌握異常處理技巧C++
- C++ 異常處理機制的實現C++
- 深入理解java異常處理機制Java
- .NET----錯誤和異常處理機制
- PHP異常、錯誤處理機制筆記PHP筆記
- 深入理解C++中的異常處理機制C++
- Python異常處理機制、除錯、測試Python除錯
- 深入理解java異常處理機制(目前最好的講解異常的博文)Java
- JAVA的異常處理機制(一)——try...catch...finallyJava
- React 原始碼解析系列 - React 的 render 異常處理機制React原始碼
- 異常處理機制(一)之throw與throws的區別
- 深度解析Java執行緒池的異常處理機制Java執行緒
- python中的五種異常處理機制介紹Python
- Python入門學習之異常處理機制Python
- 利用SEH異常處理機制繞過GS保護
- C++異常處理機制核心觀點總結C++
- Go 函式的健壯性、panic異常處理、defer 機制Go函式
- MySQL Slave異常關機的處理MySql
- 異常的處理
- 異常篇——異常處理
- 異常-throws的方式處理異常