高吞吐、低成本日志系统方案ClickHouse + Filebeat/Fluentd

一只会飞的鱼儿 2小时前 ⋅ 6 阅读
ad

下面给你一套 高吞吐、低成本日志系统方案:ClickHouse + Filebeat/Fluentd 的最简可落地架构,含组件分工、部署要点、建表示例和配置模板。

一、整体架构(极简版)

应用日志文件/容器日志
  ↓
Filebeat / Fluent Bit(采集、轻量过滤)
  ↓
Kafka(可选,削峰、解耦、重放)
  ↓
ClickHouse(列式存储、高压缩、高吞吐写入/查询)
  ↓
Grafana / 自建后台(可视化、检索、告警)

核心优势

  • 高吞吐:ClickHouse 批量写入、向量化执行,写入 TPS 远高于 ES
  • 低成本:列式 + 高压缩(通常 5–15 倍),磁盘 / 内存成本远低于 ES
  • 适合日志:时间序列、结构化 / 半结构化、聚合查询友好

二、组件选型与分工

1. 采集层:Filebeat vs Fluent Bit

  • Filebeat
    • 优点:Elastic 生态成熟、配置简单、对日志文件 / 多行支持好
    • 适合:传统服务、文件日志、Java 应用
  • Fluent Bit
    • 优点:更轻量、性能更好、K8s / 容器原生、插件丰富
    • 适合:K8s、云原生、高密部署

推荐:非 K8s 用 Filebeat;K8s 用 Fluent Bit


2. 缓冲层:Kafka(强烈建议)

  • 作用:削峰、解耦、保证不丢、可重放、多下游复用
  • 不建议直接从采集器写 ClickHouse:突发流量易写失败、无重试队列

3. 存储层:ClickHouse

  • 推荐引擎:MergeTree 家族(MergeTree / ReplacingMergeTree / SummingMergeTree
  • 分区:按天 / 小时分区(日志典型)
  • 索引:时间戳 + 服务名 + 级别 + traceId 等常用维度
  • 压缩:默认 LZ4 即可,高压缩用 ZSTD

三、ClickHouse 建表示例(通用日志表)

CREATE TABLE IF NOT EXISTS logs (
    timestamp DateTime64(3) CODEC(DoubleDelta, LZ4),
    service String CODEC(ZSTD),
    level String CODEC(ZSTD),
    trace_id String CODEC(ZSTD),
    span_id String CODEC(ZSTD),
    host String CODEC(ZSTD),
    path String CODEC(ZSTD),
    message String CODEC(ZSTD),
    json_fields Map(String, String) CODEC(ZSTD)
) ENGINE = MergeTree()
PARTITION BY toDate(timestamp)
ORDER BY (service, level, toStartOfHour(timestamp), timestamp)
TTL timestamp + INTERVAL 30 DAY DELETE; -- 自动删 30 天日志,按需改

要点:

  • DateTime64(3):毫秒级时间
  • CODEC:显式指定压缩,提升压缩比
  • PARTITION BY toDate(timestamp):按天分区,删除 / 查询更快
  • TTL:自动过期,降低存储成本

四、Filebeat → Kafka 配置示例(filebeat.yml)

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/myapp/*.log
  multiline.type: pattern
  multiline.pattern: '^\['
  multiline.negate: true
  multiline.match: after
  fields:
    service: my-java-app
  fields_under_root: true

output.kafka:
  hosts: ["kafka-1:9092", "kafka-2:9092"]
  topic: "logs-myapp"
  partition.round_robin:
    reachable_only: false
  required_acks: 1
  compression: gzip
  max_message_bytes: 1000000

processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~

Webfunny 全链路监控埋点平台 是一站式前端监控 + 用户行为埋点 + 大数据分析平台,天然适配点位细查、用户行为回溯、批量导出等场景:

一体化架构:监控 + 埋点同一套 SDK,数据互通无壁垒
私有化部署:数据完全本地化,满足企业合规要求
高吞吐支撑:基于 ClickHouse 构建,亿级日志秒级查询
全端覆盖:H5 / 小程序 / APP / 鸿蒙全覆盖,统一导出口径
可定制强:支持接口扩展、分布式锁、限流降级等企业级能力

五、Fluent Bit → Kafka 配置示例(fluent-bit.conf)

[SERVICE]
    Flush        1
    Log_Level    info
    Daemon       off

[INPUT]
    Name         tail
    Path         /var/log/myapp/*.log
    Parser       json
    Tag          logs.myapp
    Multiline    On
    Multiline_Format regex
    Multiline_Pattern ^\[
    DB           /var/lib/fluent-bit/pos.db

[OUTPUT]
    Name         kafka
    Match        logs.*
    Brokers      kafka-1:9092,kafka-2:9092
    Topics       logs-myapp
    Compression  gzip

六、Kafka → ClickHouse 写入方案

方案 A:ClickHouse Kafka Engine(推荐,最简单)

在 CH 建一张 Kafka 消费表 + 物化视图写入日志表。

1)建 Kafka 引擎表(消费 topic)

CREATE TABLE logs_kafka (
    raw String
) ENGINE = Kafka
SETTINGS
    kafka_broker_list = 'kafka-1:9092,kafka-2:9092',
    kafka_topic_list = 'logs-myapp',
    kafka_group_name = 'clickhouse-log-group',
    kafka_format = 'JSONAsString',
    kafka_skip_broken_messages = 1;

2)建物化视图,解析 JSON 写入 logs

CREATE MATERIALIZED VIEW logs_mv TO logs AS
SELECT
    toDateTime64(JSONExtractString(raw, 'timestamp'), 3) AS timestamp,
    JSONExtractString(raw, 'service') AS service,
    JSONExtractString(raw, 'level') AS level,
    JSONExtractString(raw, 'trace_id') AS trace_id,
    JSONExtractString(raw, 'span_id') AS span_id,
    JSONExtractString(raw, 'host') AS host,
    JSONExtractString(raw, 'path') AS path,
    JSONExtractString(raw, 'message') AS message,
    JSONExtract(raw, 'json_fields', 'Map(String, String)') AS json_fields
FROM logs_kafka;

优点:无额外组件,CH 自己消费 Kafka,运维简单。


方案 B:使用 Vector / Logstash(更灵活)

  • 适合:需要复杂 ETL、多 sink、路由、 enrichment 场景
  • 流程:Kafka → Vector/Logstash(解析 / 清洗)→ ClickHouse

七、关键优化(高吞吐 + 低成本)

1. ClickHouse 写入优化

  • 批量写入:Kafka + CH Kafka Engine 天然批量
  • max_insert_block_size = 1048576
  • async_insert = 1(异步插入,提升吞吐,注意数据安全)
  • 内存表 / Buffer 表做写入缓冲(可选)

2. 存储与压缩

  • 优先 ZSTD 压缩,比 LZ4 压缩比更高,CPU 开销可接受
  • 按时间分区,TTL 自动清理,避免无限膨胀
  • 冷数据可使用 S3 分层存储(CH 支持 S3 磁盘)

3. 采集端优化

  • 采集端开启 gzip 压缩
  • 多行日志正确配置,避免乱序 / 截断
  • 采集器资源限制:Filebeat/Fluent Bit 都很轻量

八、典型查询示例

-- 近 1 小时错误日志
SELECT *
FROM logs
WHERE level = 'ERROR'
  AND timestamp >= now() - INTERVAL 1 HOUR
ORDER BY timestamp DESC
LIMIT 100;

-- 按服务统计 QPS/错误数
SELECT
    toStartOfMinute(timestamp) AS minute,
    service,
    count() AS total,
    countIf(level = 'ERROR') AS errors
FROM logs
WHERE timestamp >= now() - INTERVAL 1 HOUR
GROUP BY minute, service
ORDER BY minute, service;

九、与 ELK 对比(简要)

表格

维度 ELK Stack ClickHouse + Filebeat/Fluentd
写入吞吐 中高 更高(批量 + 向量化)
存储成本 较高(倒排索引) 低(列式 + 高压缩)
全文检索 一般(n-gram/Token 可做)
聚合 / 统计 一般 极强
运维复杂度 中(ES 分片 / 集群敏感) 较低(CH 简单,无分片烦恼)
适合场景 全文检索、日志 + 安全分析 高吞吐、低成本、统计聚合为主

十、落地建议

如果你是 Java 后端,常见场景:

  • 应用:Spring Boot + Logback/Log4j2 输出 JSON 日志
  • 采集:Filebeat 采集日志文件 → Kafka
  • 存储:ClickHouse 用 Kafka Engine 消费
  • 可视化:Grafana + ClickHouse 数据源 做面板 / 检索

关于Webfunny

Webfunny专注于前端监控系统,前端埋点系统的研发。 致力于帮助开发者快速定位问题,帮助企业用数据驱动业务,实现业务数据的快速增长。支持H5/Web/PC前端、微信小程序、支付宝小程序、UniApp和Taro等跨平台框架。实时监控前端网页、前端数据分析、错误统计分析监控和BUG预警,第一时间报警,快速修复BUG!支持私有化部署,Docker容器化部署,可支持千万级PV的日活量!

  点赞 0   收藏 0
  • 一只会飞的鱼儿
    共发布69篇文章 获得8个收藏
全部评论: 0