Spark:从kafka获取非常大的消息

时间:2018-04-13 16:35:43

标签: java apache-spark apache-kafka

我正试图收到来自卡夫卡的火花的非常重要的信息。 但似乎spark对可以读取的消息大小有限制。 我已经在kafka配置中更改为能够消费并发送大消息但这还不够(我认为这与spark不是kafka有关)因为在使用kafka.consumer脚本时我没有任何问题显示内容消息。

也许这与spark.streaming.kafka.consumer.cache.maxCapacity有关,但我不知道如何在基于spark java的程序中设置它。

谢谢。

更新

我使用它连接到Kafka,通常args [0]是zookeeper地址,而args [1]是groupID。

if (args.length < 4) {
        System.err.println("Usage: Stream Car data <zkQuorum> <group> <topics> <numThreads>");
        System.exit(1);
    }

    SparkConf sparkConf = new SparkConf().setAppName("stream cars data");

    final JavaSparkContext jSC = new JavaSparkContext(sparkConf);
    // Creer le contexte avec une taille de batch de 2 secondes
    JavaStreamingContext jssc = new JavaStreamingContext(jSC,new Duration(2000));

    int numThreads = Integer.parseInt(args[3]);

    Map<String, Integer> topicMap = new HashMap<>();
    String[] topics = args[2].split(",");

    for (String topic: topics) {
        topicMap.put(topic, numThreads);
    }

    JavaPairReceiverInputDStream<String, String> messages =
            KafkaUtils.createStream(jssc, args[0], args[1], topicMap);

    JavaDStream<String> data = messages.map(Tuple2::_2);

这是我得到的错误

18/04/13 17:20:33 WARN scheduler.ReceiverTracker: Error reported by receiver for stream 0: Error handling message; exiting - kafka.common.MessageSizeTooLargeException: Found a message larger than the maximum fetch size of this consumer on topic Hello-Kafka partition 0 at fetch offset 3008. Increase the fetch size, or decrease the maximum message size the broker will allow.
        at kafka.consumer.ConsumerIterator.makeNext(ConsumerIterator.scala:90)
        at kafka.consumer.ConsumerIterator.makeNext(ConsumerIterator.scala:33)
        at kafka.utils.IteratorTemplate.maybeComputeNext(IteratorTemplate.scala:66)
        at kafka.utils.IteratorTemplate.hasNext(IteratorTemplate.scala:58)
        at org.apache.spark.streaming.kafka.KafkaReceiver$MessageHandler.run(KafkaInputDStream.scala:133)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

2 个答案:

答案 0 :(得分:0)

根据您使用的Kafka版本,您需要在Kafka配置文件中可用(或要创建)的consumer.properties文件中设置以下使用者配置。

适用于0.8.X或更低版本。

fetch.message.max.bytes

对于Kafka 0.9.0或更高版本,请设置

fetch.max.bytes 

根据您的应用程序找到合适的值。

EG。 fetch.max.bytes=10485760

参考thisthis

答案 1 :(得分:0)

所以我找到了解决问题的方法,事实上我在评论中说,配置文件中的文件只是示例,在说明服务器时不考虑它们。因此,包括fetch.message.max.bytes在内的所有消费者配置都需要在消费者代码中完成。

这就是我做到的:

if (args.length < 4) {
        System.err.println("Usage: Stream Car data <zkQuorum> <group> <topics> <numThreads>");
        System.exit(1);
    }

    SparkConf sparkConf = new SparkConf().setAppName("stream cars data");

    final JavaSparkContext jSC = new JavaSparkContext(sparkConf);
    // Creer le contexte avec une taille de batch de 2 secondes
    JavaStreamingContext jssc = new JavaStreamingContext(jSC,new Duration(2000));

    int numThreads = Integer.parseInt(args[3]);

    Map<String, Integer> topicMap = new HashMap<>();
    String[] topics = args[2].split(",");

    for (String topic: topics) {
        topicMap.put(topic, numThreads);
    }



    Set<String> topicsSet = new HashSet<>(Arrays.asList(topics));
    Map<String, String> kafkaParams = new HashMap<>();
    kafkaParams.put("metadata.broker.list", args[0]);
    kafkaParams.put("group.id", args[1]);
    kafkaParams.put("zookeeper.connect", args[0]);
    kafkaParams.put("fetch.message.max.bytes", "1100000000");



    JavaPairReceiverInputDStream<String, String> messages=KafkaUtils.createStream(jssc,
            String.class,
            String.class,
            StringDecoder.class,
            StringDecoder.class,
            kafkaParams,
            topicMap,MEMORY_ONLY() );


    JavaDStream<String> data = messages.map(Tuple2::_2);