字节跳动日志采集系统揭秘——如何稳定处理每天数百TB日志?

2 阅读2分钟

日志,是分布式系统的“黑匣子”。在字节跳动,每天产生 数百 TB 日志,这些数据支撑着监控、推荐、增长、安全等核心系统。本篇文章将揭秘字节跳动的日志采集系统设计,并用 Node.js + Kafka 实现一个简化版日志采集链路


🧠 一、日志采集的核心难点

  1. 量大:字节跳动级别每天产生数百 TB 日志
  2. 链路长:从客户端 → 采集器 → 聚合服务 → 下游消费(Hive、ES)
  3. 实时性要求高:部分日志需秒级进入实时推荐系统
  4. 多格式多来源:Web、App、后端、容器、基础设施全链打通

📦 二、字节跳动日志采集架构演进

🔷 架构概览:

Client → SLS SDK → DataWay(本地Agent)→ Kafka 集群 → Flink / Hive / ClickHouse
模块功能说明
SLS SDK各端采集,前端/客户端打点
DataWay轻量日志代理,支持压缩、批量、打标签
Kafka核心消息队列,支持异地复制、Topic 管控
后处理系统Flink 做实时指标,Hive 做离线分析

🔧 DataWay 是字节跳动自研的本地日志 Agent,稳定运行在数十万台机器上。


⚙️ 三、代码实战:Node.js + Kafka 模拟日志采集链路

1. 安装 Kafka 依赖:

npm install kafkajs

2. 创建 Kafka Producer(日志采集端)

const { Kafka } = require('kafkajs');

const kafka = new Kafka({ clientId: 'logger', brokers: ['localhost:9092'] });
const producer = kafka.producer();

async function sendLog(userId, action) {
  await producer.connect();
  await producer.send({
    topic: 'user-events',
    messages: [
      { value: JSON.stringify({ userId, action, timestamp: Date.now() }) },
    ],
  });
  await producer.disconnect();
  console.log('日志已发送');
}

sendLog('u10001', 'click_button');

3. 创建 Kafka Consumer(日志聚合/处理端)

const consumer = kafka.consumer({ groupId: 'log-processors' });

async function start() {
  await consumer.connect();
  await consumer.subscribe({ topic: 'user-events', fromBeginning: true });

  await consumer.run({
    eachMessage: async ({ message }) => {
      const log = JSON.parse(message.value.toString());
      console.log('处理日志:', log);
      // 模拟落地到存储系统
    },
  });
}

start();

🔍 四、工程实践中的重点细节

问题点字节跳动做法
网络不稳定SDK 离线缓存 → Agent 重发
日志质量问题日志结构校验 + 异常字段打标
日志过载风险限速 + 拆包 + 分区限流 + Topic 限制
可观测性日志采集链路自身也打点监控
隐私合规用户隐私字段需脱敏/加密

✍️ 五、总结与思考

  • 字节跳动日志采集体系是分布式容错 + 实时传输 + 海量消费三者结合
  • Kafka 是核心组件,但本地 Agent(如 DataWay)同样重要
  • 中小型团队可以从 “SDK → Kafka → Hive/Flink” 模型入手,逐步演进

🎁 拓展推荐

  • 《Kafka 权威指南》— Confluent 团队
  • 《字节跳动日志系统 DataWay 架构设计与演进》
  • Flink + Kafka 流处理实时日志系统实践