Ceph Monitor的數據管理


轉自:https://www.ustack.com/blog/ceph-monitor-2/

Monitor管理了Ceph的狀態信息,維護着Ceph中各個成員的關系,這些信息都是存放在leveldb中的,但是這些數據是如何生成的?又是如何消亡的。本文旨在展現Ceph monitor中數據的生老病死,帶領讀者走入Monitor的世界。

數據概覽

首先我們分析的版本是0.94.7的版本,也就是目前Hammer最新的版本。對於leveldb中的數據,我們需要來一個感性的認識,請看下面數據,由於數據太多這里僅僅列出了key:

111111111111

可以看到這里有paxos,有monmap,osdmap,mdsmap,auth,logm,和上一篇(Ceph Monitor基礎架構與模塊詳解)中的Monitor的架構圖很像。paxos記錄了每次propose的value,具體可以這么來看:

222222222

以paxos:1869為例,paxos為prefix,1869為key。可以將不同的prefix當做不同的表,里面的key是主鍵,其存儲的值是value,這里paxos:1869存儲的就是Monitor一致同意的1869次決議。所有的狀態的變化都是從這個決議里產生的。
那我們有什么方式可以查看決議的內容呢?我們可以通過如下命令先將數據從leveldb中導出來:

333333333

然后使用ceph-dencoder工具來查看:

44444444444

從上面的數據輸出我們可以得出一下幾點:

  • paxos:1869存儲的是MonitorDBStore::Transaction序列化后的數據
  • Monitor的Transaction和Osd的Transaction類似,都封裝了多個op的操作
  • log通過paxos來保持一致性,所以這里有,同理osdmap,monmap,pgmap等都應該Transaction里
  • 這里僅僅是paxos決議的值,但是上面有osdmap的key,那么osdmap:num的val應該也是和paxos里相應的內容一樣
  • Paxos應該有Trim機制,因為如果數據一致這么存下去,不是辦法

Paxos決議流程

到這里需要講一下Paxos算法,因為Monitor里面數據的更新操作都是通過Paxos決議來完成的,也就是說Paxos掌管着Monitor數據的“生”。

Paxos解決了什么問題?
Paxos算法解決了分布式環境中一個不變量的值的一致性問題。

解決了一個值的問題有用嗎?
我們的決議號就是這個變量。里面存放了決議的內容。決議內容通過之后,就把其寫入數據庫。我們可以將無數內容放到這個變量的值里面。有什么放不進去的嗎?沒有!當我們能夠在分布式環境中確定一個變量的值的時候,已經足夠我們使用了。

為什么是一個不變量的值?
這個不變量可以理解為C語言中的常量,一旦確定之后就不能改變,這里的不變就是一旦決議通過之后,無論發生什么情況,決議n的值還是當初通過的那個值。
但是我們怎么用呢?都不變了,我們用它干嘛?其實從上面的解釋就已經可以看出來,我們說了是一個不變量的值,並不是一直就是一個變量,決議n的值確定了之后,我們可以再決議n+1的值。Ceph也正是這么用的,從上面的list出來的內容就可以大致了解。

Monitor更新一個值的流程:

1、Leader

1)設置new_value =v,v中值就是我們上面看到的paxos:1869中的值,都是kv。
2)將自己加入到同意者集合。
3)生成MonitorDBStore::Transaction, 以paxos為前綴,last_commited+1 的key來將v寫入到leveldb中,同時更新pending_v,和pending_pn。
4)將new_value, last_commited和accepted_pn發送給quorum中的所有成員。

2、Peon

1)判斷自己的accepted_pn和Leader發送過來的accepted_pn是否相等,如果小於就忽略,認為是舊一輪的決議。
2)判斷自己last_commited是否和leader發送過來的相關,如果不相關,就是出現了不一致,直接assert。
3)同Leader中的3)。
4)將accpted_pn 和 last_commited發送給Leader。

3、Leader

1)判斷Peon發送過來的pn是不是和自己的accepted_pn一致,如果不等可能有則返回。
2)判斷last_commited,如果Peon發送過來的last_commited比last_commted -1 小,則認為是舊一輪的消息,丟棄。
3)判斷Peon是否在同意者結合,如果不在就加入,如果在,說明一個Peon發送了兩次accept消息,Leader直接assert。
4)當接受者結合和quorum結合一樣的時候,也就是大多數人都同意了,Leader提交決議。
5)更新leveldb中的last_commited為last_commited + 1。
6)將new_value中的數據都展開封裝成transaction,然后寫入,插入回調。
7)當Leader完成本地的提交之后,調用回調向quorum中的所有成員發送commit消息 。

4、Peon

1)在接收到commit消息之后,進行內部提交。

這里有幾點需要說明的是:
在決議的過程中其實提交了Leader提交了兩次,一次是直接將決議當做bl寫入paxos的prefix中,另一次是將bl解析出來(bl里的內容都是封裝的小的op操作)在寫入bl里封裝的prefix的庫中。
所有的update操作的請求都會路由到Leader,也就是說無論你有3個,或者5個,在處理update請求的時候只會是1個。

OSDMap的管理

這里我們以OSDMap為例,來看看它是如何從生成到進庫的。
當有osd up或者down的時候,monitor會感知到。當消息走到prepare_update的時候,會在各自的prepare函數經過各種處理,最終會將更新紀錄到pending_inc中。因為OSDMap的更新全紀錄在pending_inc這個變量里。然后在dispatch中,會判斷是不是要走決議流程,如果走了決議流程之后會首先將pending_inc中的內容encode進transaction,這里調用了一個很重要的函數encode_pending。在這個函數里將pending_inc中該有的內容都塞進了transaction。當有了這個transaction之后,就是會走我們上面講的Paxos決議流程了。最終這些決議會持久化到leveldb中。

從上面我們可以看到Monitor的架構,這里雖然講的是OSDMonitor怎么處理消息的,但是MDSMonitor,MonMapMonitor都是一樣的。Update操作改變自己的pending_inc,然后在encode_pending的時候生成transaction,然后就是走決議流程。

同樣可以通過以下命令將osdmap拿出來看看:

55555555555

總結
本文首先通過工具從leveldb中將monitor的數據拿出來,大概了解了Monitor的數據內容,然后分析了生成數據的流程–Paxos決議,最后使用一個簡單的例子OSDMap來講述了OSDMap數據是如何生成和存儲的。希望本文能夠幫助讀者了解Mon,從而對Ceph有更深刻的理解,以便大家開發出更好的產品,以及對客戶更優質的服務。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM