【圖文教程】打造高性能、高可靠的塊存儲系統(tǒng)
塊存儲系統(tǒng)
分布式存儲有出色的性能,可以扛很多故障,能夠輕松擴展,所以我們使用Ceph構(gòu)建了高性能、高可靠的塊存儲系統(tǒng),并使用它支撐公有云和托管云的云主機、云硬盤服務(wù)。
由于使用分布式塊存儲系統(tǒng),避免了復(fù)制鏡像的過程,所以云主機的創(chuàng)建時間可以縮短到10秒以內(nèi),而且云主機還能快速熱遷移,方便了運維人員對物理服務(wù)器上硬件和軟件的維護。
用戶對于塊存儲系統(tǒng)最直觀的感受來源于云硬盤服務(wù),現(xiàn)在我們的云硬盤的特點是:
- 每個云硬盤***支持 6000 IOPS和170 MB/s的吞吐率,95%的4K隨機寫操作的延遲小于2ms 。
- 所有數(shù)據(jù)都是三副本,強一致性,持久性高達10個9。
- 創(chuàng)建、刪除、掛載、卸載都是秒級操作。
- 實時快照。
- 提供兩種云硬盤類型,性能型和容量型。
軟硬件配置
經(jīng)過多輪的選型和測試,并踩過無數(shù)的坑之后,我們選擇了合適我們的軟件和硬件。
軟件
硬件
- 從SATA磁盤到SSD,為了提高IOPS和降低Latency。
- 從消費級SSD到企業(yè)級SSD,為了提高可靠性。
- 從RAID卡到HBA卡,為了提高IOPS和降低Latency。
最小部署架構(gòu)
隨著軟硬件的升級,需求的調(diào)整, 我們的部署架構(gòu)也不斷在演進,力求在成本、性能、可靠性上達到***平衡點。
最小規(guī)模部署中有12個節(jié)點,每個節(jié)點上有3塊SSD。節(jié)點上有2個萬兆口和1個千兆口,虛擬機網(wǎng)絡(luò)和存儲網(wǎng)絡(luò)使用萬兆口,管理網(wǎng)絡(luò)使用千兆口。每個集群中都有3個Ceph Monitor節(jié)點。
輕松擴展
云計算的好處是極強的擴展性,作為云計算的底層架構(gòu),也需要有快速的Scale-out能力。在塊存儲系統(tǒng)的部署架構(gòu)中,可以以12臺節(jié)點為單位進行擴展。
改造OpenStack
原生的OpenStack并不支持統(tǒng)一存儲,云主機服務(wù)Nova、鏡像服務(wù)Glance、云硬盤服務(wù)Cinder的后端存儲各不相同,造成了嚴重的內(nèi)耗。我們把這三大服務(wù)的后端統(tǒng)一起來,進行高效管理,解決了虛擬機創(chuàng)建時間長和鏡像風(fēng)暴等問題,還能讓虛擬機隨便漂移。
原生的OpenStack
改造后的OpenStack
使用原生的OpenStack創(chuàng)建虛擬機需要1~3分鐘,而使用改造后的OpenStack僅需要不到10秒鐘時間。這是因為nova-compute不再需要通過HTTP下載整個鏡像,虛擬機可以通過直接讀取Ceph中的鏡像數(shù)據(jù)進行啟動。
我們還增加兩個OpenStack沒有的功能: QoS 和 共享云硬盤。云計算的另外一個好處是租戶資源隔離,所以必備QoS。共享云硬盤可以掛載給多臺云主機,適用于數(shù)據(jù)處理的場景。
我們還使用了OpenStack的multi-backend功能,支持多種云硬盤類型,現(xiàn)在我們的云硬盤類型有性能型、容量型,可以滿足數(shù)據(jù)庫和大文件應(yīng)用。
#p#
高性能
存儲系統(tǒng)主要的性能指標(biāo)是IOPS和Latency。我們對于IOPS的優(yōu)化已經(jīng)達到了硬件的瓶頸,除非更換更快的固態(tài)硬盤或者閃存卡,或者是改變整個架構(gòu)。我們對于Latency的優(yōu)化也快接近完成,可以達到企業(yè)級存儲的水平。
復(fù)雜的I/O棧
整個塊存儲系統(tǒng)有著長長的I/O棧,每個I/O請求要穿過很多線程和隊列。
優(yōu)化操作系統(tǒng)
優(yōu)化操作系統(tǒng)的參數(shù)可以充分利用硬件的性能。
CPU
- 關(guān)閉CPU節(jié)能模式
- 使用Cgroup綁定Ceph OSD進程到固定的CPU Cores上
Memory
- 關(guān)閉NUMA
- 設(shè)置vm.swappiness=0
Block
- 設(shè)置SSD的調(diào)度算法為deadline
FileSystem
- 設(shè)置掛載參數(shù)”noatime nobarrier”
優(yōu)化Qemu
Qemu作為塊存儲系統(tǒng)的直接消費者,也有很多值得優(yōu)化的地方。
- Throttle: 平滑的I/O QoS算法
- RBD: 支持discard和flush
- Burst: 支持突發(fā)請求
- Virt-scsi: 支持多隊列
優(yōu)化Ceph
我們對于Ceph的優(yōu)化是重頭戲,有很多問題也是時間長、規(guī)模上去之后才暴露出來的。
#p#
高可靠性
存儲需要高可靠性,保證數(shù)據(jù)可用并且數(shù)據(jù)不丟失。因為我們的架構(gòu)中沒有使用UPS和NVRAM,所以寫請求的數(shù)據(jù)都是落到三塊硬盤之后才返回,這樣***限度地保證了用戶的數(shù)據(jù)安全。
如何計算持久性
持久性是數(shù)據(jù)丟失的概率,可以用于度量一個存儲系統(tǒng)的可靠性,俗稱 “多少個9”。數(shù)據(jù)的放置(DataPlacement)決定了數(shù)據(jù)持久性,而Ceph的CRUSH MAP又決定了數(shù)據(jù)的放置,因此CRUSH MAP的設(shè)置決定了數(shù)據(jù)持久性。但是,即時我們知道需要修改CRUSH MAP的設(shè)置,但是我們應(yīng)該怎么修改CRUSH MAP的設(shè)置呢,我們該如何計算數(shù)據(jù)持久性呢?
我們需要一個計算模型和計算公式,通過以下資料,我們可以構(gòu)建一個計算模型和計算公式。
- Reliability model
- 《CRUSH: Controlled, Scalable, Decentralized Placement of Replicated Data》
- 《Copysets: Reducing the Frequency of Data Loss in Cloud Storage》
- 《Ceph的CRUSH數(shù)據(jù)分布算法介紹》
最終的計算公式是: P = func(N, R, S, AFR)
- P: 丟失所有副本的概率
- N: 整個Ceph Pool中OSD的數(shù)量
- R: 副本數(shù)
- S: 在一個Bucket中OSD的個數(shù)
- AFR: 磁盤的年平均故障率
這個計算模型是怎么樣得到計算公式的呢?下面是4個步驟。
- 先計算硬盤發(fā)生故障的概率。
- 定義哪種情況下丟失數(shù)據(jù)不能恢復(fù)。
- 計算任意R個OSD發(fā)生故障的概率。
- 計算Ceph丟失PG的概率。
硬盤發(fā)生故障的概率是符合泊松分布的:
- fit = failures in time = 1/MTTF ~= 1/MTBF = AFR/(24*365)
- 事件概率 Pn(λ,t) = (λt)n e-λt / n!
Ceph的每個PG是有R份副本的,存放在R個OSD上,當(dāng)存有這個PG的R個OSD都發(fā)生故障時,數(shù)據(jù)是不可訪問的,當(dāng)這R個OSD都損壞時,數(shù)據(jù)是不可恢復(fù)的。
計算一年內(nèi)任意R個OSD發(fā)生相關(guān)故障概率的方法是:
- 計算一年內(nèi)有OSD發(fā)生故障的概率。
- 在Recovery時間內(nèi),(R-1)個OSD發(fā)生故障的概率。
- 以上概率相乘,就是一年內(nèi)任意R個OSD發(fā)生相關(guān)故障概率,假設(shè)是 Pr。
- N個OSD中,任意R個OSD的組合數(shù)是C(R, N)。
因為這任意R個OSD不一定存有同一個PG的副本,所以這任意R個OSD發(fā)生故障并不會導(dǎo)致數(shù)據(jù)不可恢復(fù),也就是不一定會導(dǎo)致數(shù)據(jù)丟失。
假設(shè)每個PG對應(yīng)一組OSD(有R個OSD, 稱之為Copy Set),有可能多個PG對應(yīng)同一組OSD。假設(shè)有M個不同的Copy Set, M是一個非常重要的數(shù)字。
我們再來對Copy Set進行精確的定義:Copy Set上至少有一個PG的所有副本,當(dāng)這個Copy Set損壞時,這個PG的所有副本也會丟失,這個PG上的所有數(shù)據(jù)就不可恢復(fù)。所以Ceph丟失數(shù)據(jù)的事件就是Ceph丟失PG, Ceph丟失PG就是有一個Copy Set發(fā)生損壞,一個Copy Set丟失的概率就是 P = Pr * M / C(R, N) 。
持久性公式就是個量化工具,它可以指明努力的方向。我們先小試牛刀,算一下默認情況下的持久性是多少?
假設(shè)我們有3個機架,每個機架上有8臺節(jié)點,每個幾點上有3塊硬盤,每個硬盤做一個OSD,則一共有72個OSD。
默認的crush map設(shè)置如下所示
通過持久性公式,我們得到下面的數(shù)據(jù)。
默認情況下,持久性有8個9,已經(jīng)比一般的RAID5、RAID10要高,和RAID6差不多,但是還不能滿足公有云的要求,因為公有云的規(guī)模很大,故障事件的數(shù)學(xué)期望也會很大,這就逼著我們盡量提高持久性。
提高持久性的方法有很多,比如增加副本數(shù),使用Erase Code等。不過這些方法都有弊端,增加副本數(shù)勢必會擴大成本;使用Erase Code會導(dǎo)致Latency提高,不適合于塊存儲服務(wù)。在成本和Latency的制約下,還有什么辦法可以提高持久性呢?
前面我們已經(jīng)得到一個量化公式 P = Pr * M / C(R, N), 我們從量化公式入手,去提高持久性(也就是降低P)。要想降低P, 就得降低Pr、M,或者是提高C(R, N)。因為C(R, N)已經(jīng)確定,我們只能降低Pr和M。
降低恢復(fù)時間
從Pr的定義可以知道Pr與恢復(fù)時間有關(guān),恢復(fù)時間越短,Pr的值越低。那么恢復(fù)時間跟什么有關(guān)系呢?
我們需要增加更多的OSD用于數(shù)據(jù)恢復(fù),以便減少恢復(fù)時間。目前host bucket不能增加更多的OSD,這是因為主機的網(wǎng)絡(luò)帶寬限制和硬盤插槽限制。解決辦法是從CRUSH MAP入手,增加一種虛擬的Bucket: osd-domain, 不再使用host bucket。
通過使用osd-domain bucket,我們把持久性提高了10倍,現(xiàn)在持久性有9個9。
減少Coepy Set個數(shù)
如何減少Copy Set的個數(shù)呢?Copy Sets是和PG的映射有關(guān)的,我們從CRUSH MAP的規(guī)則和條件入手,減少Copy Set的個數(shù)。解決辦法增加虛擬的Bucket: replica-domain, 不再使用rack bucket。每個PG必須在一個replica-domain上,PG不能跨replica-domain,這樣可以顯著減少Copy Set的個數(shù)。
通過使用replica-domain,現(xiàn)在的持久性有10個9,持久性比默認的crush map設(shè)置提高了100倍。
#p#
自動化運維
Ceph的運維比較費心,稍有差池,整個云平臺都會受到影響,因此我們覺得運維的目標(biāo)是可用性:
減少不必要的數(shù)據(jù)遷移,進而減少slow requests,保證SLA。
部署
我們整個云平臺都是使用Puppet部署的,因此我們使用了Puppet去部署Ceph。一般Ceph的安裝是分階段的:
- 安裝好Ceph Monitor集群。
- 格式化Disk,使用文件系統(tǒng)的UUID去注冊O(shè)SD, 得到OSD ID。
- 根據(jù)OSD ID去創(chuàng)建數(shù)據(jù)目錄,掛載Disk到數(shù)據(jù)目錄上。
- 初始化CRUSH MAP。
Puppet只需要完成前三步,第四步一般根據(jù)具體情況用腳本去執(zhí)行。因為OSD ID是在執(zhí)行過程中得到的,而Puppet是編譯后執(zhí)行,這是一個悲傷的故事,所以puppet-ceph模塊必須設(shè)計成retry的。
相比eNovance和Stackforge的puppet-ceph模塊,我們的puppet-ceph模塊的優(yōu)點是:
- 更短的部署時間
- 支持Ceph所有的參數(shù)
- 支持多種硬盤類型
- 使用WWN-ID替代盤符。
維護
升級Ceph的過程很簡單,三條命令就可以搞定:
- ceph osd set noout #避免在異常情況下不可控
- ceph osd down x #提前mark down, 減少slow request
- service ceph restart osd.x
更換硬件或者升級內(nèi)核時需要對機器進行重啟,步驟也很簡單:
- 把這臺機器上的虛擬機遷移到其他機器上
- ceph osd set noout
- ceph osd down x #把這個機器上的OSD都設(shè)置為down狀態(tài)
- service ceph stop osd.x
- 重啟機器
擴展集群的時候需要非常小心,因為它會觸發(fā)數(shù)據(jù)遷移:
- 設(shè)置crush map
- 設(shè)置recovery options
- 在凌晨12點觸發(fā)數(shù)據(jù)遷移
- 觀察數(shù)據(jù)遷移的速度,觀察每個機器上網(wǎng)口的帶寬,避免跑滿
- 觀察slow requests的數(shù)量
你總會碰到硬盤損壞的時候,替換硬盤時需要非常小心,你要小心的設(shè)置crush map,你要保證要替換硬盤過程中replica-domain的weight的值是不變的,這樣才能保證不必須要的數(shù)據(jù)遷移。
監(jiān)控
Ceph自家的Calamari長得不錯,但是不夠?qū)嵱?,而且它的部署、打包還不完善,在CentOS上還有一些BUG,我們只能繼續(xù)使用原有的工具。
- 收集:使用diamond,增加新的colloctor,用于收集更詳細的數(shù)據(jù)。
- 保存:使用graphite,設(shè)置好采集精度和保存精度。
- 展示:使用grafana,挑了十幾個工具,發(fā)現(xiàn)還是grafana好看好用。
- 報警:zabbix agent && ceph health
我們根據(jù)Ceph軟件架構(gòu)對每個OSD分成了很多個throttle層,下面是throttle模型:
有了throttle model,我們可以對每個throttle進行監(jiān)控,我們在diamond上增加了新的collector用于對這些throttle進行監(jiān)控,并重新定義了metric name。
***,我們可以得到每個OSD每層throttle的監(jiān)控數(shù)據(jù)。但平時只會關(guān)注IOPS、吞吐率、OSD Journal延遲、讀請求延遲、容量使用率等。
事故
在云平臺上線已經(jīng)快一年了,我們遇到的大小事故有:
- SSD GC問題,會導(dǎo)致讀寫請求的Latency非常大,飆到幾百毫秒。
- 網(wǎng)絡(luò)故障,會導(dǎo)致Monitor把OSD設(shè)置為down狀態(tài)。
- Ceph Bug, 會導(dǎo)致OSD進程直接崩掉。
- XFS Bug, 會導(dǎo)致集群所有OSD進程直接崩掉。
- SSD 損壞。
- Ceph PG inconsistent。
- Ceph數(shù)據(jù)恢復(fù)時把網(wǎng)絡(luò)帶寬跑滿。
總體來說,Ceph是非常穩(wěn)定和可靠的。
【本文來源:運維幫微信號】