CDN日志是内容分发网络运行过程中产生的最原始、最完整的数据记录。每一次用户请求,无论命中缓存还是回源,都会在边缘节点上留下一条日志,其中包含了访问时间、客户端IP、请求方法、URL、状态码、响应字节数、缓存命中状态、Referer、User-Agent等关键信息。把这些日志管好、用好,是评估CDN效果、排查线上问题、发现安全威胁的基础。本文将从日志的采集与格式解析、存储与处理架构、分析与监控实践三个角度,系统讲讲CDN日志管理的完整链路。

一、CDN日志的采集方式与常见格式解析
目前主流CDN厂商提供的日志获取方式主要有两类:离线日志下载和实时日志推送。离线日志通常按小时打包,通过控制台或API接口拉取,适合对时效性要求不高的日常统计和报表场景,优点是实现简单、成本可控。实时日志推送则是通过Kafka等消息队列,把节点产生的日志近实时地投递到用户自己的接收端,延迟通常在秒级到分钟级,适合做实时监控、告警和攻击拦截。两种方式并不冲突,实践中往往同时启用:实时流负责告警和大盘,离线包负责精确对账和长期归档。
拿到日志后,第一步是理解格式。以常见的Nginx风格CDN日志为例,一行日志通常长这样:
[09/Jan/2025:14:32:11 +0800] 203.0.113.45 GET /static/app.js 200 10240 HIT "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" "https://ipipp.com/index.html" edge-node-03 0.023
这条日志包含了几个值得注意的字段。状态码200表示请求成功;HIT表示请求在边缘节点命中了缓存,如果是MISS则说明发生了回源;末尾的0.023通常代表响应耗时,单位是秒。缓存命中状态字段是CDN日志中最有价值的字段之一,通过统计HIT与MISS的比例,可以直接算出缓存命中率。解析这类日志时,可以用正则表达式提取字段,也可以在日志采集端配置结构化输出,直接以JSON格式生成,省去后续解析成本:
log_format cdn_json escape=json '{'
'"time":"$time_iso8601",'
'"client_ip":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status,'
'"bytes":$body_bytes_sent,'
'"cache_status":"$upstream_cache_status",'
'"referer":"$http_referer",'
'"ua":"$http_user_agent",'
'"rt":$request_time'
'}';
access_log /var/log/nginx/cdn_access.log cdn_json;需要特别提醒的是,各家CDN的字段定义和顺序存在差异,比如有的厂商日志中IP字段可能包含端口,有的会把回源耗时和响应耗时分开记录。接入多家CDN的团队建议先抽象出一套统一的内部日志Schema,在采集层做一次字段映射,避免下游分析逻辑被厂商格式差异绑架。
二、海量CDN日志的存储与处理架构设计
CDN日志的量级往往超出想象。一个日请求量十亿级别的业务,即使按每条日志500字节计算,一天产生的原始日志也有数百GB。如果没有合理的存储架构,日志很快会把磁盘吃满,或者查询慢到无法使用。设计日志处理架构时,核心思路是分层:采集层、传输层、存储层、计算层各司其职。
采集层通常在每个日志接收服务前部署Filebeat、Fluentd或Flume,负责监听日志文件变化或接收推送流。传输层一般用Kafka做缓冲,它可以削峰填谷,防止流量突增时下游被冲垮,同时支持多个消费组各自订阅,一份日志同时供给实时分析和离线仓库。存储层的选择取决于查询需求:如果主要做全文检索和排障,Elasticsearch比较合适;如果偏重海量数据的聚合统计和留存成本控制,ClickHouse或对象存储加Parquet格式的方案性价比更高。
下面是一个典型的Kafka消费端把日志写入ClickHouse的示例:
CREATE TABLE cdn_access_log
(
time DateTime,
client_ip IPv4,
uri String,
status UInt16,
bytes UInt64,
cache_status LowCardinality(String),
rt Float32
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(time)
ORDER BY (time, client_ip);按天分区、按时间和IP排序的表设计,可以让按时间段、按IP的查询直接裁剪数据块,扫描量大幅下降。针对冷热数据,还应制定生命周期策略:热数据保留7到30天供高频查询,温数据压缩归档到对象存储保留半年到一年,超期数据定期清理。如果没有归档策略,存储成本会随时间线性膨胀,这一点在日志管理规划阶段就要想清楚。
三、基于CDN日志的监控分析与问题定位实践
日志管理的最终目的是产生洞察。CDN日志分析有几类高频场景,值得提前建好固定看板。第一是流量与带宽趋势,按分钟聚合的带宽曲线能直观反映业务高峰和异常突刺。第二是缓存命中率,按域名、按路径前缀、按文件类型多维度拆解,命中率突然下降往往意味着缓存配置变更、URL带随机参数或缓存过期策略出了问题。第三是状态码分布,5xx比例升高提示源站或节点异常,大量404可能是资源缺失,也可能是扫描攻击的前兆。
以一次典型的日志排查为例:某天监控发现某域名缓存命中率从95%跌到60%。通过日志按URL维度聚合,很快定位到是某个接口的响应头里动态加了一个时间戳参数,导致每个请求的URL都不一样,全部MISS并回源打挂了源站。类似的问题,纯靠业务方反馈往往滞后数小时,而日志分析几分钟就能定位。常用的聚合SQL示例如下:
SELECT
toStartOfMinute(time) AS minute,
count() AS req_cnt,
round(countIf(cache_status = 'HIT') / count() * 100, 2) AS hit_rate,
round(sum(bytes) / 1024 / 1024, 2) AS traffic_mb
FROM cdn_access_log
WHERE time >= now() - INTERVAL 1 HOUR
GROUP BY minute
ORDER BY minute;除了性能分析,日志还是安全防护的重要数据源。通过统计客户端IP的请求频率,可以识别CC攻击和恶意爬虫;分析Referer和User-Agent的异常组合,能发现盗链和伪装流量。一个简单实用的做法是设置实时规则:当某IP在一分钟内请求超过阈值且缓存命中率异常时,自动触发告警并联动CDN的访问控制能力进行限速或封禁。
总结来说,CDN日志管理是一个从采集、解析、存储到分析监控的完整工程体系。做好字段标准化和数据分层是基础,实时与离线双链路是保障,固定看板加自动告警才能让日志价值持续释放。建议团队尽早规划日志预算和留存策略,把CDN日志当作核心观测数据来经营,而不是出问题后才临时翻找的记录文件。