今天,我们非常荣幸地欢迎 Dassana 的创始人兼首席执行官 Gaurav Kumar 作为嘉宾来到我们的博客。请继续阅读,了解他们为何选择 ClickHouse 构建安全数据湖,该数据湖整合了不同的数据源,以提供情境化的数据洞察。
SIEM 的挑战
近年来,由于网络风险日益增加及其对业务的影响,现代企业在安全产品方面进行了大量投资。从几乎没有可见性,到现在客户拥有了超出他们管理能力的可见性。如今,一家典型的大型企业使用十几种以上的安全技术。这些工具以各种形状和大小发出数据,使得理解数据变得更加困难。
例如,如果您被要求创建一个简单的管理仪表板,以显示各个业务部门的网络安全态势,您将如何着手?也许您想展示每个业务部门解决安全问题所需的时间(平均修复时间)?如何按 SLA 违规对业务部门进行排名?
在上面的截图中,Dassana 提供了一个有趣的洞察:中等严重程度问题的 SLA 违规出现激增。我们还可以看到哪个团队可能对此负责(财务团队)。Dassana 中的所有可视化都是向下钻取的,因此我们可以找出根本原因。如果没有 Dassana,安全团队将花费无数小时从不同来源获取数据并对其进行标准化。
如今,这些看似简单的问题通常需要编写复杂的 SIEM 查询才能解答(如果您幸运的话,所有数据都会被发送到 SIEM)。但是,即使是现代 SIEM 也是为不可变的时间序列事件数据(例如日志)而设计的。但是安全数据不仅仅是日志。例如,警报的状态可以是“打开”或“关闭”。假设您想找出有多少警报处于“打开”状态,您将如何着手?如果警报在一小时前处于“打开”状态,并且您将该事件发送到 SIEM,但现在警报状态已更改为“关闭”,您可以向 SIEM 发送更新请求,将警报状态从“打开”更新为“关闭”吗?当然,您不能,因为它被称为不可变是有原因的。因此,解决此问题的方法是重新插入更新后的数据,然后仅查询最新的数据。这些被称为最后点查询,并且在诸如 SIEM 之类的仅追加系统上运行时非常臭名昭著。
不仅安全数据的基本“可变”性质使 SIEM 难以操作,而且 SIEM 公司也停止了创新和投资来解决数据标准化等基本问题。AWS 称为“账户”ID 的东西,GCP 称为“项目”ID,Azure 称为“订阅”ID。如果我们能够标准化这些东西并将其称为“AssetContainerId”之类的名称,那岂不是很棒?这样,如果系统支持 SQL,您就可以编写如下查询 -
select count(*) as count,assetContainerID from findings where status='open' group by assetContainerID
在上面的示例中,我们显示了按标准化资产类型分组的资产计数。
那个梦想就是 Dassana。Dassana 从 CSPM 工具、IDS 等各种安全来源摄取数据并对其进行标准化 - 这使您可以以无模式的方式查询和可视化数据,这一切都归功于 ClickHouse 的强大功能。
我们为什么选择 ClickHouse
在最终选择 ClickHouse 之前,我们评估了十几个以上不同的 Big Data 系统。在 ClickHouse 提供的灵活性方面,没有哪个系统能与 ClickHouse 相提并论。具体而言,以下功能和架构优势征服了我们:
- 不同的表引擎使我们能够以适合用例的格式存储数据。
- 能够使用异步插入频繁插入数据。大多数大数据系统都强制您批量处理数据,这会在应用程序端增加很多复杂性。
- 内置的会计系统,用于跟踪查询成本,例如读取的行数等。
- 能够自动将数据移动到不同的存储层。这是数据归档的基本功能,内置存储层系统为我们节省了宝贵的开发时间。更锦上添花的是,ClickHouse 还支持行级别和列级别的 TTL(生存时间)。
- 高级外部字典选项,例如从 Postgres 数据库和 HTTP 服务器填充(和刷新)字典的能力。
作为一家种子轮初创公司,我们还详细评估了成本节省,并发现 ClickHouse 的成本仅为其他大数据系统成本的一小部分。
Dassana 如何使用 ClickHouse
当我们刚开始时,在底层,Dassana 大量使用了 ReplacingMergeTree 表引擎来存储可变数据。当需要更新发现(警报)的状态时,我们为同一警报插入一个新行,其中包含更新后的状态值,并让表引擎处理重复数据删除逻辑。但是,当我们想要提供近乎实时的重复数据删除结果时,这并没有解决问题。这就是 AggregatingMergeTree 与物化视图等高级功能发挥作用的地方。
如果您想知道数据是否存储了两次,一次在 ReplacingMergeTree 中,另一次在 AggregatingMergeTree 中,答案是否定的,这要归功于 ClickHouse 的 TTL 功能。
为了查询重复数据,我们使用了“group by”聚合查询。虽然这种方法在一段时间内有效,但随着我们数据的增长,我们开始遇到性能问题。您可以在此处阅读有关此重复数据删除方法的更多信息:用于 Upsert 和频繁更新的行级重复数据删除策略
所有建议的方法都不适用于我们的规模,这时我们意识到了 ClickHouse 字典功能的魔力。
让我们举个例子。考虑以下架构
CREATE TABLE default.foo (
tenant UUID,
record_id UInt64,
insert_ts UInt64,
data String,
insert_ts_dt DateTime MATERIALIZED toDateTime(divide(insert_ts,1000))
)
Engine = ReplacingMergeTree(insert_ts)
ORDER BY (tenant, record_id);
在这里,record_id
是我们想要查询重复数据删除数据的唯一“资产 ID”或实体 ID。“data”只是 record_id
的任意值。
现在,让我们创建一个像这样的字典
CREATE OR REPLACE DICTIONARY default.foo_last_point_dict
(
`record_id_hash` UInt64,
`insert_ts` UInt64
)
PRIMARY KEY record_id_hash
SOURCE(CLICKHOUSE(
QUERY '
SELECT cityHash64(tenant, record_id) as record_id_hash, max(insert_ts)
FROM table_x
WHERE {condition}
GROUP BY record_id_hash
ORDER BY record_id_hash
'
update_field 'insert_ts_dt'
update_lag 120
))
LIFETIME(5)
LAYOUT(SPARSE_HASHED(PREALLOCATE 0));
这里最重要的一点是查询
SELECT cityHash64(tenant, record_id) as record_id_hash, max(insert_ts)
FROM table_x
WHERE {condition}
GROUP BY record_id_hash
ORDER BY record_id_hash
此查询由 ClickHouse 根据 LIFETIME(上面为 5 秒)定期运行。通过 update_field
配置的 insert_ts_dt
的值被注入到 WHERE
子句中,以确定返回的数据。此查询返回用于填充字典的每个 record_id_hash
的最大 insert_ts
。要查询数据,我们运行如下 SQL 查询
SELECT * FROM foo
WHERE equals(insert_ts, dictGet('default.foo_last_point_dict, 'insert_ts', cityHash64(tenant, record_id)))
此查询选择主表中的行,其中 insert_ts
与字典中最后一点(最新)的值相同。
与任何系统一样,总复杂度保持不变 - 您可以随意调整它。在这种情况下,我们想要出色的性能,但它带来了以下必须注意的挑战:
- 如果
record_id
的基数非常高,则内存消耗会更高。幸运的是,我们发现我们可以将数亿个资产(不同的record_id
)数据存储在 32GB RAM 的机器上。 - 在 5 秒(字典加载频率)的短时间内,查询将匹配陈旧数据。这在我们的准确性预算范围内,因为无论如何数据都是以流式方式加载的,并且我们用例的大多数分析查询都是关于趋势和近似值。
值得一提的是,我们也尝试过“Join”表引擎,但发现我们基于字典的方法性能更高。
经验教训
虽然这篇文章向您展示了 ClickHouse 的一些强大功能,但我们也想强调我们的一些经验教训。ClickHouse 以其所有的荣耀和力量,是一种需要谨慎和注重细节才能驾驭的力量。我们的一些经验教训是:
- 生产环境对等性。您很可能在 Intel CPU 上运行 ClickHouse。不要在 Apple Silicon 上运行测试,并期望在 Intel CPU 上一切都相同。在所有 ClickHouse 构建版本中,Intel 构建版本是最稳定的。同样,尝试为测试集群分配与生产集群可用的资源量相同的资源量。这听起来可能很昂贵,但您可以在不使用测试集群时将其关闭。某些问题仅在系统大量使用时才会浮出水面。
- 不要手动管理 ClickHouse。如果您不使用 ClickHouse Cloud,那简直是一种犯罪,因为它消除了许多扩展和复制数据的复杂性。
- 不要在生产环境中使用实验性功能。这应该是显而易见的教训,但有时使用实验性功能很诱人。例如,当我们开始使用投影时,它们几乎已投入生产,但我们应该等待。等待辅助轮脱落。
关于 Dassana
我们由一群成功的连续创业者和云安全资深人士创立,正在构建一个安全数据湖,以整合不同的数据源并提供情境化的数据洞察。我们的目标是简化大规模数据访问,同时不影响性能并优化成本,使客户能够专注于战略业务优先级。
在此处了解有关 Dassana 的更多信息:这里。