Ceph Jewel版本三副本写操作的示例分析

53次阅读
没有评论

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

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计8285字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)