2. 数据采集策略:日志采集(ELK/Loki)、数据库采集(Binlog/CDC)、APM数据采集(SkyWalking/Pinpoint)

做测试数据分析,第一步就是搞定数据来源。说白了,你分析得再牛,没有数据也是白搭。我个人习惯把数据采集分成三大类:日志、数据库、APM。这三类数据各有各的脾气,采集策略也完全不同。今天我就把这套打法掰开揉碎了讲给你听。

2.1 日志采集:ELK vs Loki

日志是最传统、最基础的数据源。我刚开始做测试那会儿,查日志全靠 ssh 上服务器用 grep。现在想想,那简直是原始人时代。后来有了 ELK,再后来 Loki 也冒出来了。这两套方案我都深度用过,说说我的感受。

2.1.1 ELK 三件套

ELK 就是 Elasticsearch、Logstash、Kibana 的组合。这套方案非常成熟,社区也大。我在项目中遇到过最典型的场景:线上出了个诡异的内存泄漏,靠 ELK 的全文搜索能力,硬是从几 TB 的日志里把异常堆栈给揪了出来。

ELK 的采集流程大概是这样的:

应用日志 → Filebeat(轻量采集) → Logstash(过滤/解析) → Elasticsearch(存储/索引) → Kibana(可视化)

这里有个关键点:Logstash 很吃资源。我曾经在一个高并发项目里,Logstash 直接把 CPU 干到了 90%。后来我换成了 Filebeat + 轻量过滤,才把性能稳住。

核心配置示例(Filebeat):

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/app/*.log
  multiline.pattern: '^\d{4}-\d{2}-\d{2}'
  multiline.negate: true
  multiline.match: after

output.elasticsearch:
  hosts: ["localhost:9200"]
  index: "app-logs-%{+yyyy.MM.dd}"

嗯,这里要注意 multiline 配置。Java 异常栈是多行的,不配这个,一条异常会被拆成几十条日志,分析起来能把你逼疯。

2.1.2 Loki:轻量级选手

Loki 是 Grafana 家的产品。它跟 ELK 最大的区别是:Loki 不全文索引日志内容,只索引元数据(标签)。这带来了两个好处:存储成本低、查询速度快。但代价是——你不能像 ELK 那样做复杂的全文搜索。

我个人习惯这样选型:

  • 需要复杂搜索、聚合分析 → 选 ELK
  • 主要做实时监控、告警 → 选 Loki
  • 预算有限、日志量巨大 → 选 Loki

我的实战建议:中小团队可以先上 Loki + Promtail + Grafana。这套组合部署简单,资源占用低。等业务复杂了再考虑迁移到 ELK。我曾经帮一个创业团队从零搭建,两周就搞定了全链路的日志采集和监控。

2.2 数据库采集:Binlog 与 CDC

日志采集的是「系统说了什么」,数据库采集的是「数据发生了什么变化」。这两者结合起来,才能还原问题的全貌。

为什么要采集数据库?举个例子:用户反馈订单状态不对。日志里可能只记录了「订单更新失败」,但数据库里记录了「从待支付→已支付→已取消」的完整变化链条。没有数据库的变更数据,你根本不知道问题出在哪一步。

2.2.1 Binlog 采集

MySQL 的 Binlog 记录了所有数据变更。采集 Binlog 的工具有很多:Canal、Maxwell、Debezium。我用得最多的是 Canal,阿里开源的,稳定可靠。

Binlog 采集的核心流程:

MySQL Master → Binlog → Canal(伪装成 Slave) → MQ(Kafka/RocketMQ) → 消费端

Canal 配置示例:

canal.instance.master.address=127.0.0.1:3306
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
canal.instance.connectionCharset=UTF-8
canal.instance.filter.regex=test\\..*
# 监听 test 库下的所有表

这里有个坑:Binlog 有三种格式——STATEMENT、ROW、MIXED。做数据采集一定要用 ROW 格式。为什么?STATEMENT 格式记录的是 SQL 语句,你拿到的是 UPDATE user SET status=1 WHERE id>100,根本不知道具体改了哪些行。ROW 格式会记录每一行的前后镜像,这才是我们做分析需要的。

我曾经踩过的坑:有一次生产环境的 Binlog 格式被 DBA 改成了 MIXED,结果 Canal 采集到的数据全是 SQL 语句,没法解析成具体的变更记录。排查了整整一天才发现是格式问题。从那以后,我每次上线都会检查 Binlog 格式。

2.2.2 CDC(Change Data Capture)

CDC 是比 Binlog 更广义的概念。它不限于 MySQL,还支持 PostgreSQL、Oracle、MongoDB 等。Debezium 是目前最流行的 CDC 框架,基于 Kafka Connect 构建。

CDC 的优势在于:

  • 异构数据同步:MySQL 的数据变更实时同步到 Elasticsearch
  • 事件驱动:数据变更作为事件发布,下游服务可以订阅
  • 历史数据回溯:可以指定从某个时间点开始消费

我个人习惯用 Debezium + Kafka 的组合。举个例子,测试环境需要实时比对数据库和缓存的差异,我就用 Debezium 把数据库变更流到 Kafka,然后写个消费者做实时校验。

2.3 APM 数据采集:SkyWalking vs Pinpoint

APM(应用性能监控)采集的是「请求在系统里怎么跑的」。日志告诉你「出错了」,数据库告诉你「数据变了」,APM 告诉你「为什么变慢了」。

我遇到过最典型的场景:一个接口偶尔超时,日志没有报错,数据库也没有异常。最后靠 SkyWalking 的调用链发现,是某个下游服务的连接池满了,请求在排队等待。这种问题,没有 APM 数据根本定位不了。

2.3.1 SkyWalking

SkyWalking 是国产开源 APM 系统,对 Java 生态支持非常好。它的采集原理是:通过 Java Agent 字节码增强,自动拦截方法调用,生成调用链数据。

部署方式很简单:

# 在 JVM 启动参数中加入
-javaagent:/path/to/skywalking-agent.jar
-Dskywalking.agent.service_name=my-service
-Dskywalking.collector.backend_service=127.0.0.1:11800

SkyWalking 采集的数据包括:

  • 调用链:每个请求经过的所有服务和方法
  • 性能指标:响应时间、吞吐量、错误率
  • 服务拓扑:服务之间的调用关系
  • 数据库 SQL:执行的 SQL 语句和执行时间

我的使用习惯:SkyWalking 的拓扑图是我排查问题的第一站。先看拓扑图,哪个服务变红了(高延迟或高错误率),就点进去看调用链。这样能快速缩小问题范围,不用在几十个服务里瞎猜。

2.3.2 Pinpoint

Pinpoint 是韩国团队开源的 APM 系统。跟 SkyWalking 相比,它的特点是:

  • 代码级追踪:能看到每个方法的执行时间,甚至能定位到具体哪一行代码慢
  • 实时性更好:数据采集和展示的延迟更低
  • UI 更直观:调用链的火焰图做得非常漂亮

但 Pinpoint 也有缺点:资源消耗比 SkyWalking 大。我在一个高并发项目里试过,Pinpoint Agent 会导致应用响应时间增加 5%-10%。后来换成了 SkyWalking,性能损耗控制在 3% 以内。

对比维度 SkyWalking Pinpoint
性能损耗 低(约 3%) 中(约 5-10%)
代码级追踪 支持(需配置) 默认支持
部署复杂度 简单 中等
社区活跃度 高(中文社区)
适用场景 大规模分布式系统 中小规模、需要精细分析

2.4 三种数据采集的协同策略

你想想看,日志、数据库、APM 这三类数据,单独看都有局限性。但把它们串起来,威力就大了。

我常用的协同策略是这样的:

  1. APM 发现异常:某个接口响应时间突然飙升
  2. 调用链定位服务:发现是订单服务调用支付服务超时
  3. 日志查错误详情:支付服务的日志显示「连接池耗尽」
  4. 数据库查变更记录:Binlog 显示支付服务的数据库连接数配置被误改

这一套组合拳打下来,问题根因基本就浮出水面了。

数据采集的黄金法则:

  • 日志要全量采集,但要有分级(ERROR/WARN/INFO)
  • 数据库变更要实时采集,延迟控制在秒级
  • APM 要采样采集,100% 采集会拖垮系统
  • 三类数据要有统一的 TraceID 关联

嗯,说到 TraceID,这是数据关联的关键。我建议在应用层就生成 TraceID,然后透传到日志、数据库操作、APM 调用链里。这样出了问题,拿着 TraceID 就能在三套系统里来回查,效率翻倍。

最后说一句:数据采集不是一次性工作。系统在变,业务在变,采集策略也要跟着调整。我每半年会 review 一次采集方案,看看有没有遗漏的数据源,有没有性能瓶颈。这个习惯,建议你也保持。