如何提高Ceph性能以及穩定性:Deep Scrubbing和I/O saturation
本文轉載自微信公眾號「新鈦云服」,作者祝祥 。轉載本文請聯系新鈦云服公眾號。
介紹
Ceph是在云環境中最常使用的分布式存儲系統。設計初衷是提供較好的性能、可靠性和可擴展性。
Ceph項目最早起源于Sage就讀博士期間的工作(最早的成果于2004年發表),并隨后貢獻給開源社區。在經過了數年的發展之后,目前已得到眾多云計算廠商的支持并被廣泛應用。RedHat及OpenStack都可與Ceph整合以支持虛擬機鏡像的后端存儲。
Ceph最令人津津樂道的是,Ceph在一個統一的存儲系統中同時提供了對象存儲、塊存儲和文件存儲,即Ceph是一個統一存儲,能夠將企業企業中的三種存儲需求統一匯總到一個存儲系統中,并提供分布式、橫向擴展,高度可靠性的存儲系統,Ceph存儲提供的三大存儲接口。
I/O擁塞是Ceph運維中最常見的問題,常常會影響到生產業務,極端情況會導致存儲集群的宕機。
I/O瓶頸則會影響OpenStack上的應用程序性能,即使系統仍然在正常運行,但是I/O的瓶頸會導致所有突發的I/O任務都會卡死。
本文將會解釋為什么會在Ceph上會遇到這種情況,以及如何修改對應的參數,從而提高Ceph的穩定性以及對應的I/O性能。
ceph scrubbing
CEPH使用兩種清理方式來檢查存儲運行狀況。清理操作默認情況下每天都會執行。
- normal scrubbing:捕獲OSD錯誤或文件系統錯誤。如上圖所示,該操作不耗資源,不影響I/O性能。
- deep scrubbing: 比較PG對象中的所有數據。它會查找磁盤上的損壞的扇區。此處理是I/O密集型的。對I/O影響比較大。
上述指標歷史記錄中顯示的I/O性能是由于每天從凌晨0:00到7:00進行的深度清理過程導致的。如果需要詳細了解這一過程,請看下面的配置以及參數說明。下表簡單列出了清理的相關參數,本文也會就這些參數提供部分說明。
osd scrub begin/end hour :這些參數定義了清理時間窗口。以我們的環境為例,一般我們會計劃在凌晨0點到7點之間進行清理任務。深度清理需要較長時間,如果最后一次的深度清理在早上7點之前開始,則處理的結束時間很可能會在大約1小時后。這也就是為什么我們的環境I/O在會在早上7點后降低,但在8點之后恢復為較高的原因。
正確設置Ceph有關的清理時間窗口非常重要。避開業務高峰期,選擇業務低谷期間進行深度清理。如果業務是區域性的和基于人工,那么每夜進行一次處理是很有必要的。如果全天業務負載都很均衡,那么全局時間窗口(從0am到24pm)看起來更合適。
osd deep scrub interval:該參數定義了在PG上執行深度清理的時間周期。默認設置是每周一次。這意味著,當深度清理的計劃開始工作時,它將標記所有未深度清理的PG,一直到該批次所有PG的深度清理任務完成?;旧?,并行深度清理的級別與該參數和時間窗口有關。一周一次深度清理是比較保守的。
經過一番驗證,哪怕是深度清理的時間間隔為1周,似乎也沒有在4天之前進行過任何PG的深度清理。如果我們想要延長時間段或時間窗口,那么如果PG的處理頻率超過預期的周期,我們將無法解決問題。這一假設有部分是正確的,但也有部分是錯誤的。在CEPH代碼中可以找到有關這種過度處理的說明:
- scrubber.time_for_deep = ceph_clock_now() >=
- info.history.last_deep_scrub_stamp + deep_scrub_interval;
- bool deep_coin_flip = false;
- // If we randomize when !allow_scrub && allow_deep_scrub, then it guarantees
- // we will deep scrub because this function is called often.
- if (!scrubber.time_for_deep && allow_scrub)
- deep_coin_flip = (rand() % 100) < cct->_conf->osd_deep_scrub_randomize_ratio * 100;
- scrubber.time_for_deep = (scrubber.time_for_deep || deep_coin_flip);
基本上,深度清理也依賴于第四個參數,當前的官方文檔尚未說明:
osd_deep_scrub_randomize_ratio: 隨機執行深度清理的概率,可設置0.01 ,值越大,清理概率也越大,也容易影響業務。這個不受osd_deep_scrub_interval影響,但會在osd_scrub_begin_hour—osd_scrub_end_hour之間執行
在這種情況下,初始設置為15%。假設每天進行一次深度清理任務分配,那么則意味著每周都會通過隨機過程選擇一個PG。換句話說,從統計學上講,這意味著> 50%的PG將每周處理兩次。這就是為什么所有PG在4天的時間內(即使間隔為1周)都進行了處理的原因。
如果您在不更改osd_deep_scrub_randomize_ratio的情況下更改osd deep scrub interval,則并不會減少清理的工作量。因此,通常需要將這兩個參數同步使用。
osd_deep_scrub_randomize_ratio的目標是將深度清理操作線性化,否則在PG創建的每個周期內我們可能會有比較大的I/O峰值,即使間隔一個又一個周期時間,這依然可能會越來越線性化。當隨機因素對應于間隔時間(基本為一周的15%)時,這將在PG深度清理分布中形成線性關系。但工作量會增加大約150%。因此,當PG深度清理任務被分配,就可以正確處理PG的過期時間,從而降低整個調度的工作量。另一種工作方式是使用一個概率來定義周期(統計的方式),并將該周期用作未處理的PG的垃圾收集器。在我看來,這是一個很好的設置,例如,隨機地使用5%的概率統計處理PG,每個PG大約3周,間隔1個月。
分析scrub速度
了解您的清理和深度清理的速率對于了解系統性能瓶頸并計算正常時間來處理清理任務很重要。對于后續的事件回顧與追溯非常有效。
此命令提供PG狀態和上次清理/深度清理的時間。
- [~] ceph pg dump
您可以查看PG最早深度清理時間:
- [~] ceph pg dump | awk '$1 ~/[0-9a-f]+\.[0-9a-f]+/ {print $25, $26, $1}' | sort -rn
淺度清理
- [~] ceph pg dump | awk '$1 ~/[0-9a-f]+\.[0-9a-f]+/ {print $22, $23, $1}' | sort -rn
您可以按時間過濾以獲取給定時間處理的PG數量,因此您每天可以處理一定數量的PG進行清理。
- [~] ceph pg dump | awk '$1 ~/[0-9a-f]+\.[0-9a-f]+/ {print $25, $26, $1}' | sort -rn | grep 2020-XX-YY | wc
您可以更改ID,以進行淺度清理。
這些信息對于了解Ceph系統是否正常以及是否達到瓶頸是很重要的,因為在較短的時間范圍內有很多任務需要運行,比如隨機比率太高,并且您每天有太多的清理操作。
進一步配置scrub參數
以下是其他一些參數將對負載產生影響,因為一旦我們定義了要執行的任務,就需要做好計劃,然后合理執行。
- osd max scrubs: 表示單個OSD(驅動器)可以進行的最大清理次數。通常為1。但是您可以在同一主機上的不同OSD上進行多并發清理操作。這可能會影響Ceph全局I/O性能,尤其是在驅動器硬盤之間共享總線時。
清理是按chunk組織的。如果chunk大小由兩個值定義:** osd scrub chunk min和osd scrub chunk max。這似乎是一個批處理操作,但目前尚不清楚對于一個chunk是否同時包含深度清理和淺度清理。兩個chunk之間的處理由osd scrub sleep**設置的時間進行分開。此參數沒有描述的單位,因此了解如何使用它有點復雜。默認設置為0.1(10%)。
優先級
CEPH 優先處理優先級較高的I/O任務。這樣,我們就可以進行清理操作的同時,也不會對用戶I/O造成太大影響。該數值越大,優先級越高,任務也越優先。涉及不同的優先級參數:
- osd requested scrub priority:是手動啟動的清理(淺度與深度)操作的優先級。這很重要,大家通常都會修改。默認值為120,已經高于用戶優先級。因此,對默認場景而言,并不推薦修改該參數。
- osd scrub priority:是自動計劃的清理(淺度和深度)操作的優先級。該值默認為5。4為推薦的最佳值。
- osd client op priority: 是客戶端I/O的優先級。最大值為63。它也是默認值。
塊大小
塊大小讀取訪問性能也會影響全局清理的性能。osd deep scrub stride參數設置要讀取的塊大小。默認值為512KB(524288)。該參數對于固態硬盤,塊大小在16KiB以上并不重要。對于512KiB機械磁盤,這是一個比較好的調整參數,您可以使用1MiB或2MiB塊提高吞吐量。
系統負載
osd scrub load threshold參數允許在系統負載(cpu loadavg)高于給定限制值時停止清理動作。通常,這有助于在I/O密集操作期間停止清理動作。但是scrub本身也會產生負載,因此在我看來,正確調整此參數有點復雜。對于CPU較小的CEPH服務器,卻很有意義的。
清理調度
還有一件還不清楚的事情:何時執行清理操作的調度計劃?是在每個批處理窗口上(每天一次)還是在每個chunk快滿的時候才執行?在這種情況下,系統如何確保按不同的時間段內處理所有PG。這些信息是理解隨機PG選擇在清除調度中的影響的關鍵點。官方文檔中對這些說明非常少。
常用的配置命令
該配置是每個OSD附帶的。以下列出了一個OSD的默認參數:
- ceph config show-with-defaults osd.x # with x a OSD number
在所有OSD上查看參數
- ceph tell osd.* config get osd_deep_scrub_randomize_ratio
其他一些用于了解有關OSD和磁盤性能的命令或工具。有時候,可以發現IO清理問題實際上很可能是底層IO性能問題。
- hdparm -Tt /dev/sdx
- ceph tell osd.x bench -f plain
最后
隨著Ceph集群數據量和集群規模逐漸擴大,在日常維護中,我們經常遇到各種異常情況,其中頻次較多的就是慢請求slow-request,慢請求會導致性能抖動,直接影響集群的穩定性,需要謹慎對待。而slow-request大部分都是由清理動作引起的,合理的配置以及規劃清理計劃,可以避免影響生產業務,同時也可以充分發揮存儲的性能。