首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Netflix 如何使用 ClickHouse 处理PB 级日志系统

Netflix 如何使用 ClickHouse 处理PB 级日志系统

作者头像
萝卜要努力
发布2025-11-14 13:04:36
发布2025-11-14 13:04:36
2010
举报
文章被收录于专栏:萝卜要加油萝卜要加油

原文链接: https://clickhouse.com/blog/netflix-petabyte-scale-logging[1]

引言:Netflix的“恐怖”日志规模

“在Netflix,规模决定一切。”工程师Daniel Muino的这句话,背后是一组震撼的数据:

  • 单日日志 ingestion 量达 5PB,平均每秒处理 1060万条事件(峰值1250万条);
  • 每条日志约5KB,支撑4万+微服务,服务全球190个国家的3亿+订阅用户;
  • 日志保留周期灵活(2周到2年),每秒还要响应500-1000次查询——这些查询是工程师排查故障、监控服务的核心工具。

要让这么大规模的日志“秒级可查”,光靠ClickHouse还不够。Netflix团队靠3个关键优化,才实现了“日志生成20秒内可搜、部分场景最低2秒延迟”的体验(远优于5分钟SLA)。

一、先看懂Netflix的日志架构:冷热分层是关键

Netflix的日志流程并不复杂,但每一步都经过取舍:

  1. 日志采集 thousands of 微服务 → 轻量级Sidecar → Ingestion集群;
  2. 临时缓冲后 数据写入Amazon S3,同时触发Amazon Kinesis消息;
  3. 核心存储分层
    • 热数据层(ClickHouse) 存储近期日志,主打“快”——支撑秒级查询、交互式调试;
    • 冷数据层(Apache Iceberg) 长期存储历史数据,兼顾成本与大规模时间范围查询;
  4. 统一查询层 通过Query API自动匹配目标命名空间,工程师无需关心“数据存在哪”,直接获取统一结果。
Netflix ClickHouse architecture
Netflix ClickHouse architecture

source:https://clickhouse.com/blog/netflix-petabyte-scale-logging

最终效果 点击日志事件、展开JSON payload、按指纹哈希分组百万条消息,都不用等查询“转圈”。

二、3个核心优化:从 ingestion 到查询的全面提速

优化1:日志指纹识别——用“编译器思维”替代机器学习/正则

日志要有用,首先得“去重归组”(即指纹识别):把百万条相似日志(如仅ID不同)压缩成一个模式,避免工程师被噪音淹没。

Netflix团队踩过两个坑:

  • 早期使用机器学习:理论可行,但资源消耗极高、速度太慢,直接导致产品不可用;
  • 再使用正则表达式:能匹配模式,但扛不住每秒1000万条的量——识别效率跟不上。

最后他们换了个思路:“日志识别和编译器分词是同一个问题,解法也一样——用词法分析器(lexer)”。 团队用JFlex(Java工具)生成优化后的词法分析器,把日志模式编译成高效代码,而非 runtime 解析复杂正则。 效果立竿见影:

  • 吞吐提升 8-10倍
  • 平均指纹识别时间从216微秒降到 23微秒
  • 即使是P99延迟也大幅降低。
优化2:数据序列化——逆向工程原生协议,突破写入瓶颈

指纹识别后,日志要以“每秒百万条”的速度写入ClickHouse,这一步又遇到了序列化瓶颈。

最初方案是JDBC批量插入:简单但低效——每次预编译语句都要协商 schema 和序列化细节, overhead 随规模暴涨。

团队先降到更低抽象层:用ClickHouse Java客户端的RowBinary格式,手动逐列序列化(如把DateTime64编码成“从 epoch 开始的纳秒数”),虽获性能提升,但仍不满足。

epoch 指的是“记时的零点”。最常见的是 Unix epoch: 1970-01-01 00:00:00(UTC)。

真正的突破来自一篇ClickHouse博客:原生协议(native protocol)的性能远超RowBinary[2],但Java客户端不支持(仅Go客户端支持)。 于是Daniel直接逆向工程Go客户端,自己造了个编码器:用原生协议生成LZ4压缩块,直接写入ClickHouse。 最终效果:CPU占用更低、内存效率更高,吞吐持平甚至超过RowBinary——“虽未完美,但还有很大优化空间”。

优化3:自定义标签查询——分片映射把3秒查询砍到700ms

日志查询中,工程师严重依赖“自定义标签”(如按微服务名、请求ID过滤),但标签也成了查询性能的“重灾区”。

原来的存储方式是Map(String, String):ClickHouse会把Map存成“键数组+值数组”,每次查询都要线性扫描——而Netflix每小时有2.5万个唯一标签键、数千万个唯一值,扫描速度极慢。

团队先试了ClickHouse创始人Alexei建议的LowCardinality类型:对标签键有效,但标签值太多,无法覆盖。

最终解法很简单:给Map分片。把标签键哈希到31个小Map里,查询时直接定位到目标分片,不用全量扫描。

效果惊人:

  1. 纯过滤查询:从3秒降到 1.3秒
  2. 过滤+投影查询:从近3秒降到 700ms以内
  3. 数据扫描量直接减少5-8倍。

三、最后:简洁才是大规模系统的核心

这三个优化没有复杂技巧,本质都是“简化”:

  • 指纹识别:用编译期代码替代 runtime 计算;
  • 序列化:用更底层的原生协议减少协商开销;
  • 查询:用分片减少扫描范围。

正如Daniel所说:“成功的关键不是耍小聪明,而是通过简化,让系统做最少的无用功。”

对Netflix而言,这套系统不仅是“日志存储”——更是支撑3亿用户流畅观影的“故障排查生命线”:从“等查询”到“秒级响应”,背后是每一个优化细节的积累。

引用链接

[1]https://clickhouse.com/blog/netflix-petabyte-scale-logging

[2]原生协议(native protocol)的性能远超RowBinary: https://clickhouse.com/blog/clickhouse-input-format-matchup-which-is-fastest-most-efficient

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-10-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 萝卜要加油 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言:Netflix的“恐怖”日志规模
  • 一、先看懂Netflix的日志架构:冷热分层是关键
  • 二、3个核心优化:从 ingestion 到查询的全面提速
    • 优化1:日志指纹识别——用“编译器思维”替代机器学习/正则
    • 优化2:数据序列化——逆向工程原生协议,突破写入瓶颈
    • 优化3:自定义标签查询——分片映射把3秒查询砍到700ms
  • 三、最后:简洁才是大规模系统的核心
  • 引用链接
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档