【SPDK 用户态存储】JSON-RPC 与生命周期:配置面、热插拔与重启边界
内容提要
SPDK配置面通过JSON-RPC管理,区分STARTUP和RUNTIME状态,热插拔变更仅存于内存,重启后丢失。需用save_config导出配置并纳入版本控制,编排系统应声明式渲染配置,避免依赖shell历史。生产变更需审计,升级时重放黄金配置验证兼容性。
延伸解读
配置真相源:内存态与持久态分离
文章强调,SPDK 的热插拔变更(如 bdev、nvmf 对象)仅存在于进程内存,进程退出即丢失。因此,运维必须区分“运行态”和“持久态”:运行态以当前 RPC 视图为准,持久态以 save_config 导出的 JSON 或编排库存为准。若只依赖 shell 历史或临时 RPC,重启后配置将漂移。建议将导出文件纳入版本控制,并作为声明式配置的真相源。
STARTUP 与 RUNTIME:状态机决定 RPC 可用性
SPDK 应用状态从 STARTUP 到 RUNTIME 切换,STARTUP 仅允许初始化参数,RUNTIME 才开放完整 RPC。若在 RUNTIME 阶段尝试修改初始化参数,会得到 -1 Invalid state 错误。排障时应使用 rpc_get_methods 的 current 参数确认当前可调用方法,而非依赖记忆中的完整 RPC 表。自动化脚本需显式区分冷启动序列与热 RPC,避免静默失败。
重启剧本:环境层与配置层分离
文章建议将生命周期管理写成可执行剧本,最小闭环包括:环境层(大页、绑盘)不属于 save_config;冷启动参数(-m、-s 等)进 systemd 模板;STARTUP RPC 仅放初始化选项;RUNTIME RPC 构建对象图;运行中热变更必须回流到库存。常见事故模式包括只热加盘不改库存、把 STARTUP 参数塞进 RUNTIME 脚本、多实例共用默认 socket 路径等,需通过变更门禁和审计日志缓解。
升级回归:重放黄金配置验证兼容性
升级 SPDK 版本时,应重放一份最小配置(如一个 nvme bdev、一个 nvmf 出口)并对比对象图,以捕捉 method 更名、默认参数收紧或 STARTUP/RUNTIME 可调集合变化。将重放挂入 CI 或发布 checklist,是配置面成熟度的硬指标。此外,--wait-for-rpc 模式下健康检查不能只看进程存活,应通过 rpc_get_methods 确认 RUNTIME 方法可用,否则可能将半初始化实例标绿。
Q&A
SPDK中配置面和数据面有什么区别?
SPDK的数据面负责高性能I/O处理,运行在reactor线程上;配置面通过JSON-RPC管理,用于创建bdev、配置nvmf subsystem等。配置面走管理线程,不替代数据面的性能要求。
SPDK中STARTUP和RUNTIME状态有什么区别?
STARTUP状态是初始化阶段,只允许调用设置初始化参数的一小部分RPC;调用framework_start_init后进入RUNTIME状态,此时可用RPC集合变大,但初始化参数不可再修改。
SPDK中热插拔的配置变更在重启后会丢失吗?
会丢失。热插拔变更仅存在于进程内存中,进程退出后默认丢失。要持久化配置,需要使用save_config导出配置,并在下次启动时通过-c加载。
如何将SPDK的当前配置保存下来以便重启后恢复?
使用scripts/rpc.py save_config > config.json导出当前配置,然后在启动新进程时使用-c config.json加载。导出的config.json是一组排序的RPC调用,而非数据库快照。
SPDK中rpc_get_methods命令有什么作用?
rpc_get_methods可以列出当前状态下可调用的RPC方法,带current: true参数时只显示当前状态可用的方法。排障时以它为准,避免依赖记忆中的完整RPC表。
SPDK中配置变更后如何确保重启后配置不丢失?
配置变更后应立即执行save_config导出配置,并将导出的JSON文件纳入版本控制或配置库存。不要依赖shell历史,应使用声明式渲染或版本控制管理配置。
SPDK中常见的配置事故有哪些?如何避免?
常见事故包括:只热加盘不改库存导致重启丢失;将STARTUP参数塞进RUNTIME脚本导致-1 Invalid state;多实例共用默认socket路径导致连错进程;依赖shell历史当配置。避免方法是:变更后立即导出配置、脚本分阶段、每实例独立-r、使用Git等配置中心。
SPDK中save_config导出的配置能完全复现主机状态吗?
不能。save_config只导出框架认为可序列化的RPC视图,不包括主机环境配置如hugepage、driver_override等。因此配置真相应是主机环境剧本与SPDK JSON的结合,而非单文件。