共計 8285 個字符,預計需要花費 21 分鐘才能閱讀完成。
丸趣 TV 小編給大家分享一下 Ceph Jewel 版本三副本寫操作的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
一、主 OSD 寫處理流程
OSD::ms_fast_dispatch()
|__OSD::dispatch_session_waiting()
|__OSD::dispatch_op_fast()
|__OSD::handle_op()
|__OSD::get_pg_or_queue_for_pg() 找到 OpRequest 中對應的 PG 和 Pool 信息
|__OSD::enqueue_op()
|__PG::queue_op()
|__OSD::ShardedThreadPool::ShardedWQ::queue() 將 PG 和 Op 一起放入隊列中
OSD::ShardedOpWQ::_process() 負責處理 OSD::ShardedThreadPool::ShardedWQ 隊列中的 Op
|__PGQueueable::RunVis::operator()(const OpRequestRef op)
|__OSD::dequeue_op()
|__ReplicatedPG::do_request()
|__檢查當前 PG 是否處于 flush 或 peering 狀態,若是則將 op 放入 waiting_for_peered 隊列中等待 PG 變成可用狀態
|__檢查當前 PG 是否處于 Active 狀態,若不是則將 op 放入 waiting_for_active 隊列中
|__檢查當前 PG 是否處于 REPLAY 狀態,若是則將 op 放入 waiting_for_active 隊列中
|__ReplicatedPG::do_op()
|__RepliatedPG::do_pg_op() 對于請求中包含對 PG 的操作 CEPH_OSD_RMW_FLAG_PGOP
|__根據 op 請求創建 hobject_t 類對象 (head)
|__檢查對象名字長度 / 對象 locator key 長度 / 對象 locator 名稱空間長度是否大于 osd_max_object_name_len
|__通過 FileStore 檢查 object 的 head 是否有效
|__檢查 op 請求地址是否在 OSDMap 的 blacklist 中
|__對于寫請求,檢查寫請求的數據大小是否大于 osd_max_write_size 值
|__對于 op 請求的 head 目前不可讀,則將 op 放入 waiting_for_unreadable_object 隊列中且調用 maybe_kick_recovery() 函數嘗試啟動 recovery
|__ReplicatedPG::is_degraded_or_backfilling_object() 檢查當前 op 請求的 head 是否處于 recovery 或 backfill 狀態
|__ReplicatedPG::wait_for_degraded_object() 將當前 op 請求的 head 放入 waiting_for_degraded_object 隊列中
|__檢查 head 是否在 objects_blocked_on_degraded_snap 隊列中,若是則將當前 op 請求的 head 放入 waiting_for_degraded_object 隊列中
|__檢查 head 是否在 objects_blocked_on_snap_promotion 隊列中,若是則將當前 op 請求的 head 放入 waiting_for_blocked_object 隊列中
|__檢查 head 是否在 objects_blocked_on_cache_full 隊列中,若是則將當前 op 請求的 head 放入 waiting_for_cache_not_full 隊列中
|__檢查 head 的 snapdir 是否不可讀,若是則將 head 的 snapdir 放入 waiting_for_unreadable_object 隊列中且調用 maybe_kick_recovery() 函數嘗試啟動 recovery
|__檢查 head 的 snapdir 是否處于 recovery 或 backfill 狀態,若是則將 head 的 snapdir 放入 waiting_for_degraded_object 隊列中
|__對于 op 寫請求已經在 PGLog 中,則若已經完成了寫操作則直接給客戶端返回 MOSDOpReply 消息且設置 CEPH_OSD_FLAG_ACK,否則將 op 放入到 waiting_for_ack 或 waiting_for_ondisk 隊列中
|__ReplicatedPG::find_object_context() 得到 object context 信息
|__檢查 object context 是否處于 io blocked 狀態,若是則將 op 請求放入到 waiting_for_blocked_object 或 waiting_for_degraded_object 隊列中
|__ReplicatedPG::execute_ctx()
|__ReplicatedPG::prepare_transaction()
|__創建 MOSDOpReply 消息實例
|__ReplicatedPG::calc_trim_to() 計算 trim PGLog
|__ReplicatedPG::register_on_applied() 注冊 on_applied 回調處理函數,對于 op 請求需要 ack 且此時沒有向客戶端發送過 sent_ack 或 sent_disk,則創建 MOSDOpReply 消息且在消息上添加 CEPH_OSD_FLAG_ACK 標識后將 MOSDOpReply 消息發送給客戶端
|__ReplicatedPG::register_on_commit() 注冊 on_committed 回調處理函數, 對于 op 請求需要 ack 且此時沒有向客戶端發送過 sent_disk,則創建 MOSDOpReply 消息且在消息上添加 CEPH_OSD_FLAG_ACK 和 CEPH_OSD_FLAG_ONDISK 標識后將 MOSDOpReply 消息發送給客戶端
|__ReplicatedPG::register_on_success() 注冊 on_success 回調處理函數
|__ReplicatedPG::register_on_finish() 注冊 on_finish 回調處理函數
|__ReplicatedPG::new_repop() 創建 RepGather 類對象
|__ReplicatedPG::issue_repop()
|__創建 C_OSD_RepopCommit 類對象,即:所有副本都完成 commit 后的回調函數類,在該函數中設置 repop- all_committed=true,最后調用 ReplicatedPG::eval_repop()
|__創建 C_OSD_RepopApplied 類對象,即:所有副本都完成 applied 后的回調函數類,在該函數中設置 repop- all_applied=true,最后調用 ReplicatedPG::eval_repop()
|__ReplicatedBackend::submit_transaction()
|__ReplicatedBackend::issue_op()
|__ReplicatedBackend::generate_subop() 創建 MOSDRepOp 消息類對象
|__ReplicatedPG::send_message_osd_cluster()
|__OSD::send_message_osd_cluster() 將 MOSDRepOp 消息發送給副本所在的 OSDs 節點
|__創建 C_OSD_OnOpApplied 類對象,用來處理本地 applied 完成后的回調函數類
|__創建 C_OSD_OnOpCommit 類對象,用來處理本地 commit 完成后的回調函數類
|__RepliatedPG::queue_transactions()
|__ObjectStore::queue_transactions()
|__FileStore::queue_transactions()
|__JournalingObjectStore::_op_journal_tranactions()
|__FileJournal::submit_entry() 將寫日志請求提交到日志任務隊列中,日志寫完后回調 C_JournaledAhead 類對象
|__ReplicatedPG::eval_repop()
|__檢查 repop- rep_done 是否完成
|__檢查 repop- all_commit,即:是否所有副本都完成日志寫入,若完成則回調 on_committed() 回調函數
|__檢查 repop- all_applied,即:是否所有副本都完成落盤,若完成則回調 on_applied() 回調函數
|__檢查 repop- all_commit 和 repop- all_applied,即:是否所有副本都完成寫入操作,若完成則調用 repop- on_success() 回調函數
本地寫日志完成后的處理流程
C_JournaledAhead::finish()
|__FileStore::_journaled_ahead()
|__FileStore::queue_op() 將寫請求放入到 FileStore 的 op_wq 隊列中
|__回調 C_OSD_OnOpCommit 類對象的處理函數
本地數據落盤處理流程
FileStore::_do_op()
|__從 op_wq 隊列中讀取寫請求
|__FileStore::_do_transactions() 執行實際的寫數據操作
本地數據落完完成后的處理流程
FileStore::_finish_op()
|__回調 C_OSD_OnOpApplied 類對象的處理函數
二、副本 OSD 處理主 OSD 發送過來的寫請求 (消息是 MOSDRepOp,消息類型是 MSG_OSD_REPOP)
OSD::ms_fast_dispatch()
|__OSD::dispatch_session_waiting()
|__OSD::dispatch_op_fast()
|__OSD::handle_replica_op()
|__檢查發送方有效性
|__OSD::get_pg_or_queue_for_pg() 找到 OpRequest 中對應的 PG 和 Pool 信息
|__OSD::enqueue_op()
|__PG::queue_op()
|__OSD::ShardedThreadPool::ShardedWQ::queue() 將 PG 和 Op 一起放入隊列中
OSD::ShardedOpWQ::_process() 負責處理 OSD::ShardedThreadPool::ShardedWQ 隊列中的 Op
|__PGQueueable::RunVis::operator()(const OpRequestRef op)
|__OSD::dequeue_op()
|__ReplicatedPG::do_request()
|__ReplicatedBackend::handle_message()
|__ReplicatedBackend::sub_op_modify()
|__ReplicatedPG::log_operation()
|__PG::append_log() 寫 PGLog
|__創建 C_OSD_RepModifyCommit 類實例,用于處理日志 commit 完成后的回調處理
|__創建 C_OSD_RepModifyApply 類實例,用于處理數據落盤完成后的回調處理
|__ReplicatedPG::queue_transactions()
|__FileStore::queue_transactions()
|__JournalingObjectStore::_op_journal_tranactions()
|__FileJournal::submit_entry() 將寫日志請求提交到日志任務隊列中,日志寫完后回調 C_JournaledAhead 類對象
本地寫日志完成后的處理流程
C_JournaledAhead::finish()
|__FileStore::_journaled_ahead()
|__FileStore::queue_op() 將寫請求放入到 FileStore 的 op_wq 隊列中
|__回調 C_OSD_RepModifyCommit 類對象的處理函數
本地數據落盤處理流程
FileStore::_do_op()
|__從 op_wq 隊列中讀取寫請求
|__FileStore::_do_transactions() 執行實際的寫數據操作
本地數據落完完成后的處理流程
FileStore::_finish_op()
|__回調 C_OSD_RepModifyApply 類對象的處理函數
三、主 OSD 處理副本 OSDs 發送過來的 MOSDRepOpReply 消息處理流程 (消息類型 MSG_OSD_REPOPREPLY)
OSD::ms_fast_dispatch()
|__OSD::dispatch_session_waiting()
|__OSD::dispatch_op_fast()
|__OSD::handle_replica_op()
|__檢查發送方有效性
|__OSD::get_pg_or_queue_for_pg() 找到 OpRequest 中對應的 PG 和 Pool 信息
|__OSD::enqueue_op()
|__PG::queue_op()
|__OSD::ShardedThreadPool::ShardedWQ::queue() 將 PG 和 Op 一起放入隊列中
OSD::ShardedOpWQ::_process() 負責處理 OSD::ShardedThreadPool::ShardedWQ 隊列中的 Op
|__PGQueueable::RunVis::operator()(const OpRequestRef op)
|__OSD::dequeue_op()
|__ReplicatedPG::do_request()
|__ReplicatedBackend::handle_message()
|__ReplicatedBackend::sub_op_modify_reply()
|__對于設置了 CEPH_OSD_FLAG_ONDISK 標識的消息來說,刪除 waiting_for_commit 隊列中對應的 OSD ID
|__刪除 waiting_for_applied 隊列中對應的 OSD ID
|__對于 waiting_for_commit 隊列為空,則調用 C_OSD_RepopCommit 類對象的回調函數
|__對于 waiting_for_applied 隊列為空,則調用 C_OSD_RepopApplied 類對象的回調函數
四、回調函數類處理
C_OSD_RepModifyCommit 類處理流程
C_OSD_RepModifyCommit::finish()
|__ReplicatedBackend::sub_op_modify_commit()
|__創建 MOSDRepOpReply 消息且設置 CEPH_OSD_FLAG_ONDISK 標識
|__ReplicatedPG::send_message_osd_cluster()
|__OSD::send_message_osd_cluster() 將 MOSDRepOpReply 消息發送回主 OSD
C_OSD_RepModifyApply 類處理流程
C_OSD_RepModifyApply::finish()
|__ReplicatedBackend::sub_op_modify_applied()
|__創建 MOSDRepOpReply 消息且設置 CEPH_OSD_FLAG_ACK 標識(針對沒有進行日志處理的情況)
|__ReplicatedPG::send_message_osd_cluster()
|__OSD::send_message_osd_cluster() 將 MOSDRepOpReply 消息發送回主 OSD
C_OSD_OnOpCommit 處理流程
C_OSD_OnOpCommit::finish()
|__ReplicatedBackend::op_commit()
|__刪除 waiting_for_commit 數組中對應 OSD ID 信息
|__檢查 waiting_for_commit 數組是否為空,若為空則調用 C_OSD_RepopCommit 類對象的回調函數
C_OSD_OnOpApplied 處理流程
C_OSD_OnOpApplied::finish()
|__ReplicatedBackend::op_applied()
|__刪除 waiting_for_applied 數組中對應 OSD ID 信息
|__檢查 waiting_for_applied 數組是否為空,若為空則調用 C_OSD_RepopApplied 類對象的回調函數
看完了這篇文章,相信你對“Ceph Jewel 版本三副本寫操作的示例分析”有了一定的了解,如果想了解更多相關知識,歡迎關注丸趣 TV 行業資訊頻道,感謝各位的閱讀!