尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Vector 组件组合(Composing Components)架构演进:从 Humio Sink 门面到源端内置 Codec

Vector 组件组合(Composing Components)架构演进:从 Humio Sink 门面到源端内置 Codec Vector 组件组合Composing Components架构演进从 Humio Sink 门面到源端内置 Codec【免费下载链接】vectorA high-performance observability data pipeline.项目地址: https://gitcode.com/GitHub_Trending/vect/vector导读本文基于 Vector 仓库中的 RFC 3791rfcs/2020-10-06-3791-composing-components-pt-1.md解析 Vector 如何在高模块化与开箱即用之间取得平衡通过把一组底层组件source transform以预置默认值的方式打包成用户可直接配置的组合组件。文章将完整还原 RFC 提出的四级组合方案与选型决策并以 Humio Sink、源端 Codec 等仓库内真实实现作为证据说明这些设计如何在当前代码库中落地。读完本文你将理解 Vector 配置系统的扩展机制、TransformConfig::expand等 trait 的边界与局限以及内部事件internal events计数归属对组合组件可观测性的影响。RFC 背景为什么需要组合组件Vector 被设计成高度模块化的数据管道而当前把模块组装起来的工具就是 TOML 配置文件。这种设计赋予了用户极大的灵活性但也带来了两个实际痛点配置冗长一个完整用例往往需要串联 source、transform、sink 多个组件每个都要单独编写配置上手门槛高相比开箱即用的专用解决方案用户需要自己理解并组装这些底层模块。RFC 提出的思路是让 Vector 能够轻松创建预置配置块pre-built chunks of config用户像配置普通组件一样直接使用它们。这些配置块本质上是一组底层组件加上针对特定用例调整过的默认值例如NGINX 日志源 现有filesource regex/grok解析 transform 面向 NGINX 的默认解析规则。需要说明的是RFC 将范围限定为先支持组合 source的快速开发以 NGINX 日志为代表而组合任意组件的完整方案留待后续 RFC即仓库中的后续文档rfcs/2021-07-19-8216-multiple-pipelines.md等所延续的管线组合话题。动机用最小的开发投入换取最大的用户价值RFC 明确给出的动机是快速装配针对特定用例的 Vector 组件让 Vector 在不针对每个用例投入大量开发的前提下提升易用性把开发时间集中在可复用组件上而不是让用户每次都从零组装通过提升易用性扩大用户覆盖同时把组装这类重复劳动从用户侧转移到 Vector 内部。这一动机决定了整个 RFC 的价值判断标准以最低的复杂度增量解锁最多的用户可见价值。内部提案组合功能的四级实现方案RFC 的核心章节把组件组合的可能实现方式划分为四个递进层级层级实现方式复杂度当前状态RFC 写作时1手动实现新组件作为单个现有组件的配置门面config facade低已实现如 Humio sink 包装 Splunk HEC sink2手动实现新组件作为一个 source 一个 codec transform的配置门面中低未实现但已有source 上挂 codec的计划3手动实现新组件作为展开为任意组件管线的配置门面高仅具备有限能力TransformConfig::expand4自动从数据描述中派生新组件TOML 定义组合编译期内置最高不推荐近期实施层级 1单组件配置门面最朴素的做法新组件不实现任何新逻辑只是在配置层面套壳并调整默认值。RFC 以Humio sink为例——它是现有Splunk HEC sink的包装。这一设计在当前仓库中有完整实现见 src/sinks/humio/logs.rsHumioLogsConfig通过build_hec_config()方法把自身配置翻译成HecLogsSinkConfig再委托给 Splunk HEC 的既有实现完成真正构建fn build_hec_config(self) - HecLogsSinkConfig { HecLogsSinkConfig { default_token: self.token.clone(), endpoint: self.endpoint.clone(), host_key: Some(self.host_key.clone()), indexed_fields: self.indexed_fields.clone(), index: self.index.clone(), sourcetype: self.event_type.clone(), source: self.source.clone(), timestamp_nanos_key: self.timestamp_nanos_key.clone(), encoding: self.encoding.clone(), compression: self.compression, batch: self.batch, request: self.request, tls: self.tls.clone(), acknowledgements: HecClientAcknowledgementsConfig { indexer_acknowledgements_enabled: false, ..Default::default() }, timestamp_key: Some(config_timestamp_key_target_path()), endpoint_target: EndpointTarget::Event, auto_extract_timestamp: None, confinement: self.confinement.clone(), } }从这段代码可以清楚地看到门面facade模式的三个特征字段映射Humio 的token/endpoint/event_type等概念被映射到 HEC 的default_token/endpoint/sourcetype等底层字段默认值调整Humio 默认端点为https://cloud.humio.com见同文件中的HOST常量与default_endpoint()默认关闭 HEC 的 indexer acknowledgementsindexer_acknowledgements_enabled: false协议复用endpoint_target: EndpointTarget::Event决定走 HEC 的/services/collector/event事件端点Humio 直接复用 Splunk HEC 协议。层级 2source codec 门面RFC 的推荐起点RFC 认为下一步最简单的是层级 2在层级 1 的基础上把范围从单个组件扩展到一个 source 加一个内嵌 codec。其技术前提是给 source 引入 codec 概念用户直接在 source 配置里声明如何解析进来的数据。一旦该特性就绪实现NGINX 日志源这类组合组件就变得很直接——把filesource 与一个解析 codecregex 或 grok绑定并提供 NGINX 专用默认值。RFC 的核心结论是建议优先聚焦层级 2同时收集需要层级 3 的用例数据。假设这类组合组件中数量最多的是类似 NGINX source 的形态——组合现有 sourcefile 现有 transformregex/grok 解析器并为每个提供面向 NGINX 的默认值。聚焦这些简单用例能显著降低在收获价值前需要引入的复杂度。层级 3展开为任意管线层级 3 是新组件配置展开为一整条组件管线。RFC 指出当时已存在有限能力transform 可以通过TransformConfig::expand展开为多个 transform。关于这一能力当前仓库 src/config/transform.rs 中TransformConfigtrait 的nestable()方法注释给出了重要佐证——展开机制引入了一个必须防范的问题/// For some transforms, they can expand themselves into a subtopology of nested transforms. /// However, in order to prevent an infinite recursion of nested transforms, we may want to only /// allow one layer of expansion.也就是说展开expansion允许一个 transform 变成一组嵌套 transform 的子拓扑但为了防止无限递归嵌套必须限制只允许一层展开并且某些 transform 在特定父类型之下无法正确工作nestable返回false。RFC 同时点出了层级 3 的深层障碍与现有配置 trait 的契合度差TransformConfig等 trait 是按单个组件设计的展开语义难以平滑融入API 容易令人困惑一个组件展开成多个其输入输出、schema 推导、错误归属都变得复杂要做得正确需要更深层地改造配置 trait以支持分阶段构建staged building这种模式。层级 4TOML 定义 编译期内置RFC 明确不推荐层级 4 允许用 TOML 而不是 Rust 代码定义组合类似此前被提出过的snippets片段想法但有两个关键差异编译期内置而非运行期加载组合定义被直接编译进 Vector 二进制修改它们必须重新编译 Vector需要集成进构建流程需要足够通用的组合 API 暴露给 TOML面对如此多种多样的潜在管线形态设计一个通用 TOML 组合描述语法非常困难。基于这两点RFC 判断层级 4 近期不值得投入如果未来我们拥有更多数据驱动的配置定义方式这一判断可能改变。这也解释了为什么 Vector 至今仍以 Rust 内建组件为主而不是开放 TOML 自定义组件。理由Rationale为什么从层级 2 切入RFC 对选型的理由总结为一句关键判断这套变更以最小的必要投入解锁最多的用户可见价值并且不会损害未来更深层架构变更的计划。即层级 2 的选择是一个帕累托最优路径先享受组合组件带来的易用性红利同时为未来推向层级 3 保留空间而不是一上来就进行伤筋动骨的配置系统重构。行动计划Plan of Attack及源码对照RFC 给出了分两阶段推进的实施清单这里结合当前仓库代码逐一对照第一阶段为组合 source 铺路[ ] 实现TransformFn源自架构 RFC并让非 task transform 切换到它TransformFn是一个函数式 transform 抽象用于替代需要独立任务task的 transform是轻量管线组合的基础。从当前仓库结构看transform 的构建统一走 src/config/transform.rs 中TransformConfig::build(self, globals: TransformContext) - crate::ResultTransformTransform由 lib/vector-lib/src/ 中的vector_lib::transform::Transform提供函数式 transform 正是由这类轻量抽象支撑。[ ] 给Pipeline增加Vecdyn TransformFn字段Pipeline是事件流经的一组 transform 的容器。给其追加 transform 列表字段是为了让组合 source 内部预置的解析逻辑能以追加到Pipeline的方式生效而不是新建一个独立组件。[ ] 组合 source 以门面方式实现在传给SourceConfig::build的Pipeline前置相关TransformFn这正是层级 2 的核心落地形态组合 source 的build不再只返回一个数据源而是在其输出Pipeline上先挂载预置的解析 transform。从源码结构看拓扑构建逻辑集中在 src/topology/builder.rs事件先经 source 进入Pipeline再流向后续组件因此在 Pipeline 上追加 TransformFn可以在不改动 topology 框架的前提下完成组合。[ ] 将event_processed内部事件移到 topology 包装层而非组件自身动机是避免重复计数或错误打标如果组合组件 1 个 source 1 个内置 transform而两者各自上报事件已处理同一事件就会被计两次。正确做法是让内部事件只由 topology 层面的包装统一上报。当前仓库中事件计数由 src/topology/builder.rs 中的internal_event::EventsReceived/EventsSent等注册句柄如let events_received register!(EventsReceived)统一统计而各组件内部通过internal_events模块见 src/internal_events/上报更细粒度的事件——这印证了 RFC 中计数归属确实是组合组件必须解决的可观测性问题。第二阶段按需推向层级 3[ ] 把TransformConfig::expand升级为一等公民阶段拆分现有 config 的build方法[ ] 让新的展开阶段对所有组件生效不仅限于 transform[ ] 考虑引入更细粒度的内部组件类型设计成可组合进用户可见的 source、transform 与 sink组合组件对配置系统的意义从当前代码看设计走向虽然 RFC 发布于 2020 年但其确立的设计原则在今天仓库的配置体系中依然可辨门面模式是组合的低成本首选。Humio sink 至今仍以配置翻译 委托构建的方式复用 Splunk HEC 实现src/sinks/humio/logs.rs 的ValidatedSink实现通过build_from_validated委托给 HEC证明层级 1 的架构决策经受住了时间检验。源端 codec 已成为现实。RFC 中给 source 附加 codec 解析的设想在当前仓库中由 lib/codecs/ 这一独立 crate 承载lib/codecs/src/下包含大量解码器与序列化器实现source 侧解析能力已经内聚为可复用模块——这正是层级 2 得以成立的基础设施。展开机制始终带着防止无限嵌套的约束。TransformConfig::nestable()src/config/transform.rs用parents: HashSetstatic str显式声明能否在特定父类型下嵌套正是 RFC 对层级 3 复杂性的预判在 trait 设计上的投影。总结RFC 3791 为 Vector 的组件组合能力画出了一条清晰的演进路线现状通过配置门面层级 1复用现有组件Humio sink 是标准范例近期目标借助 source 内嵌 codec层级 2快速产出 NGINX 日志这类source 解析器组合组件为此需要TransformFn、Pipeline扩展和内部事件计数归属三块基础设施远期可能在收集到足够用例后把TransformConfig::expand升级为对所有组件生效的一等公民构建阶段层级 3明确不做编译期 TOML 定义组合层级 4直到出现更通用的数据驱动配置方案。这套先易后难、用需求驱动架构升级的取舍逻辑是理解 Vector 配置系统设计哲学的一把钥匙模块化负责上限组合组件负责下限而 RFC 保证了两者之间的路径足够平滑。对希望在 Vector 上构建领域专用数据管道的开发者而言门面模式与组合 source 的思路同样可以直接迁移到自己的配置实践中。【免费下载链接】vectorA high-performance observability data pipeline.项目地址: https://gitcode.com/GitHub_Trending/vect/vector创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表