clickhouse出现数据重复问题排查
在生产环境中,偶然发现clickhouse数据表中出现重复数据,并且都是重复的两条数据,重重迷雾,疑窦重生…
建表语句如下:
CREATE TABLE test.baseinfo
(
`id` String,
`name` String,
`update_time` Date
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/test/baseinfo/{shard}',
'{replica}')
PRIMARY KEY id
ORDER BY id
SETTINGS index_granularity = 8192
这里对语句做了修改,与真实数据有出入,但基本相似。
问题一:已经有‘primary key’,为什么可以重复?
clickhouse这里的主键只是用来生成一级索引的,并没有唯一性约束这样的语义,其主要的作用是提升查询性能的,并不做数据唯一性的限制。
问题二:建表中使用的引擎是ReplicatedMergeTree,为什么重复数据没有被移除?
根据官网的描述,引擎ReplicatedMergeTree和MergeTree的区别就是该引擎会删除排序键值相同的重复项,但是很明显这里并没有起作用,这是bug?并不是,首先,数据的去重只会在数据合并期间进行,而合并在后台进行的时间并不是确定的,因此此引擎并不保证没有重复数据的出现。另外一点,也是我这里出现重复数据的原因,是该引擎是依据排序键值进行判断重复数据并删除的,而排序 order by 是在分区 partition 内排序的,所以只有重复数据出现在同一分区才会被删除,而这里并没有自定义分区键。可以使用以下sql查看数据表的分区情况。
--从system.parts中查看数据表的分区信息 select partition,name,active from system.parts p where p.table = 'table_name'
所以因为我这里没有自定义分区键,导致重复数据写入了不同的分区,所以重复数据并没有被删除。
问题三:将数据写入CH的代码有问题吗?为什么会写入重复数据?
这里的数据是从KAFKA中消费而来,写入到ClickHouse中的。于是我开始在本地测试代码,将测试数据写入到CH中,经过查询发现,数据只有一条!!!!!这说明代码将数据写入并没出现问题,并不会将一条数据写入两次。然后我再次启动程序,查询CH,出鬼了!!!每条数据都有重复!而且都是两条!于是我就彻底陷入了迷雾,到底问题出在哪???
经过思考和搜索资料,意识到问题的关键是两条,每一条都是两条,于是我果断停掉了程序,然后继续消费KAFKA中的数据,但是不写入CH,只打印出来,查询数据表后,果然,终于抓到了,这边停止将数据写入CH,但是这条数据却出现在了CH中,有另一个我不知道的程序在偷摸摸的将数据导入到CH!!!终于真相大白了!
每天进步一点点,终会积沙成塔!