深入解析 Crimson OSD 生命周期状态机:从 preboot、booting 到 active 的完整启停流程
深入解析 Crimson OSD 生命周期状态机从 preboot、booting 到 active 的完整启停流程【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/ceph本文以 Ceph 新一代 OSD 实现 Crimson基于 Seastar 协程的异步 OSD 守护进程的OSDState状态机为主题系统讲解 OSD 从启动注册、健康检查、等待激活到优雅下线的全部状态转换及其背后消息协议。读完本文你将掌握 Crimson OSD 五个核心状态preboot、booting、active、prestop、waiting_for_healthy的语义、状态迁移触发条件并能对照源码src/crimson/osd/state.h、src/crimson/osd/osd.cc追踪MOSDBoot、MOSDMarkMeDown等消息在启动与停机路径中的实际作用。为什么 Crimson OSD 需要显式的状态机经典ceph-osd的启动与停止逻辑分散在OSD::init()、OSD::handle_osd_map()等大量回调中状态边界并不直观。Crimson 采用 Seastar 的sharded架构把 OSD 拆分为多个 shard 并行运行因此需要一个集中、可广播、可被各 shard 查询的守护进程级状态。OSDState类src/crimson/osd/state.h正是为此设计它继承seastar::peering_sharded_serviceOSDState每个 shard 持有一个本地实例状态枚举定义了 7 个值state.h#L30-L38INITIALIZING、PREBOOT、BOOTING、ACTIVE、PRESTOP、STOPPING、WAITING_FOR_HEALTHYPRIMARY_COREcore 0是状态迁移的权威执行者set_active()/set_stopping()通过invoke_on_all把状态广播到所有 shardstate.h#L95-L111任意 shard 都可以只读查询is_active()、is_stopping()并通过when_active()挂起等待直到 OSD 进入activestate.h#L68-L74。从源码结构看OSDState比文档状态图多出INITIALIZING与STOPPING两个内部状态前者表示 OSD 仍在初始化、尚未订阅 osdmap_handle_osd_map()会因此直接丢弃收到的地图见 osd.cc#L1183-L1186后者表示已进入最终停止流程。状态机总览原始设计文档 doc/dev/crimson/osd.rst 用 graphviz 描绘了如下状态迁移本文以 Mermaid 状态图呈现同一语义状态进入条件退出条件语义waiting_for_healthy心跳不可达或内部心跳失败tick周期性复查恢复健康后转preboot自检等待健康preboot守护进程启动 / 被标记 down 后地图就绪后发送MOSDBoot转booting准备注册booting发出MOSDBoot收到标记自己为 up 的 osdmap 转active等待被 quorum 认可activeosdmap 标记自己为 upstop()/ 被标 down / SIGINT / 不健康正常服务业务prestop收到stop请求收到更新后的 osdmap 或MOSDMarkMeDown优雅下线前的收尾各状态语义详解waiting_for_healthy先证明自己健康再谈服务如果 OSD 守护进程无法连接到自己的心跳heartbeat对端或者自身内部心跳失败它就被判定为不健康进入waiting_for_healthy状态并周期性检查自身的网络可达性与内部心跳状态直到恢复健康后才继续启动流程。对应到代码心跳子系统由 src/crimson/osd/heartbeat.h 的Heartbeat类实现它实现了crimson::net::Dispatcher接口监听心跳消息并维护与对端 OSD 的连接会话。需要说明的是从当前源码看waiting_for_healthy的完整实现仍处于待完善状态在 osd.cc#L1329-L1336 有一处注释明确写着TODO: Missing start_waiting_for_healthy() counterpart关联跟踪单 66832当前实现是在未停止时持续订阅下一份 osdmap。这意味着文档描述的是该状态的既定设计意图而代码中进入waiting_for_healthy并周期性 tick 自检的完整闭环仍在演进中。preboot向 Monitor 报告我准备好了preboot是 OSD 启动后的第一个正式状态。OSD 向已连接的 Monitor 发送MOSDBoot消息告知集群它已准备好对外服务从而让 quorum 在 osdmap 中把它标记为up。源码中的启动入口是OSD::start_boot()osd.cc#L641-L648seastar::future OSD::start_boot() { pg_shard_manager.set_preboot(); return monc-get_version(osdmap).then(this { auto [newest, oldest] ret; return _preboot(oldest, newest); }); }它先调用pg_shard_manager.set_preboot()置位状态该调用最终转发到OSDState::set_preboot()见 pg_shard_manager.h#L120再从 Monitor 查询当前 osdmap 版本区间进入_preboot()。_preboot()osd.cc#L650-L682是一系列准入检查只有全部通过才会真正发送 boot 消息osdmap 尚未取得首个地图get_epoch() 0时等待初始 osdmap若 osdmap 标记本 OSD 已被销毁is_destroyed抛出异常终止若设置了NOUP标志则等待其清除要求SORTBITWISE标志已设置要求集群require_osd_release不低于 octopus此处可看出 Crimson 的基线版本约束当地图 epoch 接近最新时按osd_map_message_max配置决定是否立即_send_boot()否则通过osdmap_subscribe补齐缺失的地图。booting等待被 quorum 认可在正式被标记为up之前OSD 必须停留在booting状态。_send_boot()osd.cc#L684-L724完成两个动作调用pg_shard_manager.set_booting()把状态从preboot推进到booting组装并发送MOSDBoot消息携带 superblock、当前 osdmap epoch、boot_epoch、心跳front/back地址、集群地址以及CEPH_FEATURES_ALL特性位。值得注意的是该消息的 metadata 中显式写入了osd_type crimsonosd.cc#L715-L717。从注释可知这与OSDMonitor::preprocess_boot的校验逻辑相呼应——Monitor 只有在 osdmap 设置了允许 crimson 的allow_crimson标志时才会受理注册这是集群侧对 Crimson OSD 的准入控制。此外还附带从对象存储读取的osd_objectstore类型如seastore。active正式对外服务当 OSD 收到一份把自己标记为up的 osdmap 时迁移到active状态此后才有资格处理客户端 I/O、参与 PG 的 peering 与 recovery。激活判断集中在committed_osd_maps()osd.cc#L1256-L1354。每消费一份新地图OSD 都会检查三个条件if (bind_epoch up_from osdmap-get_addrs(whoami) public_msgr-get_myaddrs() pg_shard_manager.is_booting()) { INFO(osd.{}: activating..., whoami); co_await pg_shard_manager.set_active(); beacon_timer.arm_periodic( std::chrono::seconds(local_conf()-osd_beacon_report_interval)); tick_timer.arm(std::chrono::seconds(TICK_INTERVAL)); }即本 OSD 在地图中处于up、绑定 epoch 早于up_from、公开地址与地图记录一致、且当前正处于booting——四者齐备才调用set_active()广播激活同时启动周期性beacon间隔由osd_beacon_report_interval配置控制和 tick 定时器。send_beacon()只在is_active()时发送MOSDBeaconosd.cc#L1617-L1630这也是 Monitor 判断 OSD 存活的依据之一。active状态并非永久稳定文档明确指出存在三类退出路径管理员手动停止或 osdmap 中标记stopcommitted_osd_maps()检测到osdmap-is_stop(whoami)后调用shutdown()osd.cc#L1339-L1340shutdown()内部通过abort_source.request_abort()触发整体中止osd.cc#L1609-L1615被标记 down 或地址不匹配should_restart()osd.cc#L1560-L1582检查地图是否仍把本 OSD 标为 up、地图中的 public/cluster 地址是否与本地 messenger 实际绑定地址一致任一不满足就触发restart()——取消各定时器、清零 up epoch然后重新start_boot()osd.cc#L1597-L1607即状态回到preboot这也对应图中active - preboot的迁移进程收到 SIGINT直接终止见下文停机流程。prestop优雅下线的告别仪式无论何种原因收到stop请求OSD 都无条件转入prestop。但在真正告别之前它会向 Monitor 发送MOSDMarkMeDown请求得到确认——确认的方式是收到更新后的 osdmap其中自己已不在up集合或另一条MOSDMarkMeDown消息。源码中这一流程由OSD::prepare_to_stop()承载osd.cc#L1780-L1803if (osdmap osdmap-is_up(whoami)) { pg_shard_manager.set_prestop(); const auto timeout ... local_conf().get_valdouble(osd_mon_shutdown_timeout); try { co_await seastar::with_timeout( ... , monc-send_message( crimson::make_messageMOSDMarkMeDown( monc-get_fsid(), whoami, osdmap-get_addrs(whoami), osdmap-get_epoch(), true)).then([this] { return stop_acked.get_future(); })); } catch (seastar::timed_out_error) {} }要点包括只有当前地图仍把自己标为up时才需要走确认流程否则无需等待set_prestop()之后OSD 停止接收新业务发送MOSDMarkMeDown并等待stop_ackedpromise 完成等待时长受配置osd_mon_shutdown_timeout约束超时则放弃等待继续关闭两种确认分别由两个代码路径兑现handle_mark_me_down()在收到 Monitor 回传的MOSDMarkMeDown时调用got_stop_ack()osd.cc#L1473-L1482committed_osd_maps()在处理到一份已不再把本 OSD 标为 up 的地图时同样调用got_stop_ack()osd.cc#L1323-L1326。got_stop_ack()定义于 osd.h#L259-L263。停机链路从信号到状态机的完整闭环prestop之上还有STOPPING状态。OSDState::set_stopping()会把本地状态置为STOPPING同时向所有等待when_active()的协程抛出system_shutdown_exceptionstate.h#L50-L54让那些等待激活的异步任务以异常方式尽快终止避免悬挂。进程级停机入口在 src/crimson/osd/main.ccosd.start().get(); INFO(crimson startup completed); should_stop.wait().get(); // 等待 SIGINT / SIGTERM INFO(crimson shutting down); osd.stop().get(); // 触发 OSD::stop()should_stop是 Seastar 应用库的stop_signalsrc/crimson/osd/stop_signal.h注册了 SIGINT 与 SIGTERM 的处理器收到信号后置位 abort、广播条件变量wait()随即返回进而调用OSD::stop()。OSD::stop()osd.cc#L855-L885内部先调用prepare_to_stop()即上面所述prestop确认流程再依次停止 public/cluster messenger、admin socket、heartbeat、对象存储、mon/mgr 客户端及各 sharded service。这正是状态图中active - end (kill(SIGINT))的代码级还原。值得注意的是SIGHUP 在 Crimson 中被显式忽略main.cc#L190-L192即不随信号重读配置这与经典 OSD 的行为不同也说明 Crimson 当前不依赖 SIGHUP 做配置热更新。状态机的并发安全设计由于 OSD 状态迁移set_preboot、set_booting、set_prestop都带有ceph_assert(seastar::this_shard_id() PRIMARY_CORE)断言state.h所有状态写入被严格限制在 core 0避免多核并发写状态造成竞态而is_active()、is_stopping()则允许任意 shard 只读访问用于本地快速判断是否继续派发业务。此外MOSDMap的消费在 osd.cc#L1159-L1173 通过handle_osd_map_lock唯一锁串行化——因为committed_osd_maps()中的状态判定is_booting()、is_preboot()、is_prestop()依赖于地图按序消费同一时刻只允许一个地图处理流程推进状态机。这种单一写入者 多读副本 事件串行化的设计是 Crimson 将经典 OSD 生命周期管理适配到 Seastar 多 shard 模型下的核心思路也是理解 doc/dev/crimson/osd.rst 状态图在真实运行时的必要背景。小结Crimson OSD 的生命周期可以用一条主线概括启动后进入preboot通过_preboot()一系列集群准入检查后发送MOSDBoot转入booting收到把自己标记为 up 的 osdmap 后激活为active并开启 beacon/tick 周期任务此后可能因停止请求进入prestop发送MOSDMarkMeDown等待确认直至STOPPING或因健康问题回到waiting_for_healthy、因被标记 down 而回到preboot。对照 src/crimson/osd/state.h 与 src/crimson/osd/osd.cc 阅读本文可以清晰地看到每一个状态转换背后对应的消息与函数调用为排查 Crimson OSD 启动失败、无法激活或优雅停机超时等问题提供直接依据。【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/ceph创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

读懂人工智能白皮书最佳实践源码逻辑

读懂人工智能白皮书最佳实践源码逻辑

读懂人工智能白皮书最佳实践源码逻辑 别再对着《人工智能白皮书》发呆,以为背下术语就能上手。很多开发者读完官方文档,语法会了,模型能跑,但真到业务场景里,连数据管道怎么接、安全合规怎么落地都一脸懵。这就是典型的“学会语法却不知怎么搭项目”。今…

2026/9/22 11:47:17 阅读更多 →
闲鱼怎么退款背后的并发陷阱:搞定这3个高频面试题

闲鱼怎么退款背后的并发陷阱:搞定这3个高频面试题

闲鱼怎么退款背后的并发陷阱:搞定这3个高频面试题 看了一堆教程还是不会写项目?别怪自己笨,是没人告诉你,那些看似简单的业务逻辑,在生产环境里全是坑。…

2026/9/22 11:47:17 阅读更多 →
黑键练习曲性能优化保姆级教程:解决搭项目卡顿难题

黑键练习曲性能优化保姆级教程:解决搭项目卡顿难题

黑键练习曲性能优化保姆级教程:解决搭项目卡顿难题 学会语法却不知怎么搭项目,代码一跑就卡死?这是很多开发者在进阶阶段的噩梦。今天这篇黑键练习曲保姆级教程,专治各种性能顽疾。 性能瓶颈定位…

2026/9/22 11:47:17 阅读更多 →

最新新闻

共射放大电路频率特性:仿真与实测偏差及米勒效应解析

共射放大电路频率特性:仿真与实测偏差及米勒效应解析

简介:北邮模电实验五《共射放大电路的频率特性与深负反馈的影响》docx实验报告,面向模拟电子线路课程学习者,用于掌握频率特性测试、波特图仿真与负反馈影响分析,也适合作为实验报告撰写模板。资源仅1个Word文档,约4.6…

2026/9/23 16:24:21 阅读更多 →
影视剧本创作:深度思考模型在IP改编场景的提示词工程指南

影视剧本创作:深度思考模型在IP改编场景的提示词工程指南

简介:这份PDF文档聚焦影视剧本创作领域,面向编剧、内容创作者及对AI辅助创作感兴趣的从业者,系统讲解如何借助深度思考模型完成IP改编场景下的提示词工程。内容从深度思考模型的基础概念与工作原理切入,延伸至IP改编场景分类、数据…

2026/9/23 16:24:20 阅读更多 →
3招解决外国h小游戏卡顿,手写实现帧率翻倍

3招解决外国h小游戏卡顿,手写实现帧率翻倍

3招解决外国h小游戏卡顿,手写实现帧率翻倍 官方文档里那些关于渲染管线的长篇大论,看两行就让人头大,根本抓不住性能瓶颈在哪。…

2026/9/23 16:24:20 阅读更多 →
网络编程培训选错坑:3个框架完整示例对比

网络编程培训选错坑:3个框架完整示例对比

网络编程培训选错坑:3个框架完整示例对比 复制来的代码跑不通,90%的人卡在环境依赖和异步模型理解上。别急着怪自己基础差,多半是教程只给了 完整示例 ,却没讲清楚底层I/O模型差异。 定位与痛点:为什么你的TCP总是超时…

2026/9/23 16:24:20 阅读更多 →
3个维度拆解赛尔号网页游戏,避开90%高频面试题坑

3个维度拆解赛尔号网页游戏,避开90%高频面试题坑

3个维度拆解赛尔号网页游戏,避开90%高频面试题坑 看了一堆教程还是不会写项目?别怪你笨,是你没搞懂底层逻辑。很多人盯着那些花哨的特效看,却忽略了赛尔号这类老网页游戏在性能优化上的真实痛点。这不仅仅是怀旧,更是理解早期Web架构的绝佳样本。…

2026/9/23 16:24:19 阅读更多 →
确定性网络白皮书拆解:FlexE、TSN、DetNet 技术选型与落地避坑指南

确定性网络白皮书拆解:FlexE、TSN、DetNet 技术选型与落地避坑指南

简介:《未来网络白皮书:确定性网络技术体系》由网络通信与安全紫金山实验室联合华为、北京邮电大学等单位编写,面向网络通信研究者、工业互联网从业者及高校师生,系统解答传统“尽力而为”互联网难以满足智能制造、远程医疗、自动…

2026/9/23 16:23:19 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →