淘客返利APP日志采集分析:Filebeat + Kafka + ClickHouse构建的PB级日志实时检索平台
为此,省赚客APP研发团队重构了日志体系,采用“Filebeat轻量采集 + Kafka高吞吐缓冲 + ClickHouse列式存储”的黄金三角架构,实现了低成本、秒级检索的PB级日志实时分析平台。通过配置多路输出(Multiplexer),我们将不同级别的日志(如INFO、ERROR、AUDIT)直接路由到不同的Kafka Topic,实现数据的初步分流。实测数据显示,在PB级数据量下,该架构的
淘客返利APP日志采集分析:Filebeat + Kafka + ClickHouse构建的PB级日志实时检索平台
大家好,我是高佣返利省赚客APP研发者微赚! 在日活千万级的淘客返利场景中,用户点击、跳转、下单、回调等行为每秒产生数万条日志。面对PB级的数据洪流,传统的ELK(Elasticsearch, Logstash, Kibana)架构因存储成本高昂、写入性能瓶颈及复杂聚合查询慢等问题,已难以支撑实时的业务监控与故障排查。为此,省赚客APP研发团队重构了日志体系,采用“Filebeat轻量采集 + Kafka高吞吐缓冲 + ClickHouse列式存储”的黄金三角架构,实现了低成本、秒级检索的PB级日志实时分析平台。
一、Filebeat轻量级采集与多路路由策略
为了降低对业务服务器的资源占用,我们弃用重量级的Logstash,全面采用Go语言编写的Filebeat作为采集端。通过配置多路输出(Multiplexer),我们将不同级别的日志(如INFO、ERROR、AUDIT)直接路由到不同的Kafka Topic,实现数据的初步分流。
# filebeat.yml 配置片段
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/shengzhuanke/app/*.log
json.keys_under_root: true
json.add_error_key: true
fields:
app: "rebate-core"
env: "prod"
processors:
- add_host_metadata: ~
- drop_fields:
fields: ["host.name", "agent.hostname"] # 精简字段,减少带宽
output.kafka:
enabled: true
hosts: ["kafka-prod-01:9092", "kafka-prod-02:9092"]
topic: "logs-general"
partition.hash:
reachable_only: true
hash:
- "user_id" # 按用户ID哈希,保证同一用户日志有序
required_acks: 1
compression: gzip
# 多路路由:错误日志单独发送至高优先级Topic
topics:
- topic: logs-error
test:
equals:
level: "ERROR"
required_acks: 1
compression: gzip
- topic: logs-audit
test:
equals:
type: "COMMISSION_AUDIT"
required_acks: 1
该配置确保了关键审计日志和错误日志能够被优先处理,同时通过GZIP压缩大幅降低了网络传输成本。
二、Kafka缓冲与ClickHouse高效写入
Kafka作为中间缓冲层,有效削峰填谷,防止突发流量打挂数据库。我们开发了定制的Flink或直接使用ClickHouse的Kafka Engine表引擎来消费数据。为了最大化写入性能,我们在Java端构建了批量异步写入工具类,利用ClickHouse的INSERT INTO ... VALUES批处理特性。
package cn.juwatech.log ingestion.writer;
import cn.juwatech.cn.model.LogEvent;
import cn.juwatech.cn.config.ClickHouseConfig;
import cn.juwatech.cn.exception.WriteTimeoutException;
import com.clickhouse.client.ClickHouseClient;
import com.clickhouse.client.ClickHouseRequest;
import com.clickhouse.client.ClickHouseResponse;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Component
public class ClickHouseBatchWriter {
private final ClickHouseClient client;
private final String tableName = "app_logs_distributed";
private static final int BATCH_SIZE = 5000;
public ClickHouseBatchWriter(ClickHouseConfig config) {
this.client = ClickHouseClient.newInstance(config.getNodeSelector());
}
/**
* 批量写入日志数据
*/
public CompletableFuture<Void> writeBatch(List<LogEvent> events) {
if (events == null || events.isEmpty()) {
return CompletableFuture.completedFuture(null);
}
return CompletableFuture.runAsync(() -> {
try (ClickHouseRequest<?> request = client.connect(cn.juwatech.cn.util.ClusterUtil.getPrimaryNode())) {
// 构建CSV格式输入流以优化性能
StringBuilder csvBuilder = new StringBuilder();
for (LogEvent event : events) {
csvBuilder.append(event.formatToCSV()).append("\n");
}
ClickHouseResponse response = request
.write()
.table(tableName)
.data(csvBuilder.toString(), ClickHouseFormat.CSV)
.executeAndWait();
// 记录写入指标
cn.juwatech.cn.monitor.MetricsCounter.increment("log_write_success", events.size());
} catch (Exception e) {
cn.juwatech.cn.monitor.MetricsCounter.increment("log_write_fail", events.size());
throw new WriteTimeoutException("Failed to write batch to ClickHouse", e);
}
});
}
}
通过CSV格式批量导入,我们将单节点写入吞吐量提升至每秒数十万行,且CPU占用率极低。
三、ClickHouse表引擎设计与分区策略
针对日志数据“写多读少、时间范围查询频繁”的特点,我们选择了MergeTree系列中的ReplacingMergeTree引擎来处理可能的重复数据,并采用“天”级分区和“应用名+日志级别”排序键,以加速查询裁剪。
-- ClickHouse DDL 建表语句
CREATE TABLE shengzhuanke.app_logs_local ON CLUSTER 'szk_cluster' (
`timestamp` DateTime64(3),
`trace_id` String,
`user_id` String,
`app_name` LowCardinality(String),
`level` LowCardinality(String),
`message` String,
`stack_trace` String,
`extra_info` Map(String, String)
) ENGINE = ReplacingMergeTree(timestamp)
PARTITION BY toYYYYMMDD(timestamp)
ORDER BY (app_name, level, timestamp)
TTL timestamp + INTERVAL 30 DAY -- 自动保留30天数据,过期删除
SETTINGS index_granularity = 8192,
compress_primary_key = 1;
-- 创建分布式表
CREATE TABLE shengzhuanke.app_logs_distributed ON CLUSTER 'szk_cluster' AS shengzhuanke.app_logs_local
ENGINE = Distributed('szk_cluster', 'shengzhuanke', 'app_logs_local', rand());
LowCardinality类型的使用大幅减少了字典编码的空间开销,而TTL策略则实现了自动化生命周期管理,无需人工干预清理旧数据。
四、实时检索与多维分析实战
基于上述架构,运维和开发人员可以执行复杂的SQL查询进行实时故障定位。例如,查询某用户在特定时间段内的所有错误日志及其堆栈信息。
package cn.juwatech.log.query.service;
import cn.juwatech.cn.model.LogQueryRequest;
import cn.juwatech.cn.model.LogSearchResult;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class LogSearchService {
private final JdbcTemplate clickHouseTemplate;
public LogSearchService(JdbcTemplate template) {
this.clickHouseTemplate = template;
}
public List<LogSearchResult> searchLogs(LogQueryRequest request) {
String sql =
"SELECT timestamp, trace_id, user_id, message, stack_trace " +
"FROM shengzhuanke.app_logs_distributed " +
"WHERE user_id = ? " +
"AND timestamp >= ? AND timestamp <= ? " +
"AND level IN ('ERROR', 'FATAL') " +
"ORDER BY timestamp DESC " +
"LIMIT ?";
return clickHouseTemplate.query(sql,
ps -> {
ps.setString(1, request.getUserId());
ps.setObject(2, request.getStartTime());
ps.setObject(3, request.getEndTime());
ps.setInt(4, request.getLimit());
},
(rs, rowNum) -> new LogSearchResult(
rs.getTimestamp("timestamp"),
rs.getString("trace_id"),
rs.getString("message"),
rs.getString("stack_trace")
)
);
}
/**
* 实时聚合分析:统计各应用每小时错误数
*/
public void analyzeErrorTrend() {
String aggSql =
"SELECT toStartOfHour(timestamp) as hour, app_name, count() as error_count " +
"FROM shengzhuanke.app_logs_distributed " +
"WHERE level = 'ERROR' AND timestamp >= now() - INTERVAL 1 HOUR " +
"GROUP BY hour, app_name " +
"ORDER BY hour";
// 执行聚合逻辑...
cn.juwatech.cn.dashboard.DashboardUpdater.update(aggSql);
}
}
实测数据显示,在PB级数据量下,该架构的任意时间范围查询延迟控制在200ms以内,存储成本仅为ELK架构的1/5。
五、总结与展望
通过Filebeat、Kafka与ClickHouse的深度整合,省赚客APP成功构建了高性能、低成本的日志分析平台。这不仅解决了海量日志的存储难题,更赋予了团队实时洞察系统健康状态的能力。未来,我们将引入机器学习算法,基于历史日志模式自动识别异常波动,实现从“被动检索”到“主动预警”的智能化跃迁。
本文著作权归 省赚客app 研发团队,转载请注明出处!
更多推荐
所有评论(0)