普通方案
如图1,是大家常见的一种用法,所有CH节点参与分发数据的原因是因为大家想把唯一Key相同的数据分发到同一个节点,好做一些SQL查询。
如图2,也是常见的一种做法,就是数据存储在哪个节点无所谓,一般只算SUM、COUNT等聚合函数。如果业务可以使用该方案,非常OK,基本上无需考虑新方案了。
a. 优点:
- 所有节点都消费Kakfa,消费能力强。
- 使用成本相对较低,用户自己搞定。
- 图2 方案 也是推荐方案的一种。
b. 缺点:
- 消费、写入、查询都在同一个节点,影响查询。
- 集群基础负载高,线程间的上下文切换多。
- 图1 方案受限于节点个数,如果节点超过100个,数据交换和MergeTree的小文件合并能吃掉你大部分CPU使用率。
- 图1 方案你如果还想用多副本,你的ZK会‘爆炸’,原地起飞。
优化方案
如图3,使用几个高性能消费Kafka数据,然后分发到所有其他节点,其他节点只有LocalTable的写压力。测试后发现几个高性能节点来消费数据是OK的。
如图4,在图3的基础上支持多副本,集群规模不是特别大的情况下,zk的压力还是扛的住的。
a. 优点
- 有点‘读写分离’的意思,查询集群的基础负载会小很多,有利于提供稳定的查询服务。
- 查询集群可以直接突破100个节点,容易水平扩展。
- 消费Kafka集群的节点个数也可以根据上游的数据量进行收缩,对数据写入影响较小。
- 节点的都在干自己擅长的事情,效率更高。
- 在数据Hash的情况下,可以支持多副本表,且节点和单副本不会差太多,主要还是看ZK。
b. 缺点
- 需要独立配置几台Kafka 消费节点。
- 如果数据不需要Hash的话,当前方案比图2确实多了一些网络传输,数据合并压力。
三、参数配置
配置参数 | 默认值 | 推荐值 | 参数说明 |
---|---|---|---|
kafka_thread_per_consumer | 0 | 1 | 一个Consumer 对应一条线程,再大对数据消费意义不大 |
kafka_num_consumers | 1 | CPU核数/2 | 当前Kafka Engine表启动的Consumer数量,master分支最大值已经是和机器物理CPU核数一致了,主流分支还是最大16个。 |
kafka_max_block_size | 65536 | 1048576 | 每次从Kafka端拉取一批的最大消息数量 |
kafka_skip_broken_messages | 0 | 10 | 每批数据允许和Schema不匹配的数据条数,一般情况下用户都有脏数据。 |
四、结论
在需要使用数据Hash的场景时,我们推荐使用图3、图4方案,降低查询集群的压力,降低长期的运维成本。
参考社区PR:https://github.com/ClickHouse/ClickHouse/issues/26640