陳云煒 李偉波 陳蔡濤
在OpenStack云平臺(tái)中,對(duì)資源的監(jiān)控與計(jì)量是確保云平臺(tái)穩(wěn)定運(yùn)行的標(biāo)準(zhǔn)配置,也恰恰是日常最讓人煩惱的問(wèn)題。尤其在公有云平臺(tái)中,對(duì)資源的監(jiān)控與計(jì)量不僅可以向業(yè)務(wù)使用者展現(xiàn)業(yè)務(wù)對(duì)資源的使用情況,還可以成為按需計(jì)費(fèi)模式下的計(jì)費(fèi)依據(jù),但是監(jiān)控?cái)?shù)據(jù)的準(zhǔn)確性、實(shí)時(shí)性以及海量監(jiān)控?cái)?shù)據(jù)的處理、儲(chǔ)存和索引性能等都具有挑戰(zhàn)性的工作。說(shuō)到運(yùn)維監(jiān)控,大家熟知的有Zabbix、Cacti、Nagios等傳統(tǒng)的開(kāi)源運(yùn)維監(jiān)控系統(tǒng);這些監(jiān)控系統(tǒng)都很強(qiáng)大也很靈活,從普通的業(yè)務(wù)使用上來(lái)說(shuō),經(jīng)過(guò)相關(guān)的配置、插件定制甚至是二次開(kāi)發(fā),完全可以完成對(duì)系統(tǒng)資源的監(jiān)控與計(jì)量功能。但這些監(jiān)控系統(tǒng)畢竟是獨(dú)立的監(jiān)控系統(tǒng),并沒(méi)有與OpenStack云平臺(tái)進(jìn)行契合,在OpenStack云平臺(tái)中增刪業(yè)務(wù)資源時(shí),這些監(jiān)控系統(tǒng)是無(wú)感知的,也就是不能自動(dòng)地對(duì)OpenStack云平臺(tái)的資源進(jìn)行自動(dòng)監(jiān)控。并且OpenStack是一個(gè)多租戶的云平臺(tái),以上這些開(kāi)源的監(jiān)控系統(tǒng)中要做到不同租戶的資源數(shù)據(jù)分別監(jiān)控與計(jì)量以及索引,還是比較復(fù)雜的。所幸OpenStack社區(qū)有Ceilometer項(xiàng)目來(lái)實(shí)現(xiàn)OpenStack集群資源監(jiān)控與計(jì)量的功能。Ceilometer項(xiàng)目從OpenStack Folsom版本開(kāi)始發(fā)布,經(jīng)過(guò)不斷的迭代,功能也逐漸豐富,包含了監(jiān)控、計(jì)量與告警等功能,并且通過(guò)OpenStack的endpoint RESTful API以及消息隊(duì)列,可以非常好地與OpenStack中的其他項(xiàng)目相結(jié)合,實(shí)現(xiàn)分租戶的自動(dòng)化的資源監(jiān)控和計(jì)量。然而由于Ceilometer在運(yùn)行性能上的一些原因,社區(qū)逐漸地Ceilometer項(xiàng)目進(jìn)行了功能的拆分:Ceilometer主要實(shí)現(xiàn)資源數(shù)據(jù)的采集,將計(jì)量和數(shù)據(jù)存儲(chǔ)功能分拆成為Gnocchi項(xiàng)目,將告警功能拆分成為Aodh項(xiàng)目。本文僅涉及Ceilometer數(shù)據(jù)采集和Gnocchi數(shù)據(jù)處理和存儲(chǔ)兩個(gè)部分,并且基于OpenStack Ocata版及之后版本的Ceilometer和Gnocchi進(jìn)行分析。
二、Ceilometer與Gnocchi架構(gòu)
1.Ceilometer架構(gòu)和基本概念
在OpenStack中Ceilometer主要負(fù)責(zé)數(shù)據(jù)采集,其采用類似于agent加server的結(jié)構(gòu),大致的架構(gòu)如下圖1所示:
圖 1
其數(shù)據(jù)采集是由agent端來(lái)完成的,在Ceilometer中有compute、central、ipmi等類型的agent,一般常用的是compute和central兩種類型的agent:
Compute agent:負(fù)責(zé)收集OpenStack部署中各個(gè)計(jì)算節(jié)點(diǎn)上VM實(shí)例的資源使用數(shù)據(jù)。Compute agent須在每個(gè)計(jì)算節(jié)點(diǎn)上安裝,并且需要與虛擬機(jī)管理程序(Hypervisor)進(jìn)行密切的交互以獲得VM虛擬機(jī)實(shí)例的相關(guān)資源數(shù)據(jù)。不同類型的Hypervisor提供了不同的API,因此Compute agent所能收集的數(shù)據(jù)受限于Hypervisor API所能提供的數(shù)據(jù)類型。
Central agent:負(fù)責(zé)輪詢公共RESTful API,以收集未通過(guò)消息隊(duì)列發(fā)布消息的OpenStack組件的相關(guān)資源情況,還可以通過(guò)SNMP收集硬件相關(guān)的資源。例如:OpenStack Networking、OpenStack Object Storage、OpenStack Block Storage等資源的使用情況均由Central agent輪詢RESTful API來(lái)進(jìn)行收集。
IPMI agent:負(fù)責(zé)收集OpenStack部署的各個(gè)計(jì)算節(jié)點(diǎn)上的IPMI傳感器數(shù)據(jù)和Intel節(jié)點(diǎn)管理器數(shù)據(jù)。此agent需要節(jié)點(diǎn)安裝了ipmitol程序以支持IPMI數(shù)據(jù)收集。
Ceilometer agent采集到的數(shù)據(jù)需要發(fā)送到server端進(jìn)行匯總、分析和儲(chǔ)存,在ceilometer中數(shù)據(jù)的發(fā)送方式是由publisher來(lái)定義和處理的,收集到的每種類型的數(shù)據(jù)都可以使用一個(gè)或多個(gè)publisher發(fā)送,在OpenStack的Ocata版本中,Ceilometer agent采集到的數(shù)據(jù)依然默認(rèn)是采用notifier://類型的publisher發(fā)送到消息隊(duì)列中。Ceilometer agent采集到的原始數(shù)據(jù)稱為Meter,Meter是資源使用的某個(gè)計(jì)量項(xiàng),它的屬性包括:名稱(name)、單位 (unit)、類型(cumulative:累計(jì)值,delta:變化值、gauge:離散或者波動(dòng)值)以及對(duì)應(yīng)的資源屬性等;某些數(shù)據(jù)在采集到時(shí)可能還不符合相關(guān)格式,因此可以在發(fā)送數(shù)據(jù)前進(jìn)行一些轉(zhuǎn)換,這個(gè)轉(zhuǎn)換稱為T(mén)ransformer,一條Meter數(shù)據(jù)可以經(jīng)過(guò)多個(gè)Transformer處理后再由publisher發(fā)送,流程簡(jiǎn)圖如下圖2所示:
圖 2
在消息隊(duì)列中由Ceilometer collector充當(dāng)一個(gè)server的角色來(lái)消費(fèi)消息隊(duì)列中的收集到的監(jiān)控?cái)?shù)據(jù)消息。Ceilometer collector可將采集到的數(shù)據(jù)進(jìn)一步加工和處理,然后將數(shù)據(jù)通過(guò)HTTP方式發(fā)送到Gnocchi組件中進(jìn)行處理和儲(chǔ)存,并且后續(xù)的數(shù)據(jù)索引讀取也是由Gnocchi進(jìn)行處理。但Ceilometer也保留了舊版本的一些功能,可以選擇舊版本Ceilometer的方式將數(shù)據(jù)直接存入一些數(shù)據(jù)庫(kù)中。
2.Gnocchi架構(gòu)和基本概念
Gnocchi 提供數(shù)據(jù)存儲(chǔ)服務(wù),是一個(gè)時(shí)間序列數(shù)據(jù)庫(kù),為Ceilometer提供存儲(chǔ)后端,致力于解決Ceilometer應(yīng)用中所面臨的大規(guī)模存儲(chǔ)和索引時(shí)間序列數(shù)據(jù)的性能問(wèn)題。Gnocchi不僅解決了大規(guī)模時(shí)間序列數(shù)據(jù)存取的性能問(wèn)題,同時(shí)還把OpenStack云平臺(tái)中多租戶等特性考慮在內(nèi)。引用Gnocchi官方的一張圖,其架構(gòu)如下圖3所示:
圖 3
由以上架構(gòu)圖可以看出Gnocchi主要有兩個(gè)核心部件:API和Metricd,并且依賴于三個(gè)外部組件:Measure Storage、Aggregate Storage、Index。
Measure Storage:measures是Gnocchi對(duì)數(shù)據(jù)的第三層劃分,是實(shí)際的監(jiān)控?cái)?shù)據(jù)。因此Measure Storage用于保存實(shí)際監(jiān)控?cái)?shù)據(jù),并且是臨時(shí)保存的,在Gnocchi處理后會(huì)刪除其中已處理的數(shù)據(jù)。
Aggregate Storage:首先要理解Aggregate是什么。Gnocchi采用了一種獨(dú)特的時(shí)間序列存儲(chǔ)方法:它不是存儲(chǔ)原始數(shù)據(jù)點(diǎn),而是在存儲(chǔ)它們之前對(duì)它們按照預(yù)定義的策略進(jìn)行聚合計(jì)算,僅保存處理后的數(shù)據(jù)。所以Gnocchi在讀取這些數(shù)據(jù)時(shí)會(huì)非常快,因?yàn)樗恍枰x取預(yù)先聚合計(jì)算好的結(jié)果。因此Aggregate Storage是用于保存用戶時(shí)間看到的聚合計(jì)算后的結(jié)果數(shù)據(jù)。
Index:通常是一個(gè)關(guān)系型數(shù)據(jù)庫(kù),用于索引resources和metrics,以使得可以快速地從Measure Storage或Aggregate Storage中取出所需要的數(shù)據(jù)。
API:即gnocchi-api服務(wù)進(jìn)程,通過(guò)Indexer和Storage的driver,提供查詢和操作ArchivePolicy,Resource,Metric,Measure的接口,并將新到來(lái)的Measure存入Measure Storage。
Metricd:即gnocchi-metricd服務(wù)進(jìn)程,根據(jù)Metric定義的ArchivePolicy規(guī)則,周期性地從Measure Storage中匯總聚合計(jì)算measures,以及對(duì)Aggregate Storage中的數(shù)據(jù)執(zhí)行數(shù)據(jù)聚合計(jì)算和清理過(guò)期數(shù)據(jù)等動(dòng)作,并將聚合的結(jié)果數(shù)據(jù)保存到Aggregate Storage。
結(jié)合圖2和圖3來(lái)看,在Ceilometer collector中收集到的數(shù)據(jù)通過(guò)Gnocchi這個(gè)publisher發(fā)到到gnocchi-api,再由gnocchi-api將收集到的數(shù)據(jù)寫(xiě)入到Measure Storage。Metricd會(huì)周期性地檢索Measure Storage是否有數(shù)據(jù)需要處理,并將Measure Storage中的數(shù)據(jù)依次取出進(jìn)行聚合計(jì)算,在將計(jì)算結(jié)果保存到Aggregate Storage后也將Measure Storage中已處理的measures原始數(shù)據(jù)刪除。
在Gnocchi中,將API和Metricd均設(shè)計(jì)成無(wú)狀態(tài)的服務(wù),因此可以很方便地進(jìn)行橫向擴(kuò)展。并且對(duì)于運(yùn)行的gnocchi-metriccd守護(hù)程序或gnocchi-API端點(diǎn)的數(shù)量沒(méi)有限制,可以根據(jù)系統(tǒng)的負(fù)載大小調(diào)整相關(guān)服務(wù)進(jìn)程的數(shù)量即可提升系統(tǒng)的處理能力。
三、Ceilometer與Gnocchi的實(shí)踐與優(yōu)化
上文簡(jiǎn)述了Ceilometer和Gnocchi的基本架構(gòu)和一些基本概念,下文將講述這兩個(gè)組件在實(shí)際系統(tǒng)中的一些應(yīng)用,以及遇到的一些問(wèn)題和解決方法。
1.Ceilometer的實(shí)踐與優(yōu)化
Ceilometer的部署按照官方文檔進(jìn)行安裝和配置,一般在控制節(jié)點(diǎn)運(yùn)行ceilometer-central、ceilometer-collector和ceilometer-notification服務(wù)、在計(jì)算節(jié)點(diǎn)運(yùn)行ceilometer-compute服務(wù)。然而官方默認(rèn)的配置并不能完全符合我們的業(yè)務(wù)需求,需要進(jìn)一步優(yōu)化配置。
首先,Ceilometer agent所需要收集的數(shù)據(jù)是由polling.yaml配置文件來(lái)定義的,配置文件路徑為:/etc/ceilometer/polling.yaml,而默認(rèn)的配置是執(zhí)行所有定義在ceilometer Python包entry_points.txt中的收集器來(lái)收集發(fā)送所有數(shù)據(jù):
圖 4
然而這個(gè)“全量”的配置可能會(huì)導(dǎo)致ceilometer agent代碼層面的錯(cuò)誤,使得收集數(shù)據(jù)的流程中斷。尤其是對(duì)于Ceilometer的Compute agent,上文講到,Ceilometer的Compute agent所能收集的數(shù)據(jù)受限于Hypervisor API所能提供的數(shù)據(jù)類型,而ceilometer entry_points.txt中定義了所有不同平臺(tái)的收集器,那么肯定會(huì)有一些收集器不適用當(dāng)前平臺(tái)環(huán)境的,從而導(dǎo)致在執(zhí)行這些收集器時(shí)程序出錯(cuò):
圖 5
從數(shù)據(jù)層面來(lái)看,我們應(yīng)該只收集那些業(yè)務(wù)系統(tǒng)關(guān)心的數(shù)據(jù);因?yàn)槭占^(guò)多的無(wú)用數(shù)據(jù)時(shí)會(huì)給傳輸、處理和儲(chǔ)存都帶來(lái)額外的性能開(kāi)銷(xiāo),尤其是在使用消息隊(duì)列傳輸監(jiān)控?cái)?shù)據(jù)時(shí),消息隊(duì)列中大量的消息堆積將會(huì)導(dǎo)致消息隊(duì)列服務(wù)占用大量的內(nèi)存。因此,我們需要優(yōu)化配置,定制化地執(zhí)行收集器收集我們所需的數(shù)據(jù)。例如,在計(jì)算節(jié)點(diǎn),我們?nèi)绻麅H需收集實(shí)例虛擬機(jī)的CPU、內(nèi)存、磁盤(pán)還有虛擬網(wǎng)卡的資源使用情況,并根據(jù)各種資源的所需求的實(shí)時(shí)性定制其發(fā)送數(shù)據(jù)的頻率,簡(jiǎn)要配置示例如下圖6所示:
圖 6
其中的interval是發(fā)送數(shù)據(jù)間隔,單位是秒。而meters則是需要收集的數(shù)據(jù)類型,其參數(shù)值需要根據(jù)當(dāng)前Ceilometer所能收集的數(shù)據(jù)類型來(lái)設(shè)定,當(dāng)前Ceilometer所支持采集的數(shù)據(jù)類型在/etc/ceilometer/gnocchi_resources.yaml文件中的metrics域所定義,其值同時(shí)會(huì)對(duì)應(yīng)到Gnocchi中的資源類型,然后才可以在后續(xù)的Gnocchi中檢索和處理。
其次的優(yōu)化是我們需要增加Ceilometer collector的進(jìn)程數(shù)。在上文中提及,在OpenStack Ocata版本中,ceilometer agent收集到的數(shù)據(jù)依然是先通過(guò)消息隊(duì)列發(fā)送給ceilometer collector處理然后再發(fā)送到Gnocchi。而在Ceilometer中collector默認(rèn)的進(jìn)程數(shù)(即collector workers數(shù)量)是1,當(dāng)集群的虛擬機(jī)數(shù)量越來(lái)越多時(shí)以及采集的數(shù)據(jù)量越來(lái)越大時(shí),因Ceilometer collector處理消息速度過(guò)慢就會(huì)出現(xiàn)消息堆積的情況,由于collector響應(yīng)不及時(shí)還可能導(dǎo)致大量的Unacked消息的出現(xiàn),如下圖7:
圖 7
出現(xiàn)此類情況后可通過(guò)修改/etc/ceilometer/ceilometer.conf的配置,增加collector的workers進(jìn)程數(shù)即可解決。Collector的workers進(jìn)程數(shù)可根據(jù)集群的規(guī)模以及收集的數(shù)據(jù)量以及數(shù)據(jù)上報(bào)頻率來(lái)設(shè)定,建議在滿足消息隊(duì)列中的消息不會(huì)持續(xù)堆積的情況下再增加1~2個(gè)workers進(jìn)程,以滿足未來(lái)一段時(shí)間內(nèi)集群虛擬機(jī)不斷增加所帶來(lái)的監(jiān)控?cái)?shù)據(jù)增長(zhǎng)。
而在OpenStack Ocata版本之后的Ceilometer中,還可以通過(guò)修改所有Ceilometer agent中的/etc/ceilometer/pipeline.yaml配置文件,將其中的publishers從notifier://改為gnocchi://,然后ceilometer agent收集到的數(shù)據(jù)即可直接發(fā)送到Gnocchi的API中,不再需要Ceilometer collector作中轉(zhuǎn),避免了通過(guò)消息隊(duì)列發(fā)送給Ceilometer collector處理再轉(zhuǎn)發(fā)到Gnocchi帶來(lái)的額外性能消耗:
圖 8
2.Gnocchi的實(shí)踐與優(yōu)化
Gnocchi是一個(gè)致力于解決Ceilometer應(yīng)用中所面臨的大規(guī)模存儲(chǔ)和索引時(shí)間序列數(shù)據(jù)的性能問(wèn)題的組件,因此在Gnocchi中涉及到比較多關(guān)于性能方面的參數(shù)。
首先是Gnocchi API,其API不僅承擔(dān)了接收上報(bào)的原始監(jiān)控?cái)?shù)據(jù)并儲(chǔ)存到Measure Storage的任務(wù),還承擔(dān)著業(yè)務(wù)系統(tǒng)通過(guò)API從Aggregate Storage索引和取出所需數(shù)據(jù)的任務(wù)。在生產(chǎn)環(huán)境中,Gnocchi API一般以WSGI或uWSGI應(yīng)用的形式來(lái)運(yùn)行,可通過(guò)Apache的mod_wsgi來(lái)運(yùn)行g(shù)nocchi-api,官方的默認(rèn)配置如下圖9:
圖 9
可根據(jù)集群規(guī)模的大小調(diào)整單個(gè)API實(shí)例中的進(jìn)程數(shù)和線程數(shù)來(lái)提高API的并發(fā)量;并且Gnocchi API是無(wú)狀態(tài)的,因此在集群規(guī)模較大時(shí),可通過(guò)部署多個(gè)gnocchi-api實(shí)例,然后通過(guò)負(fù)載均衡分發(fā)請(qǐng)求到每個(gè)gnocchi-api,以此提升gnocchi-api的并發(fā)量。
然后是Gnocchi的Metricd,即gnocchi-metricd服務(wù)進(jìn)程,是Gnocchi中最核心的部分。gnocchi-metricd不僅負(fù)責(zé)了周期性地到Measure Storage中取出并計(jì)算聚合新的監(jiān)控?cái)?shù)據(jù),還負(fù)責(zé)了按照預(yù)定策略,周期性地到Aggregate Storage中重新計(jì)算聚合舊的監(jiān)控?cái)?shù)據(jù),并且刪除已過(guò)期的監(jiān)控?cái)?shù)據(jù)。因此gnocchi-metricd服務(wù)屬于計(jì)算與I/O都是密集型的進(jìn)程,需要配置好恰當(dāng)?shù)膅nocchi-metricd workers進(jìn)程數(shù)。如果gnocchi-metricd進(jìn)程數(shù)過(guò)少,則會(huì)導(dǎo)致Measure Storage有大量的meansures積壓,并且也會(huì)導(dǎo)致Aggregate Storage中有待重新計(jì)算聚合的meansures出現(xiàn)積壓,可在OpenStack控制節(jié)點(diǎn)中執(zhí)行g(shù)nocchi status命令查看gnocchi-metricd當(dāng)前的數(shù)據(jù)處理狀態(tài),如圖10:
圖 10
一般來(lái)說(shuō),gnocchi-metricd的workers進(jìn)程數(shù)應(yīng)該在滿足meansures不會(huì)持續(xù)增加的情況下再增加2個(gè)以上的workers進(jìn)程,以滿足未來(lái)一段時(shí)間內(nèi)集群虛擬機(jī)不斷增加所帶來(lái)的監(jiān)控?cái)?shù)據(jù)增長(zhǎng)。gnocchi-metricd服務(wù)也是無(wú)狀態(tài)的,因此在集群規(guī)模較大時(shí),可通過(guò)在多個(gè)機(jī)器上部署gnocchi-metricd實(shí)例,然后協(xié)同處理集群的meansures監(jiān)控?cái)?shù)據(jù)。
然后是Gnocchi中依賴的一個(gè)Index數(shù)據(jù)庫(kù)和兩個(gè)存儲(chǔ)數(shù)據(jù)的Storage。Index可選MySQL或PostgreSQL等關(guān)系型數(shù)據(jù)庫(kù),并且其保存的數(shù)據(jù)是規(guī)整的關(guān)系數(shù)據(jù),僅用于查詢索引,數(shù)據(jù)量不會(huì)很大,因此一般不會(huì)出現(xiàn)性能瓶頸。而Measure Storage和Aggregate Storage承載了Gnocchi的大部分的I/O操作,在海量監(jiān)控?cái)?shù)據(jù)前,其性能至關(guān)重要。Gnocchi官方支持的Measure Storage和Aggregate Storage類型有普通的本地文件File、Ceph、Swift、Amazon S3等,在Gnocchi 4.0版本中還增加了Redis。官方的配置中推薦使用Ceph作為Measure Storage和Aggregate Storage,而在實(shí)踐的過(guò)程中發(fā)現(xiàn),如果Gnocchi 4.0以下的版本直接使用性能一般的Ceph集群來(lái)當(dāng)作Measure Storage和Aggregate Storage時(shí),在運(yùn)行一段時(shí)間后就可能會(huì)出現(xiàn)一些奇怪的性能問(wèn)題。如圖11,Ceph集群會(huì)頻繁地出現(xiàn)OSD ops blocked的警告,甚至出現(xiàn)OSD 自動(dòng)down的問(wèn)題:
圖 11
進(jìn)而查看OSD的日志發(fā)現(xiàn)OSD之間有大量的heartbeat check no reply以heartbeat_map出現(xiàn)had timed out的情況:
圖 12
圖 13
在此情況下Ceph集群幾乎在一種不可用狀態(tài),大量的讀寫(xiě)請(qǐng)求被Blocked,運(yùn)行在Ceph集群中的虛擬機(jī)和Cinder Volume也大量失去了響應(yīng),而此時(shí)gnocchi-api和gnocchi-metricd日志中也出現(xiàn)大量的rados讀寫(xiě)Ceph集群超時(shí)的錯(cuò)誤:
圖 14
在此類情況下需要把gnocchi-api和gnocchi-metricd進(jìn)程退出,并把Ceph中存儲(chǔ)gnocchi數(shù)據(jù)的pool刪除,待數(shù)據(jù)重新平衡才可恢復(fù)。
通過(guò)調(diào)試和摸索,發(fā)現(xiàn)其原因是Ceph對(duì)海量小文件的存儲(chǔ)支持還比較差,尤其是在多副本的情況下儲(chǔ)存Gnocchi的監(jiān)控?cái)?shù)據(jù),其總數(shù)據(jù)量是成倍的增加,究其原因這還得從Ceph的存儲(chǔ)原理來(lái)進(jìn)行分析。首先需要了解在Ceph中是以O(shè)bject來(lái)儲(chǔ)存文件的,Object的大小由RADOS限定(通常為2MB或者4MB),當(dāng)文件超過(guò)這個(gè)容量大小之后就會(huì)按照每個(gè)Object的容量對(duì)文件進(jìn)行拆分,每個(gè)對(duì)象都會(huì)有一個(gè)唯一的OID用于尋址,由ino與ono生成,ino即是文件的File ID,用于在全局唯一標(biāo)示每一個(gè)文件,而ono則是分片的編號(hào)。Ceph分割文件為對(duì)象后并不會(huì)直接將對(duì)象存儲(chǔ)進(jìn)OSD中,因?yàn)閷?duì)象的size很小,在一個(gè)大規(guī)模的集群中可能有數(shù)以億計(jì)個(gè)對(duì)象,這么多對(duì)象光是遍歷尋址,速度就已經(jīng)很緩慢了。因此Ceph中引入PG(Placement Group)的概念,這是一個(gè)邏輯上的組,Object通過(guò)crush算法映射到一組OSD上,每個(gè)PG里包含完整的副本關(guān)系,比如3個(gè)數(shù)據(jù)副本分布到一個(gè)PG里的3個(gè)不同的OSD上。下面引用Ceph論文中的一張圖(圖15)可以比較直觀地理解,將文件按照指定的對(duì)象大小分割成多個(gè)對(duì)象,每個(gè)對(duì)象根據(jù)hash映射到某個(gè)PG,然后再根據(jù)crush算法映射到后端的某幾個(gè)OSD上:
圖 15
不同的對(duì)象有可能落到同一個(gè)PG里,在Ceph實(shí)現(xiàn)里,當(dāng)PG存在op(operations)時(shí),在OSD的處理線程中就會(huì)給PG加鎖,一直到queue_transactions里把事務(wù)放到j(luò)ournal的隊(duì)列里(以filestore為例)才釋放PG的鎖。從這里可以看出,對(duì)于同一個(gè)PG里的不同對(duì)象,是通過(guò)PG鎖來(lái)進(jìn)行并發(fā)的控制,好在這個(gè)過(guò)程中沒(méi)有涉及到對(duì)象的I/O,效率還是很高的;對(duì)于不同PG的對(duì)象,可以直接進(jìn)行并發(fā)訪問(wèn)。
在Ceph中,每一個(gè)pool的PG數(shù)都是在創(chuàng)建pool的時(shí)候根據(jù)集群規(guī)模大小計(jì)算得出的合理值來(lái)設(shè)置的,也就是說(shuō)每一個(gè)pool里的PG數(shù)是有限的。在Gnocchi的監(jiān)控?cái)?shù)據(jù)中,每條數(shù)據(jù)的內(nèi)容都很小,并且每條監(jiān)控?cái)?shù)據(jù)就是一個(gè)Object,當(dāng)海量小文件存到一個(gè)PG數(shù)量較少的Ceph pool中時(shí),就會(huì)出現(xiàn)單個(gè)PG中包含太多的Object的情況,雖然PG鎖的效率很高,但是在大量小文件讀寫(xiě)時(shí)依然有可能出現(xiàn)處理不過(guò)來(lái)的情況,從而就會(huì)出現(xiàn)op blocked。
另一方面,OSD端處理op時(shí)是將op劃分為多個(gè)shard,然后每個(gè)shard里可以配置多個(gè)線程,PG按照取模的方式映射到不同的shard里進(jìn)行處理。一般來(lái)說(shuō),系統(tǒng)給每個(gè)OSD配置的處理線程都是比較少的,如果Gnocchi pool的PG在OSD端一直占用大量處理線程,那么其他Ceph pool的 PG的op就會(huì)處于等待處理狀態(tài),這時(shí)也會(huì)出現(xiàn)op blocked的情況,而OSD線程占用嚴(yán)重時(shí)甚至可能導(dǎo)致OSD進(jìn)程異常退出。在OSD端,除了將數(shù)據(jù)寫(xiě)入磁盤(pán)(Filestore)外還需要寫(xiě)入文件的Extended Attributes (XATTRs)到文件系統(tǒng)或omap(Object Map)中,面對(duì)海量的小文件讀寫(xiě),OSD的壓力I/O壓力會(huì)明顯增重。
因此在Gnocchi中的數(shù)據(jù)量達(dá)到一定程度時(shí),就可能會(huì)對(duì)Ceph存儲(chǔ)集群產(chǎn)生不利的影響。在出現(xiàn)這種情況下,以下是一些解決的方案:
方案一:在Gnocchi 4.0以下的版本中,使用Swift或本地文件File作為Measure Storage和Aggregate Storage。亦或者使用Swift或本地文件File作為Measure Storage,而Aggregate Storage繼續(xù)使用Ceph;因?yàn)镸easure Storage中保存的是原始的監(jiān)控?cái)?shù)據(jù),數(shù)據(jù)的文件條目量大并且都是小文件,而Aggregate Storage中保存的是聚合計(jì)算后的結(jié)果數(shù)據(jù),數(shù)據(jù)量相對(duì)較小。但如果Ceph集群的性能不是很好,尤其是Ceph中的OSD數(shù)量較少時(shí),并且監(jiān)控的數(shù)據(jù)量相對(duì)較大,以及需要保存較長(zhǎng)一段時(shí)間時(shí),不建議使用Ceph。
方案二:升級(jí)OpenStack中的Gnocchi版本到4.0及以上,繼續(xù)使用Ceph作為Measure Storage和Aggregate Storage。Gnocchi在4.0及之后的版本代碼中做了優(yōu)化,當(dāng)使用Ceph作為Measure Storage時(shí),Measure Storage中保存的measures是保存在Ceph OSD的omap中而不是OSD的Object文件,omap中的數(shù)據(jù)是保存在Leveldb、Rocksdb等數(shù)據(jù)庫(kù)中,所以measures的數(shù)據(jù)并不會(huì)寫(xiě)到磁盤(pán)中,以此緩解OSD的I/O壓力。Aggregate Storage中的數(shù)據(jù)依然是保存為Ceph的Object文件。但是在小型Ceph集群中,如果監(jiān)控?cái)?shù)據(jù)量比較大時(shí),依然會(huì)對(duì)Ceph集群產(chǎn)生一定的性能影響。
方案三:升級(jí)OpenStack中的Gnocchi版本到4.0及以上,使用Redis作為Measure Storage,使用Swift或Ceph作為Aggregate Storage。此方案性能最優(yōu),因?yàn)镸easure Storage中保存的measures文件量大但容量小,measures需要經(jīng)過(guò)gnocchi-api寫(xiě)入Measure Storage,gnocchi-metricd讀出處理,然后gnocchi-metricd從Measure Storage刪除等步驟。使用Redis這個(gè)內(nèi)存型的數(shù)據(jù)庫(kù)不僅可以解決Measure Storage海量小文件讀寫(xiě)頻繁的需求,并且內(nèi)存高速I(mǎi)/O帶寬的優(yōu)勢(shì)使得gnocchi-api和gnocchi-metricd在I/O處理上性能更高,系統(tǒng)并發(fā)性能更好。
四、結(jié)語(yǔ)
以上對(duì)Ceilometer監(jiān)控?cái)?shù)據(jù)采集和Gnocchi數(shù)據(jù)處理的架構(gòu)和流程作了簡(jiǎn)要的分析,并且分析了筆者在將Gnocchi和Ceph存儲(chǔ)結(jié)合使用時(shí)出現(xiàn)的一些問(wèn)題,這些問(wèn)題在出現(xiàn)在生產(chǎn)環(huán)境中是非常致命的,不僅導(dǎo)致大規(guī)模的業(yè)務(wù)不可用,甚至還可能導(dǎo)致數(shù)據(jù)丟失的風(fēng)險(xiǎn)。因此在搭建OpenStack集群時(shí),預(yù)先按照集群規(guī)模、采集的數(shù)據(jù)量等等規(guī)劃好監(jiān)控?cái)?shù)據(jù)的保存方案,對(duì)生產(chǎn)環(huán)境上線后的穩(wěn)定性意義深遠(yuǎn)。
審核編輯:符乾江
-
智能計(jì)算
+關(guān)注
關(guān)注
0文章
179瀏覽量
16517 -
云平臺(tái)
+關(guān)注
關(guān)注
1文章
1322瀏覽量
39044 -
OpenStack
+關(guān)注
關(guān)注
1文章
69瀏覽量
18928 -
Ceph
+關(guān)注
關(guān)注
1文章
22瀏覽量
9421
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論