如何避免ClickHouse中的数据重复

时间:2019-07-03 09:58:39

标签: clickhouse

我已经读过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条目,因为我不这样做有足够的内存。

任何想法都会尝试。

1 个答案:

答案 0 :(得分:1)

这里发生了多件事:

  • 您可以非常精细地进行分区...无论如何,您都应该按一个月的数据进行分区。现在clickhous必须扫描大量文件。
  • 您没有为表引擎提供版本。这里的问题是,Clickhouse无法找到最应该替换的行。 我建议您使用ReplacingMergeTree的“ version”参数,因为它允许您以数字形式提供增量版本,或者,如果它对您更有效,则使用当前的DateTime(最后一个DateTime总是获胜)

    < / li>
  • 您绝不应该设计解决方案来要求调用OPTIMIZE以使您的数据在结果集中保持一致,这不是为此而设计的。

Clickhouse始终允许您编写查询,以提供(最终)一致性,而无需事先使用OPTIMIZE

避免OPTIMIZE的原因,除了在数据库上确实太慢和繁重之外,您还可能陷入竞争状态,在这种情况下,数据库的其他客户端(或复制Clickhouse节点)可能会使OPTIMIZE完成与SELECT之间的数据无效。完成。

底线,作为解决方案: 因此,您应该在此处添加版本列。然后,在插入行时,插入当前时间戳作为版本。 然后,为每一行只选择结果中版本最高的那一行,这样您就不必依赖OPTIMIZE来处理garbage collection以外的任何内容。