当Clickhouse Distributed遇到ReplacingMergeTree

问题描述

​ 由于业务限制,数据库中存在大量重复数据,故采用了ReplacingMergeTree表引擎,但后台始终没有进行数据合并。

  • 建表语句

    CREATE TABLE xxxx.xxxx ON CLUSTER xxx
    (
        user_id String,
        name String,
     )
    ENGINE = ReplacingMergeTree()
    ORDER BY (user_id);
    
    CREATE TABLE xxxx.xxxx ON CLUSTER xxx as xxxx.xxxx ENGINE = Distributed('xxxx', 'xxxx', xxxx, rand());
  • 查询数据是否有重复

    SELECT COUNT() FROM xxxx.xxxx
    41905623
    
    SELECT COUNT(x) FROM (SELECT x FROM xxxx.xxxx GROUP BY [oder_key]) 
    41705616
  • 手动执行数据合并,也没有去除重复数据

    OPTIMIZE TABLE ~ ON CLUSTER ~ FINAL
    
    SELECT COUNT() FROM xxxx.xxxx
    41905623

思考

​ 分布式表存储数据采用分片存储,如6条数据存3个节点,则每个节点存储2条数据。当发生数据合并时,可能只合并当前节点的数据。最终也在这https://stackoverflow.com/questions/62616949/deduplication-in-distributed-clickhouse-table,验证了这一猜想。

解决

​ 创建分布式表时,不使用rand()进行随机分布,使用user_id进行分片,使相同user_id的数据在写入时落在相同的节点。

CREATE TABLE xxxx.xxxx ON CLUSTER xxx as xxxx.xxxx ENGINE = Distributed('xxxx', 'xxxx', xxxx, user_id);