4. 数据流总图:事件产生→Agent采集→缓冲→清洗→归一化→写入→消费
数据采集管道的整体架构必须清晰定义各环节的边界与职责,才能支撑Reach(触达量)与Impact(影响力)两类指标的高吞吐、低延迟、可审计投递。本章以数据流总图为纲,逐层拆解从事件发生到消费侧的全链路设计。
4.1 边界定义
- 上游边界:用户端(Web / App / Server)产生的行为事件,包括曝光、点击、自定义属性等结构化 JSON 负载。
- 下游边界:消费端包括实时数仓(Flink SQL / ClickHouse)、离线数仓(Hive / Iceberg)、告警服务以及反作弊校验模块。
- 数据不落边界:缓冲层前的原始事件若超过 TTL(默认 24h)且未被确认消费,将直接丢弃;清洗层与归一化层不持久化中间状态。
4.2 分层架构
数据流共划分为 6 个逻辑层,每层可由多个物理组件组成,但对外暴露统一语义接口:
| 层序号 | 层名称 | 定位 |
|---|---|---|
| L0 | 事件产生层 | 业务侧埋点输出 |
| L1 | Agent 采集层 | 端侧 / 服务侧数据收集与格式校验 |
| L2 | 缓冲层 | 削峰填谷、解耦上下游 |
| L3 | 清洗层 | 过滤无效、非法或超限事件 |
| L4 | 归一化层 | 字段映射、维度补齐、时间对齐 |
| L5 | 写入层 | 持久化到目标存储 |
| L6 | 消费层 | 下游应用读取处理 |
4.3 组件职责
| 组件 | 所属层 | 核心职责 |
|---|---|---|
| Event SDK / Server Hook | L0 | 生成标准埋点事件,含 uuid、时间戳、事件名、属性 map |
| Sidecar Agent | L1 | 本地采集、压缩、心跳上报,支持 batch 与重试 |
| Kafka Topic | L2 | 持久化缓冲、分区有序、多消费者组隔离 |
| Wash Processor | L3 | 基于正则 + PNF 校验过滤脏数据 |
| Normalizer | L4 | IP 转地理、UA 解析、时间戳校正、枚举合并 |
| Writer | L5 | 批量写入 ClickHouse / HDFS,支持幂等写 |
| Consumer SDK | L6 | 拉取、反序列化、投递到下游算子 |
4.4 数据流与信任链路
数据流遵循 “至少一次交付 + 幂等消费” 原则。每层通过以下机制建立信任:
- 序列号:每一条事件在 L0 生成时携带全局递增 seq_id,写入层对 seq_id 去重。
- 校验和:L1 -> L2 传输时附带 CRC32 校验,缓冲层拒绝不通过的消息。
- 偏移量跟踪:消费者按分区提交 offset,失败后重置到最近可提交点。
- 死信队列:L3 或 L4 无法处理的异常事件进入专用 Topic,人工介入修复后重放。
信任链路的设计目标:任一环节故障不会导致数据永久丢失或重复写入。具体实现上,利用 Kafka 的 compaction + 幂等生产者保证最终一致。
4.5 控制流
控制流与数据流分离,通过 独立的配置中心(Apollo / Nacos) 对各层下发动态参数:
- 采样率:实时调整 L1 采集密度,应对突发流量。
- 清洗规则:热更新黑白名单、阈值。
- 归一化映射表:新增字段映射时无需重启节点。
- 背压阈值:L2 缓冲水位超过 80% 时,通知 L1 降级采样或丢弃低优先级事件。
4.6 选型权衡
| 决策点 | 推荐选型 | 备选方案 | 考量理由 |
|---|---|---|---|
| 缓冲层消息系统 | Apache Kafka 3.x | Apache Pulsar | Kafka 生态成熟、吞吐高、重平衡快;Pulsar 更适合多租户,但运维复杂度高。 |
| 清洗层计算引擎 | Flink (YARN / K8s) | Spark Streaming | Flink 原生支持事件时间、状态管理、实时规则更新。 |
| 归一化存储后端 | Redis (短属性) + MySQL (长属性) | 单 AlloyDB | 高频属性用缓存避免 DB 压力,低频映射用持久化可靠。 |
| 写入层持久化 | ClickHouse (实时) + Iceberg (离线) | Druid / HBase | ClickHouse 列存分析快,Iceberg 支持增量入湖。 |
4.7 风险点与规避
- 数据倾斜:事件 key 分布不均可导致部分分区堆积。规避:采集层对 key 加盐预处理(如
hash(event_id) % num_partitions)。 - 背压传播:下游写入慢引发上游累积。规避:L2 配置基于水位线的动态反压,通知 L1 降级采样。
- 时序错乱:网络抖动导致事件时间戳与处理时间偏差大。规避:归一化层启用 event_time 作为主时间戳,打上 kafka offset 作为辅助排序。
- 资源泄露:Agent 连接泄漏或线程膨胀。规避:Sidecar 内建连接池、超时熔断、异常自动恢复。
4.8 落地步骤
- 部署 Kafka 集群(至少 3 节点),创建 6 分区事件 Topic。
- 在业务容器中以 DaemonSet 方式注入 Sidecar Agent,接入现有埋点 SDK。
- 开发清洗 Processor(Flink 作业),配置初始规则的 JSON 文件。
- 搭建归一化服务,加载 Redis 映射和 MySQL 字典连接池。
- 配置 Writer 连接 ClickHouse 和 HDFS,设定写入并发与批大小。
- 启动消费端(Flink SQL / 告警 Hook),验证数据完整性与延迟。
4.9 验收标准
| 指标 | 目标值 | 监测方式 |
|---|---|---|
| 端到端 P99 延迟 | ≤ 5s(99% 请求) | Event SDK 内嵌 timestamp,消费端计算延迟直方图 |
| 数据丢失率 | ≤ 0.01% | Producer 发前计数 vs 消费端去重计数对比 |
| 清洗正确率 | ≥ 99.99% | 抽查异常事件是否被正确处理或入死信队列 |
| 归一化命中率 | ≥ 99.5% | Redis cache 命中流水日志 |
| 写入层吞吐 | ≥ 50万 events/sec per partition | Kafka 流量监控 + ClickHouse 写入行数 |
架构要点:此数据流总图强调了分层解耦与可观测性。每一层都有明确的故障域——缓冲层使用 Kafka 保证高可用,清洗与归一化层以 Flink 状态提供 exactly-once 语义。实际部署时应优先监控缓冲层水位与清洗层的异常率。