ClickHouse作为OLAP分析引擎已经被广泛使用,数据的导入导出是用户面临的第一个问题。由于ClickHouse本身无法很好地支持单条大批量的写入,因此在实时同步数据方面需要借助其他服务协助。本文给出一种结合Canal+Kafka的方案,并且给出在多个MySQL实例分库分表的场景下,如何将多张MySQL数据表写入同一张ClickHouse表的方法,欢迎大家批评指正。
首先来看看我们的需求背景:
1. 实时同步多个MySQL实例数据到ClickHouse,每天规模500G,记录数目亿级别,可以接受分钟级别的同步延迟;
2. 某些数据库表存在分库分表的操作,用户需要跨MySQL实例跨数据库的表同步到ClickHouse的一张表中;
3. 现有的MySQL binlog开源组件(Canal),无法做到多张源数据表到一张目的表的映射关系。
基本原理
一、使用JDBC方式同步
1. 使用Canal组件完成binlog的解析和数据同步;
2. Canal-Server进程会伪装成MySQL的slave,使用MySQL的binlog同步协议完成数据同步;
3. Canal-Adapter进程负责从canal-server获取解析后的binlog,并且通过jdbc接口写入到ClickHouse;
优点:
1. Canal组件原生支持;
缺点:
1. Canal-Adpater写入时源表和目的表一一对应,灵活性不足;
2. 需要维护两个Canal组件进程;
二、Kafka+ClickHouse物化视图方式同步
1. Canal-Server完成binlog的解析,并且将解析后的json写入Kafka;
2. Canal-Server可以根据正则表达式过滤数据库和表名,并且根据规则写入Kafka的topic;
3. ClickHouse使用KafkaEngine和Materialized View完成消息消费,并写入本地表;
优点:
1. Kafka支持水平扩展,可以根据数据规模调整partition数目;
2. Kafka引入后将写入请求合并,防止ClickHouse生成大量的小文件,从而影响查询性能;
3. Canal-Server支持规则过滤,可以灵活配置上游的MySQL实例的数据库名和表名,并且指明写入的Kafka topic名称;
缺点:
1. 需要维护Kafka和配置规则;
2. ClickHouse需要新建相关的视图、Kafka Engine的外表等;