蓝鲸 CMDB 资源变更事件存储表详解:cc_WatchChain 事件链与 cc_WatchToken 监控令牌
后端企业应用运维【免费下载链接】bk-cmdb蓝鲸智云配置平台(BlueKing CMDB)项目地址https://gitcode.com/gh_mirrors/bk/bk-cmdb点击查看免费下载本文深入剖析蓝鲸智云配置平台bk-cmdb中资源变更事件Watch的底层存储设计聚焦cc_{资源类型}WatchChain事件链表族与cc_WatchToken监控令牌表的表结构、字段语义并结合 cacheservice 的源码实现说明事件是如何被写入、游标如何演进、令牌如何实现断点续传。读完本文你将能理解 CMDB 事件订阅机制的数据落地方式并能对照仓库源码定位到对应的读写链路。一、事件机制与两张核心表的关系蓝鲸 CMDB 基于 MongoDB 的 change stream变更流能力实现资源变更事件订阅当主机、业务、模型、实例关联等数据发生变化时系统会把变更事件按资源类型分门别类地持久化到 MongoDB 中供外部系统如蓝鲸其他 SaaS、数据同步平台通过watch接口拉取。整个事件存储体系由两类表构成表族作用cc_{资源类型}WatchChain存放某类资源的变更事件事件链节点所有 WatchChain 表结构统一cc_WatchToken存放每个数据集合的监控令牌断点续传游标用于跟踪指定数据集合的变化情况从源码看链表的命名规则在 cacheservice/event/key.go 中定义ChainCollection()返回k.collection WatchChain即在原数据表名如cc_HostBase后拼接WatchChain得到事件链表名如cc_HostBaseWatchChain。而cc_WatchToken的表名常量定义于 common/tablenames.go。二、cc_{资源类型}WatchChain事件链表族2.1 覆盖的资源类型与表清单变更事件相关的表具有统一结构当前仓库归类包含如下 21 张事件链表表名称作用cc_ApplicationBaseWatchChain存放业务变更事件信息cc_BizSetBaseWatchChain存放业务集变更事件cc_bizSetRelationMixedWatchChain存放业务集关系变更事件cc_ClusterBaseWatchChain容器数据纳管——存放集群变更事件cc_HostBaseWatchChain存放主机变更事件信息cc_HostIdentityMixedWatchChain存放主机身份变更事件信息cc_InstAsstWatchChain存放实例关联变更事件信息cc_MainlineInstanceWatchChain存放主线实例变更事件信息cc_ModuleBaseWatchChain存放模块变更事件信息cc_ModuleHostConfigWatchChain存放模块主机关联关系变更事件信息cc_NamespaceBaseWatchChain容器数据纳管——存放命名空间变更事件信息cc_NodeBaseWatchChain容器数据纳管——存放节点变更事件信息cc_ObjectBaseWatchChain存放模型实例变更事件cc_PlatBaseWatchChain存放管控区域变更事件信息cc_ProcessInstanceRelationWatchChain存放进程实例关联关系变更事件信息cc_ProcessWatchChain存放进程变更事件信息cc_ProjectBaseWatchChain存放项目变更事件信息cc_SetBaseWatchChain存放集群Set变更事件信息cc_SetTemplateWatchChain存放集群模板变更事件信息cc_WorkloadBaseWatchChain容器数据纳管——工作负载变更事件信息cc_PodBaseWatchChain容器数据纳管——Pod 变更事件信息其中MixedWatchChain类表如cc_HostIdentityMixedWatchChain、cc_bizSetRelationMixedWatchChain对应的是混合事件类型源码中HostIdentifier游标类型被注释为 a mixed event type, which contains host, host relation, process events etc. and finally converted to host identifier event见 cursor.goBizSetRelation同理由业务集与业务事件转换而来cursor.go。它们由 cacheservice 的 mix-event 处理器 消费多条基础事件链后合并生成。2.2 统一的表结构所有 WatchChain 表采用统一字段结构字段类型描述_idObjectId数据唯一 IDidNumberLong自增 IDcluster_timeISODate事件时间oidString事件 ID事件所属文档的_idtypeString操作类型tokenString数据库恢复令牌MongoDB resume tokencursorStringCMDB 的事件游标inst_idNumberLong实例 IDbk_supplier_accountString开发商 ID这一结构在 Go 侧由 common/watch/types.go 的ChainNode结构体直接对应其 bson 标签与上表逐字段吻合id自增 IDsearchFollowingEventChainNodesByID正是基于它做id startID的顺序查询client.go保证事件按序消费cluster_time事件发生时间查询最早/最新事件节点时都会以cluster_time now - TTL作为过滤条件client.gooid事件所属文档的_id值用于事件详情回查type操作类型仅支持create/update/deletecommon/watch/types.gotokenMongoDB 的 resume token_data十六进制串空字符串表示链头节点cursor由 CMDB 自行生成、与 MongoDB resume token 一一对应的游标作为对外暴露的事件定位标识inst_id实例 ID为后续事件聚合预留bk_supplier_account事件所属开发商账号实例类事件还会借助它定位分表client.go。三、cc_WatchToken监控令牌表3.1 作用cc_WatchToken用于存储数据库表的监控令牌信息监控令牌用于跟踪指定数据集合的变化情况是整个事件订阅实现“断点续传 / 崩溃恢复”的关键。3.2 表结构字段类型描述_idString数据库表名即被监控集合的名字idNumberLong自增 idtokenString令牌cursorString事件游标start_at_timeISODate开始时间该表在源码中的数据结构是 common/watch/types.go 的LastChainNodeDatatype LastChainNodeData struct { Coll string json:_id bson:_id // 数据库表名 ID uint64 json:id bson:id // 自增 id Token string json:token bson:token // 令牌 Cursor string json:cursor bson:cursor // 事件游标 StartAtTime types.TimeStamp json:start_at_time,omitempty bson:start_at_time,omitempty // 开始时间 }注意该表以被监控集合名如cc_HostBase作为文档_id一行对应一个被监控集合而不是像 WatchChain 表那样每行一条事件。四、事件链的写入与令牌更新流程4.1 写入链路从源码结构看事件写入由 cacheservice/event/flow 中的事件流flow负责cacheservice 基于 MongoDB change stream 监听各资源数据表将insert/replace/update/delete等操作转换为事件后写入对应的WatchChain表同时把事件详情写入 Redis 缓存getEventDetailFromRedis的读取逻辑见 client.go事件链节点仅保存游标与定位信息详情按DetailKey(cursor)存放在 Redis。4.2 令牌的读取与回写令牌处理器flowTokenHandler是令牌表的主要读写方flow/handler.go回写事件成功入库后setLastWatchToken以{_id: key.Collection()}为过滤条件Updatecc_WatchToken把最新 token 写入对应集合的行读取GetStartWatchToken优先从cc_WatchToken取 token若该表无记录如首次启动则回退到对应WatchChain表按id倒序取最后一条节点的 token重置当 watch 遇到致命错误时resetWatchToken将 token 清空并把start_at_time设置为给定时间下次 watch 从该时间点重新开始避免误用错误的令牌导致事件丢失。4.3 游标回退兜底在读取端event/watch/client.go当用户传入的 cursor 在WatchChain表中找不到对应节点时会回退到cc_WatchToken按_id 集合名查找id再从该id继续向后拉取事件。这说明cc_WatchToken中的id承担了“链尾锚点”的作用为链节点因 TTL 过期被清理后的场景提供兜底。五、游标Cursor与令牌Token的设计细节5.1 CMDB 自定义游标的编码WatchChain 表中的cursor并非 MongoDB 原始 resume token而是 CMDB 自定义编码后的字符串。编码逻辑见 common/watch/cursor.go游标由 7 个字段用\r分隔后整体做 base64 编码版本号 \r 资源类型ID \r oid \r 操作类型 \r 集群时间秒 \r 集群时间纳秒 \r 唯一键(可选)其中资源类型 ID 与CursorType一一映射cursor.go例如host→2、biz→4、object_instance→8、kube_workload→20 等。UniqKey用于区分同一资源类型下不同实例的事件如通用实例事件以实例 ID 作为唯一键、工作负载事件以类型:ID组合作为唯一键cursor.go保证游标在重试场景下可重入且唯一。解码时cursor.go程序会校验 base64 格式、版本号、资源类型、oid 格式普通事件须为十六进制 ObjectIdinst_asst事件须为整数串以及集群时间字段任一步失败即拒绝该游标。5.2 特殊游标NoEventCursor当某段时间内没有任何事件时系统会返回NoEventCursorMQ0xDTVlYTZkM2YzOTRjMWY1ZDk4NmU5YmQ4Ng1ub0V2ZW50DTENMQ见 cursor.go。消费者收到该游标后下一次 watch 应从链头开始拉取服务端在searchFollowingEventChainNodes中对此做了专门分支处理client.go。5.3 事件类型与操作类型的映射MongoDB change stream 的操作类型与 CMDB 事件类型之间通过ConvertOperateType转换common/watch/types.goMongoDB 操作类型CMDB 事件类型insertcreatereplace/updateupdatedeletedelete其他含drop/rename/invalidate等unknown六、TTL 与数据生命周期WatchChain 事件并非永久保留。从 cacheservice/event/key.go 可以看到各资源 Key 的ttlSeconds统一为6 * 60 * 60即6 小时。该 TTL 在多个环节生效查询最早/最新事件时只扫描cluster_time在最近 6 小时内的节点client.goWatchWithStartFrom校验bk_start_from与当前时间差必须在 TTL 范围内否则返回参数错误watch.go查询 cursor 对应节点时同样附加 TTL 过滤client.go。因此消费方应保证拉取频率高于 6 小时且用游标/令牌持续续传若事件链节点已过期系统会借助cc_WatchToken中的锚点 id 兜底续传。七、watch 接口的三种拉取模式cc_{资源类型}WatchChain与cc_WatchToken最终服务于对外 watch 接口。在 cacheservice/service/cache.go 中根据请求参数分流到三种模式请求参数处理函数语义携带bk_cursorWatchWithCursor从指定游标之后继续拉取事件断点续传携带bk_start_fromUnix 秒WatchWithStartFrom从指定时间点开始拉取两者皆无WatchFromNow从现在开始监听返回当前最新事件当无事件命中时返回Watchedfalse与NoEventCursor或原游标消费方可以此游标进行下一轮轮询。请求参数定义与校验见 common/watch/watch.gobk_event_types、bk_fields、bk_resource、bk_sub_resource、bk_filter等参数共同决定了从事件链中过滤出哪些节点及其详情字段。八、小结cc_{资源类型}WatchChain统一结构的事件链节点表21 类资源各一张含混合事件表字段id自增有序、cluster_time事件时间、oid文档 ID、typecreate/update/delete、tokenMongoDB resume token、cursorCMDB 编码游标、inst_id、bk_supplier_accountcc_WatchToken以集合名为_id的令牌表保存每个集合最新 token、cursor、id 与起始时间是断点续传与崩溃恢复的锚点两者配合实现“写入事件链 → 回写令牌 → 按游标续传 → 过期兜底”的完整事件订阅闭环事件详情存于 Redis链节点默认仅保留 6 小时。如需进一步深入可继续阅读 docs/db/instance.md、docs/db/watch.md 及事件流的实现 cacheservice/event/flow/event.go。赞分享后端企业应用运维【免费下载链接】bk-cmdb蓝鲸智云配置平台(BlueKing CMDB)项目地址https://gitcode.com/gh_mirrors/bk/bk-cmdb点击查看免费下载相关推荐蓝鲸 CMDB 资源变更事件监听resource_watch接口全解析事件链、游标机制与实战用法蓝鲸 CMDB 资源变更事件监听resource_watch接口全解析事件链、游标机制与实战用法 导读 本文围绕蓝鲸智云配置平台bk cmdb对外提供后端企业应用运维蓝鲸 CMDB 资源变更事件 watch 接口详解游标回溯、短长链轮询与实战调用指南蓝鲸 CMDB 资源变更事件 watch 接口详解游标回溯、短长链轮询与实战调用指南 蓝鲸智云配置平台bk cmdb提供基于 watch 模式的资源变更事后端企业应用运维蓝鲸 CMDB 资源变更事件监听Resource Watch接口全解析基于游标的事件回溯与实时推送实战指南蓝鲸 CMDB 资源变更事件监听Resource Watch接口全解析基于游标的事件回溯与实时推送实战指南 本篇技术指南以蓝鲸智云配置平台BlueKin后端企业应用运维上一篇Superdesign用AI重新定义你的设计工作流程下一篇InputTip开发原理揭秘AutoHotkey实现输入法状态管理的核心技术创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

基于MP2642GR-Z与dsPIC33的2S电池组均衡方案设计

基于MP2642GR-Z与dsPIC33的2S电池组均衡方案设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 2:40:26 阅读更多 →
两串电池主动均衡设计与实现:MP2642GR-Z+STM32L4A6RG方案详解

两串电池主动均衡设计与实现:MP2642GR-Z+STM32L4A6RG方案详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 2:40:26 阅读更多 →
mediasoup音量监控实战:AudioLevelObserver原理、调优与降级方案

mediasoup音量监控实战:AudioLevelObserver原理、调优与降级方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 2:40:26 阅读更多 →

最新新闻

KVM内存虚拟化实战:EPT、气球驱动、KSM、大页与NUMA调优指南

KVM内存虚拟化实战:EPT、气球驱动、KSM、大页与NUMA调优指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 3:16:37 阅读更多 →
具身智能中的协同机理研究(113):TVA-World毫秒级闭环控制核心技术解析

具身智能中的协同机理研究(113):TVA-World毫秒级闭环控制核心技术解析

前沿技术探索:TVA智能体(简称TVA) TVA智能体(亦称“AI智能体视觉”)是依托Transformer架构与“因式智能体”理论构建的新型工业视觉系统,也是当前最具代表性的具身视觉技术之一。它有机融合深度强化学习&a…

2026/10/15 3:16:37 阅读更多 →
2026年,薪酬设计软件已成为企业人才竞争的秘密武器

2026年,薪酬设计软件已成为企业人才竞争的秘密武器

2026年,薪酬设计软件已成为企业人才竞争的秘密武器在新能源汽车、人工智能、芯片半导体等赛道的抢人大战中,越来越多的企业发现,仅靠“高薪”已难以锁定顶尖人才。真正拉开差距的,是一套能科学定价、动态迭代、精准激励的薪酬设计…

2026/10/15 3:16:37 阅读更多 →
2026年薪酬设计避坑指南:怎样筛选靠谱生产厂家?

2026年薪酬设计避坑指南:怎样筛选靠谱生产厂家?

如果你现在就职于一家正在经历业务转型或者加速扩张的企业,手里握着老板“必须把核心人才给我留住”的死命令,那么你一定正在头疼一件事:明年的薪酬体系到底要怎么设计?薪酬设计不是拍脑袋画饼,也不是关起门来缝缝补补…

2026/10/15 3:16:37 阅读更多 →
C#-WPF-调试与输出Console Debug Trace

C#-WPF-调试与输出Console Debug Trace

Console输出Console.WriteLine(" 卡尔曼零维模型滤波 \n");Debug输出Debug.Write()不换行,连续输出HelloWorldDebug.WriteLine()自动换行,每次输出后换行HelloWorldDebug.Write("调试输出---"(ha)"\r\n");Trace输出Trace.…

2026/10/15 3:16:37 阅读更多 →
RAG2SQL实战:用Vanna构建自然语言数据库查询助手

RAG2SQL实战:用Vanna构建自然语言数据库查询助手

说实话,我写这篇文章之前,刚被业务同事堵在工位上要数据。需求很简单:"帮我看下华东区上个月退货率超过10%的品类有哪些。"难倒是不难,但类似的临时查询我一天能接到七八个,每一个都要打开终端、连数据库、回…

2026/10/15 3:15:37 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →