概述
OSD是RADOS集群的基本存儲單元。
PG(placement group)從名字可理解為放置策略組,它是對象的集合,該集合里的所有對象都具有相同的放置策略:對象的副本都分布在相同的OSD列表上。一個對象只能屬於一個PG,一個PG對應於放置在其上的OSD列表。一個OSD上可以分布多個PG。處理來自客戶端的讀寫請求是PG的基本功能。
Pool是整個集群層面定義的一個邏輯的存儲池,它規定了數據冗余的類型以及對應的副本分布策略。目前實現了兩種pool類型:replicated類型和Erasure Code類型。一個pool由多個PG構成。
讀寫流程
讀寫流程大致分為以下幾個階段:
- 客戶端基於對象標識中的32位哈希值,通過stable_mod找到存儲池中承載該對象的PGID,然后使用該PGID作為CRUSH輸入,找到對應PG當前Primary所在的OSD並發送讀寫請求。
- OSD收到客戶端發送的讀寫請求,將其封裝為一個op,並基於其攜帶的PGID將其轉發至對應的PG。
- PG收到op后,完成一些列檢查,所有條件均滿足后,開始真正執行op。
- 如果op只包含讀操作,那么直接執行同步讀(對應多副本)或者異步讀(對應糾刪碼),等待讀操作完成后由Primary向客戶端應答。
- 如果op包含寫操作,則由Primary基於op生成一個針對原始對象操作的PG事務,然后將其提交至PGBackend,由后者按照備份策略轉化為每個副本真正需要執行的本地事務,並進行分發。當Primary收到所有副本的寫入完成應答之后,對應op執行完成,由Primary向客戶端回應寫入完成。
對象尋址
對象尋址參考client寫操作部分。
消息接收與分發
讀寫請求都是從OSD::ms_fast_dispatch開始,它是接收讀寫消息message的入口。
消息出隊處理
do_request
主要進行PG級別的檢查,處理流程:
do_op
主要進行對象級別的檢查和一些上下文的准備工作。處理流程:
execute_ctx
prerare_transaction操作主要分為三個階段:
- 通過do_osd_ops生成原始op對應的PG事務。
- 如果op針對head對象操作通過make_writeable檢查是否需要預先執行克隆操作。
- 通過finish_ctx生成操作原始對象的日志,並更新對象的OI和SS屬性。
do_osd_ops:
對於讀操作,在do_osd_ops()->do_read()中,如果是同步讀直接調用pgbackend->objects_read_sync進行讀操作。如果是異步讀,先將op添加到pending_async_reads中,然后在execute_ctx()檢測pending_async_reads隊列時執行讀操作。
寫操作步驟如下:
make_writeable:
如果op針對head對象操作,通過make_writeable檢查是否需要預先執行克隆操作。
finish_ctx:
PG事務的內存版本已經准備完畢,此時可以生成原始對象的操作日志,並更新對象上下文中OI與SS屬性。