我已经读过this,但仍然有疑问。我只有一个具有16 GB RAM,4个核心和100 GB磁盘的VM,只有ClickHouse和一个轻量级的Web api可以在上面运行。
我正在将泄漏的凭据存储在数据库中
CREATE TABLE credential (
user String,
domain String,
password String,
first_seen Date,
leaks Array(UInt64)
) ENGINE ReplacingMergeTree
PARTITION BY first_seen
ORDER BY user, domain, password, first_seen
某些凭证(在一个文件中或在多个文件中)多次出现。
我的长期目标是:
-插入数据库中已有的凭据时,我想保留较小的first_seen
并将新的泄漏ID添加到字段leaks
。
根据the documentation,我已经尝试过ReplacingMergeTree引擎,插入两次相同的数据($ cat "data.csv" | clickhouse-client --query 'INSERT INTO credential FORMAT CSV'
),然后执行OPTIMIZE TABLE credential
来强制替换引擎执行其异步工作。什么也没发生,数据在数据库中是两次。
所以我想知道:
-我对ReplacecingMergeTree引擎怀念什么?
-OPTIMIZE
的工作方式,为什么它没有达到我的期望?
-是否有真正的解决方案来避免在ClickHouse的单个实例上复制数据?
我已经尝试过手动进行。我的问题是在数据库中存储了45亿条记录,并且使用以下查询来识别100k条目样本中的重复项几乎需要5分钟:SELECT DISTINCT user, domain, password, count() as c FROM credential WHERE has(leaks, 0) GROUP BY user, domain, password HAVING c > 1
此查询显然不适用于4.5b条目,因为我不这样做有足够的内存。
任何想法都会尝试。
答案 0 :(得分:1)
这里发生了多件事:
您没有为表引擎提供版本。这里的问题是,Clickhouse无法找到最应该替换的行。 我建议您使用ReplacingMergeTree的“ version”参数,因为它允许您以数字形式提供增量版本,或者,如果它对您更有效,则使用当前的DateTime(最后一个DateTime总是获胜)
< / li>您绝不应该设计解决方案来要求调用OPTIMIZE
以使您的数据在结果集中保持一致,这不是为此而设计的。
Clickhouse始终允许您编写查询,以提供(最终)一致性,而无需事先使用OPTIMIZE
。
避免OPTIMIZE的原因,除了在数据库上确实太慢和繁重之外,您还可能陷入竞争状态,在这种情况下,数据库的其他客户端(或复制Clickhouse节点)可能会使OPTIMIZE完成与SELECT之间的数据无效。完成。
底线,作为解决方案:
因此,您应该在此处添加版本列。然后,在插入行时,插入当前时间戳作为版本。
然后,为每一行只选择结果中版本最高的那一行,这样您就不必依赖OPTIMIZE来处理garbage collection
以外的任何内容。