一种解决消费海量Kafka Topic时数据倾斜的方案

2022-01-08 12:47:55 浏览数 (2)

1 背景

业务上遇到了这样一个场景:

1. 需要同时从多个Kafka实例里消费数以百万计的Topic

2. 每个Topic的写流量差异很大,有的几百MB/s,有的几B/min

3. 每个分区的写流量最大 5MB/s

原来的解决方案的:

1. 用多个消费服务实例

2. 每个实例上为每个Topic起一个Kafka消费者

这个方案的问题是:

1. Kafka连接数不足:一个消费服务实例上会为所有Topic创建消费者,随着消费服务实例数量的增加,kafka连接数将成倍增加

2. 数据倾斜问题:所有分区被随机分配到消费服务实例上,无法保证各个消费服务实例上所有分区的写流量相同;经常会发生,某个实例上分区的写流量过大,机器负载极高,消费堆积

这个方案的优点是:

1. 可靠性高:所有消费服务实例上都有每个Topic的消费者,挂掉几个实例,分区会被转移到其他消费者上,消费不会受到影响

2. 简单

2 分布式消费任务协调

2.1 消费服务启动

DB里有一个表,用来维护Topic的元数据,例如分区数。

消费服务启动时从DB里随机选一行,作为起点,为Topic创建消费者,创建后把消费者数据量写入到Redis里;如果消费者数量 > 分区数 1则不再创建消费者。

冗余两个消费者既保证了可靠性,又不至于让kafka连接数过多

2.2 消费服务实例负载过高时抛出任务

1. cpu、mem有一个过高,找一个流量中等的topic,抛到Redis上

2. 抛出前,负载要持续超限一段时间(5min),防止topic频繁移动

3. 轮询(10s )check抛到es上的topic是否被取走,若取走,close本机上的consumer

4. 如果一个高负载实例持续抛出topic失败,说明全局负载过高,则告警,收到告警后扩容

2.3 消费服务实例负载较低时领取任务

1. 从Redis上领取任务,开启消费者

2.4 兜底策略

1. 消费服务定时上报消费的Topic到Redis

2. 消费服务定时检查是否所有的Topic都被消费,对于没有消费的Topic启动消费

0 人点赞