当Clickhouse Distributed遇到ReplacingMergeTree
问题描述
由于业务限制,数据库中存在大量重复数据,故采用了ReplacingMergeTree表引擎,但后台始终没有进行数据合并。
-
建表语句
1CREATE TABLE xxxx.xxxx ON CLUSTER xxx 2( 3 user_id String, 4 name String, 5 ) 6ENGINE = ReplacingMergeTree() 7ORDER BY (user_id); 8 9CREATE TABLE xxxx.xxxx ON CLUSTER xxx as xxxx.xxxx ENGINE = Distributed('xxxx', 'xxxx', xxxx, rand());
-
查询数据是否有重复
1SELECT COUNT() FROM xxxx.xxxx 241905623 3 4SELECT COUNT(x) FROM (SELECT x FROM xxxx.xxxx GROUP BY [oder_key]) 541705616
-
手动执行数据合并,也没有去除重复数据
1OPTIMIZE TABLE ~ ON CLUSTER ~ FINAL 2 3SELECT COUNT() FROM xxxx.xxxx 441905623
思考
分布式表存储数据采用分片存储,如6条数据存3个节点,则每个节点存储2条数据。当发生数据合并时,可能只合并当前节点的数据。最终也在这https://stackoverflow.com/questions/62616949/deduplication-in-distributed-clickhouse-table,验证了这一猜想。
解决
创建分布式表时,不使用rand()进行随机分布,使用user_id进行分片,使相同user_id的数据在写入时落在相同的节点。
1CREATE TABLE xxxx.xxxx ON CLUSTER xxx as xxxx.xxxx ENGINE = Distributed('xxxx', 'xxxx', xxxx, user_id);