共计 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 行业资讯频道,感谢各位的阅读!