ClickHouse 为什么适合安全日志分析
在安全平台建设中,日志分析几乎是绕不开的核心能力。无论是主机行为日志、网络流量日志、访问日志、告警日志,还是资产指纹、基线检查结果,最终都会沉淀成大量结构化或半结构化数据。安全团队真正关心的不是“有没有日志”,而是:日志量上来之后还能不能写得进去、查得出来、分析得动。
在传统方案里,很多人会优先想到 Elasticsearch。它确实适合全文检索,也适合做日志搜索和可视化。但当日志规模达到千万级、亿级,查询需求又从“搜一条日志”变成“按时间、主机、IP、端口、协议、告警类型做聚合分析”时,ClickHouse 的优势就会越来越明显。
本文想结合安全日志分析的真实场景,聊一聊:为什么 ClickHouse 很适合作为安全日志分析平台的底层存储与分析引擎。
一、安全日志分析的核心特点
安全日志和普通业务日志不太一样。业务日志更多关注接口状态、异常堆栈、用户行为链路,而安全日志通常有几个明显特点。
第一,数据量大,而且持续增长。
比如流量采集、访问关系分析、登录审计、进程行为、端口监听、基线检查、告警事件等数据,都可能持续不断地产生。尤其是在数据中心或企业内网环境中,主机数量一旦上来,日志量会非常可观。每天千万级日志并不夸张,高峰期还可能出现瞬时流量暴涨。
第二,写入多,修改少。
安全日志天然具有事件属性。某个连接发生了、某个进程启动了、某条告警触发了,这些数据一般都是追加写入,后续很少修改。这种“写多改少”的模式非常适合列式数据库和 OLAP 引擎。
第三,查询以时间范围和多维过滤为主。
安全分析中最常见的问题不是“某一条日志在哪里”,而是:
- 最近 1 小时某台主机有哪些异常连接?
- 某个源 IP 在过去 24 小时访问了哪些目标端口?
- 某类告警今天触发了多少次?
- 某个业务组之间是否存在异常访问关系?
- 某个资产最近 7 天的风险趋势如何?
这些查询通常都会带有时间范围、主机 ID、IP、端口、协议、告警类型、业务组等过滤条件,并且经常需要做 count、group by、topN、distinct、趋势统计等聚合分析。
第四,分析结果比单条日志更重要。
安全人员当然也需要查看原始日志,但在大多数情况下,更重要的是从大量日志中发现异常模式。例如扫描行为、暴力破解、横向移动、异常外联、端口暴露、基线风险变化等。这类场景更依赖大规模聚合、排序、过滤和统计能力。
这些特点决定了,安全日志分析需要的不只是一个“能存日志”的系统,而是一个高吞吐、低成本、强聚合、适合时间序列分析的数据引擎。
二、ClickHouse 的定位:不是普通数据库,而是 OLAP 分析引擎
ClickHouse 是一个列式 OLAP 数据库。它最擅长的不是高频事务更新,而是对大量数据进行快速分析。
这点非常关键。
如果用 MySQL 来存安全日志,在数据量小的时候当然也能用。但随着数据量增加,问题会很快暴露:写入压力大、索引膨胀、聚合查询慢、历史数据清理困难、存储成本高。MySQL 的优势在事务一致性、点查、更新和复杂业务关系建模,而不是海量日志分析。
ClickHouse 的设计目标则完全不同。它面向的是大宽表、大批量写入、大范围扫描、多维聚合。这和安全日志的查询模式高度匹配。
简单说,如果你的需求是“频繁修改一条业务数据”,ClickHouse 不一定合适;但如果你的需求是“每天写入大量日志,并且经常按时间、主机、IP、端口、类型做统计分析”,ClickHouse 就非常合适。
三、列式存储:安全日志天然适合按列分析
ClickHouse 最大的特点之一是列式存储。
传统行式数据库会把一整行数据连续存储,比如一条日志里有时间、主机 ID、源 IP、目标 IP、端口、协议、状态、告警类型、详情等字段。行式存储适合一次读取完整的一行数据。
但安全分析中,很多查询并不需要读取整行。例如我们只是想统计某个时间段内不同告警类型的数量,真正需要的可能只有三个字段:时间、告警类型、数量。日志详情、请求体、扩展字段等大字段并不需要参与计算。
列式存储的优势就在这里:查询需要哪些列,就读取哪些列。
这会带来两个明显好处。
第一,减少不必要的 IO。
如果一张日志表有几十个字段,但某次查询只用到 5 个字段,ClickHouse 只需要读取相关列,而不是把整行都读出来。这对海量日志分析非常重要。
第二,压缩率更高。
同一列的数据类型和取值往往比较相似,例如协议字段可能只有 TCP、UDP、ICMP,告警等级可能只有 low、medium、high、critical,状态字段可能只有 success、failed。相似数据放在一起,更容易压缩。对于安全日志这种字段重复度较高的数据,ClickHouse 的列式压缩能显著降低存储成本。
这也是为什么很多日志场景使用 ClickHouse 后,存储空间会比传统方案更低。
四、MergeTree:适合海量日志的核心表引擎
ClickHouse 中最常用的表引擎是 MergeTree 系列。安全日志分析一般也会基于 MergeTree 或 ReplicatedMergeTree 来设计表。
MergeTree 的核心特点可以概括为:追加写入、分区存储、后台合并、按排序键组织数据。
对于安全日志来说,这些特性非常实用。
日志通常是按时间不断追加的,所以 ClickHouse 可以持续写入新数据。写入时,数据会形成一个个数据分片,后续由后台线程进行合并。这个机制很适合高吞吐写入场景。
同时,MergeTree 支持分区。安全日志一般会按日期分区,比如按天或按月分区。这样做的好处是:
- 查询最近一天、最近七天的数据时,只扫描相关分区;
- 删除历史数据时,可以直接删除过期分区;
- 冷热数据管理更简单;
- 降低全表扫描压力。
例如安全日志通常会保留 30 天、90 天或 180 天。使用 ClickHouse 时,可以通过 TTL 或分区管理机制,自动清理过期日志,避免存储无限增长。
五、ORDER BY 排序键:决定查询性能的关键设计
在 ClickHouse 中,ORDER BY 不是传统数据库里“查询结果排序”的意思,而是表数据在磁盘上的物理组织方式。排序键设计得好,查询性能会非常明显地提升;设计得不好,ClickHouse 也可能退化成大范围扫描。
安全日志的排序键一般要围绕最常见的过滤条件来设计。
例如一张主机安全事件表,常见查询条件是时间、agent_id、event_type,那么可以考虑类似这样的排序键:
ORDER BY (event_date, agent_id, event_type, event_time)
如果是网络流量日志,常见查询条件可能是时间、源 IP、目标 IP、端口、协议,那么排序键可以围绕这些字段设计:
ORDER BY (event_date, src_ip, dst_ip, dst_port, protocol, event_time)
当然,真实设计不能机械套用,而要看查询模式。一般原则是:
- 时间字段通常要靠前,因为大多数日志查询都有时间范围;
- 高频过滤字段应该放进排序键;
- 基数字段要谨慎选择,不能只看字段是否常用,还要看过滤效果;
- 排序键不是越长越好,过长会增加写入和合并成本;
- 如果经常按 agent_id 查询单主机日志,可以把 agent_id 放在靠前位置。
安全日志系统里,表结构和排序键设计往往比“是否使用 ClickHouse”本身更重要。同样是 ClickHouse,表设计不同,查询性能可能差很多。
六、低基数字段优化:LowCardinality 很适合安全枚举字段
安全日志中有很多枚举类字段,例如:
- protocol:TCP、UDP、ICMP;
- action:allow、deny、drop;
- risk_level:low、medium、high、critical;
- event_type:login_failed、port_scan、baseline_risk、malware_detected;
- os_type:linux、windows;
- asset_type:host、container、process、service。
这类字段的特点是:总数据量很大,但字段取值种类有限。ClickHouse 提供了 LowCardinality 类型,非常适合这种场景。
LowCardinality 可以简单理解为字典编码。比如某一列原本有大量重复字符串:
TCP、TCP、UDP、TCP、ICMP、UDP……
ClickHouse 可以把它转成字典:
0 = TCP,1 = UDP,2 = ICMP
真实数据中只存 0、1、2 这样的编号。这样既减少存储空间,也能提升 group by、过滤等操作的性能。
在安全日志表设计中,对低基数字符串字段使用 LowCardinality(String),通常是一个比较有效的优化手段。
七、聚合能力强:适合告警统计、趋势分析和 TopN 查询
安全日志分析离不开聚合。
例如:
SELECT
event_type,
count() AS cnt
FROM security_event
WHERE event_time >= now() - INTERVAL 1 DAY
GROUP BY event_type
ORDER BY cnt DESC;
这个查询可以统计最近一天不同事件类型的数量。
再比如统计 TopN 源 IP:
SELECT
src_ip,
count() AS cnt
FROM network_flow
WHERE event_time >= now() - INTERVAL 1 HOUR
GROUP BY src_ip
ORDER BY cnt DESC
LIMIT 10;
这类查询在安全运营中非常常见。ClickHouse 对 count、sum、avg、group by、order by、topN 等分析类查询非常友好,尤其是在大数据量场景下优势明显。
安全平台里经常需要做趋势图,例如:
- 每小时告警数量趋势;
- 每天高危风险数量变化;
- 不同业务组的风险分布;
- 不同主机的外联次数排行;
- 端口扫描来源 TopN;
- 登录失败次数统计。
这些都是典型 OLAP 查询。ClickHouse 正是为这类场景设计的。
八、高吞吐写入:适合接入 Kafka 构建日志链路
安全日志系统通常不是单点写入,而是多个 Agent、采集器、Filebeat、Logstash 或 Flink 等组件持续写入。为了削峰和解耦,常见架构是:
Agent / Filebeat → Kafka → ClickHouse
Kafka 负责缓冲和削峰,ClickHouse 负责最终存储和分析。
这样设计有几个好处。
第一,降低采集端和存储端的耦合。
采集端只需要把日志写入 Kafka,不需要直接依赖 ClickHouse 的可用性。如果 ClickHouse 短时间写入变慢,Kafka 可以先承接数据,避免采集端直接阻塞或丢数据。
第二,应对高峰流量。
安全日志常常存在突发流量,比如扫描、攻击、批量基线检查、资产同步等场景,会导致某一时间段日志量突然增加。Kafka 可以作为缓冲层,ClickHouse 消费端再根据自身能力批量写入。
第三,方便扩展实时计算。
如果后续需要引入 Flink 做实时告警、窗口统计、白名单过滤、规则匹配,也可以从 Kafka 直接消费数据。ClickHouse 则继续承担历史明细存储和离线分析能力。
ClickHouse 本身也支持较高吞吐的批量写入。实践中,不建议一条一条写入 ClickHouse,而是应该批量写入。批量越合理,写入性能越稳定,也能减少小 part 过多带来的后台 merge 压力。
九、相比 Elasticsearch,ClickHouse 的优势在哪里?
很多人会问:日志分析不是常用 Elasticsearch 吗?为什么还要用 ClickHouse?
这个问题不能简单地说谁取代谁,而要看场景。
Elasticsearch 的强项是全文检索、倒排索引、模糊搜索、日志检索体验。如果你要在海量日志中搜索某个关键字、某段异常堆栈、某个请求内容,Elasticsearch 很合适。
但安全日志分析很多时候不是全文搜索,而是结构化分析。比如按 IP、端口、协议、主机、告警类型、时间窗口做聚合统计。这个时候 ClickHouse 的列式存储、压缩、向量化执行、聚合性能和存储成本优势就会更明显。
可以简单理解为:
- Elasticsearch 更偏搜索引擎;
- ClickHouse 更偏分析数据库;
- 如果主要需求是“查关键字”,ES 更合适;
- 如果主要需求是“做统计分析”,ClickHouse 更合适。
在安全平台中,两者也可以组合使用。比如原始日志和全文检索放 ES,结构化事件和聚合分析放 ClickHouse。但如果日志已经是结构化数据,并且主要用于报表、趋势、聚合、TopN、风险分析,那么 ClickHouse 往往是更高性价比的选择。
十、ClickHouse 在安全日志分析中的典型应用场景
ClickHouse 可以支撑很多安全场景。
1. 网络流量分析
网络流量日志通常包含源 IP、目标 IP、源端口、目标端口、协议、方向、字节数、包数、连接状态、时间等字段。
基于 ClickHouse,可以快速分析:
- 某台主机最近访问了哪些外部 IP;
- 某个端口被哪些主机访问;
- 是否存在异常高频连接;
- 是否存在端口扫描行为;
- 不同业务组之间的访问关系;
- 出入方向流量趋势。
这类查询大多是结构化过滤和聚合,非常适合 ClickHouse。
2. 告警事件分析
告警日志通常包含 agent_id、event_type、risk_level、rule_id、src_ip、dst_ip、status、event_time 等字段。
ClickHouse 可以用于:
- 统计高危告警数量;
- 查询某个规则的触发趋势;
- 分析告警来源 TopN;
- 对比不同业务组的风险分布;
- 统计某台主机的历史告警变化。
对于安全运营平台来说,这些能力可以直接支撑告警看板和风险报表。
3. 基线检查结果分析
基线检查通常会产生大量主机配置检测结果,例如弱口令、权限配置、服务风险、端口开放、系统参数等。
这些数据也很适合放入 ClickHouse 做分析:
- 哪类基线风险最多;
- 哪些主机长期存在风险;
- 某个检查项的通过率趋势;
- 不同操作系统的风险分布;
- 修复前后风险数量变化。
这类数据也符合“写多改少、按时间分析、按维度聚合”的特点。
4. 资产指纹与行为分析
资产指纹包括主机、进程、端口、服务、容器、软件、内核版本等信息。虽然部分资产数据会更新,但每次采集结果也可以作为快照存储,用于历史对比。
ClickHouse 可以分析:
- 某类软件的版本分布;
- 高危版本资产数量;
- 暴露端口变化趋势;
- 容器和进程变化情况;
- 某个业务组的资产风险画像。
这类分析对安全治理和资产管理都很有价值。
十一、使用 ClickHouse 时需要注意的问题
ClickHouse 很强,但并不是“用了就一定快”。在安全日志场景中,至少要注意几个问题。
1. 不要一条一条写入
ClickHouse 适合批量写入。如果每条日志都单独 insert,会产生大量小文件和小 part,影响后台合并,最终拖慢系统。正确做法是通过批量写入、Kafka Buffer、批量消费等方式控制写入频率和批大小。
2. 分区不能太细
很多人会误以为分区越细越好。实际上,分区过细会导致元数据和小 part 数量增加,反而影响性能。安全日志一般按天或按月分区比较常见,具体要看数据量和查询周期。
3. ORDER BY 要根据查询模式设计
ClickHouse 的排序键设计非常重要。如果大多数查询都是按 agent_id 和时间查,但排序键完全没有 agent_id,那么查询性能可能不理想。建表前应该先梳理最常见的查询条件,再设计排序键。
4. 控制字段类型
安全日志字段很多,如果全部使用 String,会增加存储和计算成本。可以根据实际情况使用 UInt32、UInt64、IPv4、IPv6、DateTime、Enum、LowCardinality 等更合适的类型。
例如 IP 地址可以考虑使用 IPv4 类型,时间字段使用 DateTime,低基数字段使用 LowCardinality(String)。字段类型设计合理,存储和查询都会更好。
5. 明确它不是事务数据库
ClickHouse 不适合做高频更新、事务处理、复杂 OLTP 业务。它适合作为日志分析库,而不是替代 MySQL、PostgreSQL 这类业务数据库。
在安全平台中,一种常见做法是:
- MySQL 存配置、规则、用户、任务、策略等业务数据;
- Redis 做缓存、限流、任务状态;
- Kafka 做日志缓冲和削峰;
- ClickHouse 存安全日志和分析数据;
- Flink 做实时计算和复杂流式告警。
不同组件承担不同角色,系统会更加清晰。
十二、一个推荐的安全日志架构
一个比较典型的安全日志分析链路可以这样设计:
Agent / Plugin / Filebeat
↓
Kafka
↓
Flink / Consumer
↓
ClickHouse
↓
API Server
↓
安全运营平台 / 告警看板 / 报表分析
在这个架构中:
Agent 或 Filebeat 负责采集主机日志、流量日志、基线结果、资产信息等数据。
Kafka 负责削峰、缓冲和解耦,避免采集端直接冲击后端存储。
Flink 或普通 Consumer 可以进行数据清洗、格式转换、白名单过滤、规则匹配、字段补全等处理。
ClickHouse 负责存储结构化安全日志,并提供高性能查询分析能力。
API Server 对外提供查询接口,前端平台基于这些接口展示告警趋势、风险分布、资产画像和访问关系。
这个架构的关键点是:不要把所有事情都压到一个组件上。Kafka 负责削峰,Flink 负责流式计算,ClickHouse 负责分析查询,MySQL 负责业务配置。每个组件职责清楚,系统才容易扩展和维护。
十三、总结
ClickHouse 适合安全日志分析,本质原因不是“它很火”,而是它的设计模型和安全日志的业务特征高度匹配。
安全日志通常具备数据量大、持续写入、修改少、时间范围查询多、多维聚合多、报表分析多等特点。而 ClickHouse 的列式存储、数据压缩、MergeTree 引擎、分区机制、排序键、向量化执行和强聚合能力,正好适合解决这些问题。
如果你的安全平台主要需求是全文检索,Elasticsearch 依然有价值;但如果你的核心需求是对结构化安全日志做统计、聚合、趋势分析、TopN 排行、风险报表和历史追溯,那么 ClickHouse 往往是一个更合适、更高性能、也更具成本优势的选择。
对于安全日志平台来说,ClickHouse 不是简单的“日志存储库”,而是一个面向安全数据分析的高性能 OLAP 引擎。用得好,它可以支撑从日志检索、告警分析、风险趋势,到资产画像和安全运营看板的一整套数据分析能力。