4. 日志采集与存储:选对工具,事半功倍

采集合适,存储到位——OCSP 审计日志的性能分析,第一步其实就靠这两件事。我见过太多团队刚起步就扎进算法调优,结果发现日志根本收不上来,或者查个几天的记录就要等半天。

说白了,日志链路的前两公里要是没铺好,后面再怎么跑也快不起来。今天就聊聊我这些年用过、踩过、也优化过的采集和存储方案。

4.1 采集工具:rsyslog 与 Fluentd

采集工具的选择,直接影响你能否稳定拿到每一笔 OCSP 响应日志。我个人偏好从两个维度来评估:吞吐能力和灵活性。

4.1.1 rsyslog:轻量、可靠、原生

rsyslog 是 Linux 系统自带的日志守护进程,升级版 syslog。对 OCSP 场景来说,它的优势很直接——零依赖,配置简单,单机吞吐轻松撑到每秒数万条。

我曾经在一个日均处理 2000 万次 OCSP 查询的项目里,就用 rsyslog 把审计日志直接转发到远程服务器。配置大概长这样:

# /etc/rsyslog.d/ocsp-audit.conf

# 接收 OCSP 审计日志(本地 UDP 514 或自定义端口)
module(load="imudp")
input(type="imudp" port="514")

# 格式化输出为 JSON,方便下游解析
template(name="ocsp_json" type="list") {
    constant(value="{")
    constant(value="\"timestamp\":\"")   property(name="timereported" dateformat="rfc3339")
    constant(value="\",\"host\":\"")     property(name="hostname")
    constant(value="\",\"message\":\"")  property(name="msg" jsonr="on")
    constant(value="\"}")
}

# 转发到远程日志中心(TCP)
action(type="omfwd"
       target="10.0.1.100"
       port="6514"
       protocol="tcp"
       template="ocsp_json"
       queue.size="50000"
       queue.type="linkedlist"
       action.resumeRetryCount="-1")

这里有个坑——UDP 丢包。OCSP 响应频率很高,如果网络打满,UDP 可能扔掉 1%~3% 的日志。我曾经在高峰期发现丢了一条关键撤销记录,排查了两天才意识到是 rsyslog 默认用 UDP 转发的问题。

避坑指南
我曾经在高峰期发现 UDP 丢包导致关键撤销记录丢失。解决方案:改用 TCP 协议,并调大队列大小(queue.size)。高压场景下再配合磁盘辅助队列(queue.filename),确保不丢一条。

4.1.2 Fluentd:管道灵活、生态丰富

如果环境比较复杂——比如需要解析不同格式的 OCSP 日志、做字段过滤、或同时向多个存储目标分发日志,我建议用 Fluentd。

它的核心是一个插件架构,输入、解析、过滤、输出都能通过配置文件串联。下面是我在另一个项目中的典型配置:

# /etc/fluentd/fluent.conf

<source>
  @type  tail
  path   /var/log/ocsp-audit.log
  pos_file /var/log/fluentd-ocsp.pos
  tag    ocsp.audit
  <parse>
    @type  json
    time_key  timestamp
  </parse>
</source>

<filter ocsp.audit>
  @type  grep
  <regexp>
    key    status
    pattern good|revoked|unknown
  </regexp>
</filter>

<match ocsp.audit>
  @type  copy
  <store>
    @type  elasticsearch
    host   localhost
    port   9200
    index_name ocsp-audit-%Y%m%d
  </store>
  <store>
    @type  file
    path   /backup/ocsp-audit
    <buffer>
      chunk_limit_size 16m
      flush_interval 30s
    </buffer>
  </store>
</match>

看到没?用 copy 插件可以同时写入 Elasticsearch 和文件,既保证实时查询,又保留冷备份。我习惯把 buffer 开到 16MB,避免频繁写入磁盘造成 IO 争抢。

经验之谈
Fluentd 的 buffer 设置很关键。我曾经因为 flush_interval 太短(5s),导致小文件频繁刷盘,磁盘 IO 飙到 90%+。后来改成 30s 配合 16MB chunk,压力立刻下来。

4.1.3 工具对比表

维度rsyslogFluentd
部署复杂度极低(系统自带)中等(需安装 Ruby/td-agent)
单机吞吐≥10 万条/秒约 3~5 万条/秒
数据可靠性需显式配置 TCP + 队列内置 buffer + 重试机制
解析灵活性模板语法有限丰富(正则、JSON、多种格式)
生态插件较少丰富(200+ 输出插件)
内存占用低(约 50MB)中等(约 200~500MB)

你想想看,如果你的 OCSP 服务部署在裸金属上,日志量特别大,我倾向先选 rsyslog。如果有多重处理需求、或要对接多个存储系统,Fluentd 更灵活。

4.2 存储方案:Elasticsearch vs ClickHouse

采集完的日志要存到哪?这是另一个关键选择。我主要用过 Elasticsearch 和 ClickHouse,两者定位完全不同。

4.2.1 Elasticsearch:全文搜索利器

Elasticsearch 的优势是全文搜索和聚合分析。OCSP 审计日志里常有 certificate_serial、issuer_dn 等文本字段,ES 的倒排索引能秒级找到特定证书的历史记录。

但它也有代价——索引膨胀。每一条日志都要建倒排索引,存储开销高。我在一个项目里存了 30 天的 OCSP 日志(日均约 800 万条),光 ES 数据就占了 2TB 磁盘,而且写入吞吐很难超过 5 万条/秒。

最佳实践
如果查询场景以“按证书序列号搜索”“按时间范围聚合”为主,ES 很合适。但要注意:
  • 按天创建索引(manage rolling index),方便删除过期数据。
  • 对不需要全文搜索的字段设为 "index": false,减少存储。
  • 控制 refresh_interval 为 30s~60s,提升写入性能。

4.2.2 ClickHouse:列式存储,极致分析

ClickHouse 是真正的分析型数据库。它的列式存储让宽表聚合快得惊人。我做过测试:10 亿条 OCSP 日志,按响应状态(good/revoked)分组统计,ES 需要 8 秒,ClickHouse 只要 0.3 秒。

它的建表语句也很有特色:

CREATE TABLE ocsp_audit_local
(
    timestamp DateTime,
    host      String,
    cert_hash String,
    status    Enum8('good'=1, 'revoked'=2, 'unknown'=3),
    issuer_dn String,
    response_time_us UInt32
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(timestamp)
ORDER BY (timestamp, status, cert_hash)
TTL timestamp + INTERVAL 90 DAY DELETE;

-- 然后建分布式表
CREATE TABLE ocsp_audit AS ocsp_audit_local
ENGINE = Distributed('cluster_name', 'default', 'ocsp_audit_local', rand());

看到 TTL 了吧?自动清理过期数据,不用自己写定时脚本。而且 ORDER BY 的字段顺序直接影响查询性能。我习惯把时间戳+状态放在前面,因为大部分分析都按日/时聚合、再按状态分组。

注意
ClickHouse 不适合文本模糊搜索。如果要查“issuer_dn 包含某个词”,用 ES 更合适。另外,ClickHouse 对高并发小查询不太友好——单机 QPS 超过 300 时,连接池容易爆。建议前端加一层代理如 chproxy。

4.2.3 选型对比

维度ElasticsearchClickHouse
查询类型全文搜索、聚合大规模聚合、分析
写入性能3~5万条/秒(单节点)20~50万条/秒(单节点)
存储压缩比1:1~1:21:5~1:10(列式)
实时性准实时(秒级)准实时(秒级,但需优化合并)
运维复杂度较高(需调 JVM、分片)中等(无 JVM,但需理解合并树)
适用场景日志检索、告警溯源性能分析、大屏报表、长期存储

4.3 知识体系总览

我把这一章的核心逻辑画成了一张图,方便你理解采集和存储的上下游关系:

OCSP 审计日志采集与存储体系 OCSP 响应日志 rsyslog Fluentd 缓存 / 队列 / buffer Elasticsearch ClickHouse 全文搜索 · 告警溯源 · 日志检索 聚合分析 · 大屏报表 · 长期冷存 实际架构中,常用 rsyslog + ClickHouse 做高性能分析管道; 或用 Fluentd + Elasticsearch 满足多源汇聚与全文检索需求。

嗯,这张图把四个关键组件串起来了。从日志产生端到存储端,中间经过采集工具和缓冲。你可以在实际项目里根据需求搭配组合,比如我常用“rsyslog + ClickHouse”做高性能管道,或者“Fluentd + Elasticsearch”做多源汇聚。

核心建议
  • 日志量 > 5万条/秒,且以分析为主 → rsyslog + ClickHouse
  • 需要复杂过滤、多目标输出、全文搜索 → Fluentd + Elasticsearch
  • 混合场景:采集用 rsyslog(稳定高吞吐),同时复制一份到 ClickHouse 做分析,另一份到 ES 做检索