背景
根据公司业务,我们需要使用 kafka+clickhouse搭建一套监控数据的存储系统。kafka和clickhouse均为三节点集群。
现象
在测试过程中,数据源数据进行了多次调整,数据字段进行过调整。在某次修改接口、字段修改后,kafka有数据,但数据始终无法存入到clickhouse。
第一次排查
通过比对kafka数据,发现kafka数据字段数据类型与clickhouse定义的表结构字段不一致(类型不一致,clickhouse定义为int型,而kafka字段为float)。打回接口重新对应字段。接口后续进行了修改,将所有字段都改成了要求的类型,kafka中能看到数据已经正确,但是clickhouse仍然无法写入数据,最后数据的记录,仍然是数据出错前的最后一条。
测试重现
建立了测试用表,手动写数据。先写入几条正常数据,均能正常入表。然后将数据类型进行修改,数据无法写入。之后再恢复正常数据,数据无法入表。
初步结论
当kafka的数据错误的时候,clickhouse配置的消费管道会阻塞,导致后续数据无法继续消费,因此就算数据恢复了也没有办法继续入表。
解决方案
建了新的topic和新表,正确数据写到新的topic中,能正常入表。但是这样,之前的数据就全丢了,虽然写个小程序慢慢的补数据,不过这对生产的影响是很大的。还好我们目前只是在开发环境,损失较小。因此对数据源端提了要求,不管原始数据怎么变,数据提供端必须确保数据的正确性,才能往kafka写。
关于解决方案
我尝试过手动消费掉那些错误数据,然后重启clickhouse,企图clickhouse能跳过那些错误数据(用的同样的group),但是并没有生效。所以对于clickhouse消费数据的原理很好奇,为什么跳不过那些数据?如果有大佬看到我的文章能给予讲解,小生不胜感激!
测试过程中遇到的有意思的点
在测试重现的时候发现了一点很有意思:
如果clickhouse定义的字段是int类型的,但是kafka消息字段是string类型的整形数字,则仍然可以入表。