2. 数据采集层成本:数据源采集的“隐形账单”

数据采集,听起来很简单对吧?把业务库的数据抽过来,把日志收上来,把埋点事件接进来。很多团队一开始都觉得这层没啥成本,直到月底看到账单才傻眼。

我个人习惯把采集层成本拆成两块看:计算资源和网络带宽。前者是服务器、CPU、内存的消耗,后者是数据在网络上跑过时产生的流量费。这两块,说白了都是“看不见的钱”。

核心观点:采集层的成本往往被低估,但它可能是全链路中“单位数据成本”最高的环节。因为数据在源头还没经过压缩、清洗、聚合,原始体积最大。

2.1 业务数据库采集:CDC 与 Batch 的取舍

业务 DB 的采集,主流就两条路:CDC(Change Data Capture) 和 批量拉取(Batch Pull)。我在项目中遇到过不少团队在这上面栽跟头。

2.1.1 CDC 采集的成本模型

CDC 通过解析 binlog 或 WAL 日志来捕获变更。它的计算资源消耗主要在 Debezium、Canal 或 Flink CDC 这些组件上。

成本项 说明 典型消耗
源库解析开销 读取 binlog 对源库 IO 的影响 5%-15% 的额外 IOPS
采集服务器 CPU 序列化/反序列化、数据格式转换 2-4 核 / 万 TPS
内存 缓存未提交的事务数据 1-2 GB / 万 TPS
网络带宽 binlog 原始数据 + 元数据 约源库写入量的 1.2-1.5 倍

我的经验:CDC 的带宽成本经常被忽略。binlog 里除了数据变更,还有事务 ID、表结构元数据、心跳事件。我曾经见过一个 MySQL 实例,业务写入只有 50MB/s,但 CDC 采集出去的流量高达 80MB/s。多出来的 30MB 全是元数据和心跳。

2.1.2 批量拉取的成本陷阱

批量拉取,比如用 Sqoop、DataX 或者自己写的 JDBC 程序。它的成本模型完全不同。

  • 计算资源:主要在拉取端。每个分片一个线程,线程数 = 并发度。并发太高会把源库打死,太低又拉得慢。
  • 网络带宽:每次全量拉取,数据量 = 表大小 × 拉取次数。如果每天全量拉一次,一个月就是 30 倍的表大小。
  • 源库压力:全表扫描对 InnoDB 的 buffer pool 冲击很大,可能导致业务查询变慢。

我曾经踩过的坑:有个团队用 DataX 每天全量拉取一张 200GB 的表,结果源库的磁盘 IO 被打到 99%,业务接口响应时间从 10ms 飙升到 2s。后来改成 CDC + 增量合并,成本直接降了 70%。

2.2 日志采集:Filebeat 与 Fluentd 的“隐形 CPU”

日志采集,大家用得最多的就是 Filebeat 和 Fluentd。这两兄弟看起来轻量,但用不好照样烧钱。

2.2.1 Filebeat 的资源画像

Filebeat 用 Go 写的,理论上很省资源。但实际部署时,有几个参数特别关键:

  • harvester 数量:每个日志文件一个 harvester。如果一台机器上开了 100 个日志文件,就是 100 个 harvester。每个 harvester 占用一个文件句柄和少量内存。
  • multiline 配置:合并多行日志(比如 Java 异常栈)需要正则匹配。正则写不好,CPU 直接飙到 80%。
  • output 压缩:默认 gzip 压缩等级是 3,改成 1 能省 30% CPU,但带宽会多 10%。

2.2.2 Fluentd 的内存陷阱

Fluentd 基于 Ruby,内存管理是硬伤。我见过一个案例:Fluentd 的 buffer 配置不当,内存从 200MB 涨到 2GB,最后 OOM 被 kill 了。

组件 CPU 消耗 内存消耗 带宽消耗
Filebeat 低 (5-10%) 低 (50-200MB) 中 (取决于日志量)
Fluentd 中 (10-30%) 高 (200MB-1GB) 中 (取决于日志量)
Logstash 高 (30-60%) 高 (500MB-2GB) 中 (取决于日志量)

我的建议:如果只是采集,别用 Logstash。它太重了。Filebeat 采集 + Kafka 中转,是性价比最高的组合。Fluentd 适合需要复杂路由的场景,但一定要限制 buffer 大小。

2.3 埋点采集:客户端到服务端的“流量黑洞”

埋点数据,特别是客户端埋点,是成本黑洞。为什么?因为埋点数据量巨大,而且很多是无效数据。

2.3.1 客户端采集的成本构成

  • 计算资源:客户端 SDK 的 CPU 消耗。埋点太多会导致 App 卡顿,用户流失。
  • 网络带宽:每次上报的 HTTP 请求头 + 请求体。一个埋点事件可能只有 200 字节,但加上 HTTPS 握手、Cookie、User-Agent,实际消耗 2KB 以上。
  • 服务端接收:Nginx 反代 + 后端接收接口。每万 QPS 需要 4-8 核 CPU。

2.3.2 埋点数据的“无效成本”

你想想看,很多埋点事件上报上来,根本没人看。我统计过一个项目:

  • 70% 的埋点事件从未被任何报表或分析任务引用
  • 20% 的事件只被用过一次
  • 只有 10% 的事件被持续使用

这意味着什么?90% 的采集成本,花在了没人用的数据上。

成本优化核心:埋点采集前,先问三个问题:这个事件谁用?怎么用?多久用一次?没人回答的,就别采了。

2.4 网络带宽:最容易超支的“隐形账单”

网络带宽成本,在云上尤其明显。跨 AZ、跨 Region、跨云,每 GB 流量都是钱。

2.4.1 带宽成本的计算模型

以 AWS 为例:

  • 同 AZ 内:免费
  • 跨 AZ:$0.01/GB(双向收费)
  • 跨 Region:$0.02-$0.09/GB
  • 出站到公网:$0.05-$0.09/GB

假设每天采集 10TB 数据,跨 AZ 传输,一个月就是 10TB × 30 × $0.01 = $3000。这还只是带宽费,不算计算资源。

2.4.2 带宽优化的常用手段

手段 节省比例 代价
数据压缩(gzip/snappy) 50%-80% 额外 5-10% CPU
批量发送 30%-50% 增加 1-5 秒延迟
数据过滤(丢弃无效字段) 10%-30% 需要维护过滤规则
同 AZ 部署采集层 100%(跨 AZ 费) 架构调整

我曾经踩过的坑:有个项目把采集服务器和 Kafka 部署在不同 AZ,一个月带宽费花了 5 万美金。后来把采集层挪到和 Kafka 同一个 AZ,成本直接降到零。嗯,就是这么简单粗暴。

2.5 采集层成本全景图

下面这张图,是我自己总结的采集层成本全景。它把数据源、采集方式、成本类型串在了一起。

数据采集层成本全景图 数据采集层成本全景图 数据源 业务 DB MySQL / PostgreSQL / Oracle CDC / Batch Pull 日志 应用日志 / 系统日志 Filebeat / Fluentd 埋点 客户端 / 服务端事件 SDK / HTTP API 无效数据占比:60-90% 采集方式 CDC 实时采集 Debezium / Canal CPU: 中 带宽: 高 批量拉取 DataX / Sqoop CPU: 高 带宽: 极高 日志采集器 Filebeat / Fluentd CPU: 低-中 内存: 中 埋点接收服务 成本类型 计算资源 CPU / 内存 网络带宽 跨 AZ / 跨 Region 源库压力 IO / 连接数 无效成本 无人使用的数据

2.6 采集层成本优化的“三板斧”

说了这么多问题,总得给点解决方案。我个人总结了三板斧:

  1. 第一板斧:砍掉无效数据。埋点事件先做审计,没人用的直接下掉。日志只保留关键字段,别把整个 JSON 都扔上来。
  2. 第二板斧:压缩 + 批量。能压缩就压缩,能批量就别一条一条发。gzip 压缩等级调到 1-3,别用 9。
  3. 第三板斧:架构优化。采集层尽量和下游在同一个 AZ。跨 Region 的采集,考虑用专线或者 VPN,别走公网。

我的经验:这三板斧用下来,采集层成本通常能降 40-60%。而且大部分改动都不需要动代码,改改配置就行。性价比极高。

2.7 本章小结

采集层的成本,说白了就是“数据还没被处理时的原始成本”。它最容易被忽略,也最容易优化。记住三个关键词:无效数据、压缩、架构。