案例分析

处理kafka consumer的程序的时候,发现如下错误:

  1. ERROR [2017-01-12 07:16:02,466] com.flow.kafka.consumer.main.KafkaConsumer: Unexpected Error Occurred
  2. ! kafka.common.MessageSizeTooLargeException: Found a message larger than the maximum fetch size of this consumer on topic codeTopic partition 3 at fetch offset 94. Increase the fetch size, or decrease the maximum message size the broker will allow.
  3. ! at kafka.consumer.ConsumerIterator.makeNext(ConsumerIterator.scala:91) ~[pip-kafka-consumer.jar:na]
  4. ! at kafka.consumer.ConsumerIterator.makeNext(ConsumerIterator.scala:33) ~[pip-kafka-consumer.jar:na]
  5. ! at kafka.utils.IteratorTemplate.maybeComputeNext(IteratorTemplate.scala:66) ~[pip-kafka-consumer.jar:na]
  6. ! at kafka.utils.IteratorTemplate.hasNext(IteratorTemplate.scala:58) ~[pip-kafka-consumer.jar:na]
  7. ! at com.flow.kafka.consumer.main.KafkaConsumer$KafkaRiverFetcher.run(KafkaConsumer.java:291) ~[original-pip-kafka-consumer.jar:na]
  8. ! at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_51]
  9. ! at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_51]
  10. ! at java.lang.Thread.run(Thread.java:744) [na:1.7.0_51]

如上log可以看出,问题就是有一个较大的消息数据在codeTopic的partition 3上,然后consumer未能消费,提示我可以减小broker允许进入的消息数据的大小,或者增大consumer程序消费数据的大小。

从log上来看一目了然,如果要解决当前问题的话,

  1. 减小broker消息体大小(设置message.max.bytes参数);
  2. 增大consumer获取数据信息大小(设置fetch.message.max.bytes参数)。默认broker消息体大小为1000000字节即为1M大小。

消费者方面:fetch.message.max.bytes——>这将决定消费者可以获取的数据大小。

broker方面:replica.fetch.max.bytes——>这将允许broker的副本发送消息在集群并确保消息被正确地复制。如果这是太小,则消息不会被复制,因此,消费者永远不会看到的消息,因为消息永远不会承诺(完全复制)。

broker方面:message.max.bytes——>可以接受数据生产者最大消息数据大小。

由我的场景来看较大的消息体已经进入到了kafka,我这里要解决这个问题,只需要增加consumer的fetch.message.max.bytes数值就好。我单独把那条数据消费出来,写到一个文件中发现那条消息大小为1.5M左右,为了避免再次发生这种问题我把consumer程序的fetch.message.max.bytes参数调节为了3072000即为3M,重启consumer程序,查看log一切正常,解决这个消费错误到此结束,下面介绍一下kafka针对大数据处理的思考。

kafka的设计初衷

Kafka设计的初衷是迅速处理小量的消息,一般10K大小的消息吞吐性能最好(可参见LinkedIn的kafka性能测试)。但有时候,我们需要处理更大的消息,比如XML文档或JSON内容,一个消息差不多有10-100M,这种情况下,Kakfa应该如何处理?

针对这个问题,可以参考如下建议:

  • 最好的方法是不直接传送这些大的数据。如果有共享存储,如NAS, HDFS, S3等,可以把这些大的文件存放到共享存储,然后使用Kafka来传送文件的位置信息。

  • 第二个方法是,将大的消息数据切片或切块,在生产端将数据切片为10K大小,使用分区主键确保一个大消息的所有部分会被发送到同一个kafka分区(这样每一部分的拆分顺序得以保留),如此以来,当消费端使用时会将这些部分重新还原为原始的消息。

  • 第三,Kafka的生产端可以压缩消息,如果原始消息是XML,当通过压缩之后,消息可能会变得不那么大。在生产端的配置参数中使用compression.codeccommpressed.topics可以开启压缩功能,压缩算法可以使用GZipSnappy

不过如果上述方法都不是你需要的,而你最终还是希望传送大的消息,那么,则可以在kafka中设置下面一些参数:

broker 配置

message.max.bytes (默认:1000000) – broker能接收消息的最大字节数,这个值应该比消费端的fetch.message.max.bytes更小才对,否则broker就会因为消费端无法使用这个消息而挂起。

log.segment.bytes (默认: 1GB) – kafka数据文件的大小,确保这个数值大于一个消息的长度。一般说来使用默认值即可(一般一个消息很难大于1G,因为这是一个消息系统,而不是文件系统)。

replica.fetch.max.bytes (默认: 1MB) – broker可复制的消息的最大字节数。这个值应该比message.max.bytes大,否则broker会接收此消息,但无法将此消息复制出去,从而造成数据丢失。

Consumer 配置

fetch.message.max.bytes (默认 1MB) – 消费者能读取的最大消息。这个值应该大于或等于message.max.bytes。所以,如果你一定要选择kafka来传送大的消息,还有些事项需要考虑。要传送大的消息,不是当出现问题之后再来考虑如何解决,而是在一开始设计的时候,就要考虑到大消息对集群和主题的影响。

性能: 根据前面提到的性能测试,kafka在消息为10K时吞吐量达到最大,更大的消息会降低吞吐量,在设计集群的容量时,尤其要考虑这点。

可用的内存和分区数:Brokers会为每个分区分配replica.fetch.max.bytes参数指定的内存空间,假设replica.fetch.max.bytes=1M,且有1000个分区,则需要差不多1G的内存,确保 分区数最大的消息不会超过服务器的内存,否则会报OOM错误。同样地,消费端的fetch.message.max.bytes指定了最大消息需要的内存空间,同样,分区数最大需要内存空间 不能超过服务器的内存。所以,如果你有大的消息要传送,则在内存一定的情况下,只能使用较少的分区数或者使用更大内存的服务器。

垃圾回收:到现在为止,我在kafka的使用中还没发现过此问题,但这应该是一个需要考虑的潜在问题。更大的消息会让GC的时间更长(因为broker需要分配更大的块),随时关注GC的日志和服务器的日志信息。如果长时间的GC导致kafka丢失了zookeeper的会话,则需要配置zookeeper.session.timeout.ms参数为更大的超时时间。

Kafka consumer处理大消息数据问题的更多相关文章

  1. 【转】解决Maxwell发送Kafka消息数据倾斜问题

    最近用Maxwell解析MySQL的Binlog,发送到Kafka进行处理,测试的时候发现一个问题,就是Kafka的Offset严重倾斜,三个partition,其中一个的offset已经快200万了 ...

  2. Flume+Kafka+Storm+Redis 大数据在线实时分析

    1.实时处理框架 即从上面的架构中我们可以看出,其由下面的几部分构成: Flume集群 Kafka集群 Storm集群 从构建实时处理系统的角度出发,我们需要做的是,如何让数据在各个不同的集群系统之间 ...

  3. kafka 0.8.2 消息消费者 consumer

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  4. IDEA kafka producer数据输出缓慢 和 kafka consumer 报错的处理

    问题1. IDEA 中Kafa_Producer程序数据输出缓慢 但不报错 问题2. Kafa_Consumer程序报错: 17/11/10 11:31:11 ERROR ReceiverTracke ...

  5. 【原创】kafka consumer源代码分析

    顾名思义,就是kafka的consumer api包. 一.ConsumerConfig.scala Kafka consumer的配置类,除了一些默认值常量及验证参数的方法之外,就是consumer ...

  6. Apache Kafka:下一代分布式消息系统

    [http://www.infoq.com/cn/articles/apache-kafka/]分布式发布-订阅消息系统. Kafka是一种快速.可扩展的.设计内在就是分布式的,分区的和可复制的提交日 ...

  7. 【转载】Apache Kafka:下一代分布式消息系统

    http://www.infoq.com/cn/articles/kafka-analysis-part-1 Kafka是由LinkedIn开发的一个分布式的消息系统,使用Scala编写,它以可水平扩 ...

  8. kafka中处理超大消息的一些考虑

    Kafka设计的初衷是迅速处理短小的消息,一般10K大小的消息吞吐性能最好(可参见LinkedIn的kafka性能测试).但有时候,我们需要处理更大的消息,比如XML文档或JSON内容,一个消息差不多 ...

  9. Kafka(分布式发布-订阅消息系统)工作流程说明

    Kafka系统架构Apache Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apache项目的一部分.Kafka是一种快速.可扩展的.设计内在就是分布式的,分区的和 ...

随机推荐

  1. HDU 3094 A tree game 树删边游戏

    叶节点SG值至0 非叶节点SG值至于它的所有子节点SG值添加1 XOR和后 #include <cstdio> #include <cstring> #include < ...

  2. Kafka spring 集成

    下载配置kafka参考该链接:http://www.cnblogs.com/super-d2/p/4534323.html pom.xml: <dependency> <groupI ...

  3. [译]Java垃圾回收器的类型

    说明:这篇文章来翻译来自于Javapapers 的Types of Java Garbage Collectors 在这部分的教程中我们将讲到可使用的四种不同类型的Java垃圾回收器.垃圾回收是Jav ...

  4. Your build host version of Xamarin.IOS (release NO.)is too recent to work with the IOS designer

    Encounted such error in VS after I update the xamarin at Mac side.Here is the solution for u to refe ...

  5. HDOJ 5063 Operation the Sequence

    注意到查询次数不超过50次,那么能够从查询位置逆回去操作,就能够发现它在最初序列的位置,再逆回去就可以求得当前查询的值,对于一组数据复杂度约为O(50*n). Operation the Sequen ...

  6. Image 对象

    <html> <body> <img id="compman" src="0387.jpg" alt="Computer ...

  7. ListNode线性表

    不常用,可以看一下实现原理 namespace UnilateralismChainTable { // 结点类 public class ListNode { public ListNode(int ...

  8. .NET:线程本地存储、调用上下文、逻辑调用上下文

    .NET:线程本地存储.调用上下文.逻辑调用上下文 目录 背景线程本地存储调用上下文逻辑调用上下文备注 背景返回目录 在多线程环境,如果需要将实例的生命周期控制在某个操作的执行期间,该如何设计?经典的 ...

  9. iOS推送服务细节回顾

    iOS推送服务细节回顾 之前在做推送功能时候,就总结过一系列证书的制作,OC代码实现和服务器搭建等经验.又过了一段时间了,前前后后对推送服务做了多次的完善和优化,有iOS客户端的,还有本地服务器端的. ...

  10. [转]ARM Pipeline

    Add r0, PC, # g_oalAddressTable - (+ 8) instruction, a lot of people had cprogramdev.com Forum asked ...