SparkStreaming消费Kafka数据的时候,当有大量初始化数据时会拖累整个streaming程序的运行,问有什么办法?
总体来说这个问题大概有两种解决思路:
1.在Spark端设置限速;
2.在Kafka端设置限速。
1.Spark端设置限速
Spark端限速的方法,主要的思路是设置不同的参数,
比如在Direct模式下设置spark.streaming.kafka.maxRatePerPartition,
receiver模式下设置spark.streaming.receiver.maxRate。
它们都是控制每秒处理的消息数。应该说目前使用Direct模式的比较多,因此你需要适当地调整spark.streaming.kafka.maxRatePerPartition值。
还有一种思路,即设置spark.streaming.dynamicAllocation.enabled=true打开动态资源分配。
2.Kafka端设置限速
回到限速,在Kafka端设置限速有两种办法:
-
设置broker端参数quota.consumer.default。比如quota.consumer.default=15728640表示将连入该broker的所有consumer的TPS降到15MB/s以下。此参数的好处在于全局生效简单易用,对broker上所有consumer都是”一视同仁“;缺陷也在于此,无法单独为个别consumer限速,故该方法在0.11.0.0版本之后已经不推荐使用。
-
通过kafka-configs命令。比如下面命令是为client.id为clientA的consumer设置限速:
$ bin/kafka-configs.sh --zookeeper localhost:2181
--alter
--add-config 'consumer_byte_rate=15728640'
--entity-type clients
--entity-name clientA
此命令只为client.id=clientA的consumer设置了限速,故在Spark端你还需要显式设置client.id,比如:
Map<String, Object> kafkaParams = new HashMap<>();
...
kafkaParams.put("client.id", "clientA");
...
JavaInputDStream<ConsumerRecord<String, String>>
stream = KafkaUtils.createDirectStream(...);
值得注意的是,在Kafka端设置的限速单位都是每秒字节数。如果你想按照每秒多少条消息进行限速还需要结合消息的平均大小来计算。