使用kafka传递大文件时的配置

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

针对这个问题,有以下几个建议:

  1.   最好的方法是不直接传送这些大的数据。如果有共享存储,如NAS, HDFS, S3等,可以把这些大的文件存放到共享存储,然后使用Kafka来传送文件的位置信息。
  2.   第二个方法是,将大的消息数据切片或切块,在生产端将数据切片为10K大小,使用分区主键确保一个大消息的所有部分会被发送到同一个kafka分区(这样每一部分的拆分顺序得以保留),如此以来,当消费端使用时会将这些部分重新还原为原始的消息。
  3.   第三,Kafka的生产端可以压缩消息,如果原始消息是XML,当通过压缩之后,消息可能会变得不那么大。在生产端的配置参数中使用compression.codec和commpressed.topics可以开启压缩功能,压缩算法可以使用GZip或Snappy。

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

broker端

  • 配置文件需要配置的参数
  1. message.max.bytes : kafka 会接收单个消息size的最大限制, 默认为1M左右。如果producer发送比这个大的消息,kafka默认会丢掉。producer可以从callback函数中获得错误码:10。
  2. log.segment.bytes : kafka数据文件的大小。默认为1G, 需要确保此值大于一个消息的最大大小。
  3. replica.fetch.max.bytes : broker可复制的消息的最大字节数, 默认为1M。这个值应该比message.max.bytes大,否则broker会接收此消息,但无法将此消息复制出去,从而造成数据丢失。
  • bin目录下的kafka-run-class.sh中需要配置的参数
    kafka是由scala和java编写的。所以需要调一些jvm的参数。java的内存分为堆内内存和堆外内存。
  1. -Xms2048m, -Xmx2048m,设置的是堆内内存。-Xms是初始可用的最大堆内内存。-Xmx设置的是最大可用的堆内内存。二者设置成一样是因为效率问题,可以让jvm少做一些运算。如果这两个参数设置的太小,kafka会出现java.lang.OutOfMemoryError: Java heap space的错误。

  2. --XX:MaxDirectMemorySize=8192m。这个参数配置的太小,kafka会出现java.lang.OutOfMemoryError: Direct buffer memory的错误。 因为kafka的网络IO使用了java的nio中的DirectMemory的方式,而这个申请的是堆外内存。

    至于kafka的什么组件的哪些方法用了堆内内存还是堆外内存,还有用多少,我不清楚,没有学过java,也没看过kafka源码。只是碰到了这个问题,然后记录一下。

producer端

  1. message.max.bytes, 要设置大于发送最大数据的大小,否则会produce失败。

consumer端

  1. fetch.message.max.bytes (默认 1MB) – 消费者能读取的最大消息。这个值应该大于或等于message.max.bytes。

内存方面需要考虑的问题

  • 有一段这样的描述 Brokers allocate a buffer the size of replica.fetch.max.bytes for each partition they replicate. If replica.fetch.max.bytes is set to 1 MiB, and you have 1000 partitions, about 1 GiB of RAM is required. Ensure that the number of partitions multiplied by the size of the largest message does not exceed available memory.
    The same consideration applies for the consumer fetch.message.max.bytes setting. Ensure that you have enough memory for the largest message for each partition the consumer replicates. With larger messages, you might need to use fewer partitions or provide more RAM.
  • Brokers会为每个分区分配replica.fetch.max.bytes参数指定的内存空间,假设replica.fetch.max.bytes=1M,且有1000个分区,则需要差不多1G的内存,确保 分区数*最大的消息不会超过服务器的内存,否则会报OOM错误。同样地,消费端的fetch.message.max.bytes指定了最大消息需要的内存空间,同样,分区数*最大需要内存空间 不能超过服务器的内存。所以,如果你有大的消息要传送,则在内存一定的情况下,只能使用较少的分区数或者使用更大内存的服务器。

一些坑

  • 如果一个消息需要的处理时间很长,broker会认为consumer已经挂了,把partition分配给其他的consumer,然后循环往复, 这条record永远没法消费。方法是增加max.poll.interval.ms 参数。关于此参数的一些讨论:
    https://stackoverflow.com/questions/39730126/difference-between-session-timeout-ms-and-max-poll-interval-ms-for-kafka-0-10-0
    1. 当开启auto commit时,这一次poll得到消息对应的offset其实是下一次调用poll时再提交的。即使过了auto.commit.interval.ms也不会提交。关于此参数的一些讨论:
      https://stackoverflow.com/questions/38230862/need-clarification-about-kafka-auto-commit-and-auto-commit-interval-ms

性能调优

https://www.cnblogs.com/SpeakSoftlyLove/p/6511547.html
https://blog.csdn.net/vegetable_bird_001/article/details/51858915

以上内容参考资料:

  • kafka的一些概念
    http://f.dataguru.cn/thread-730782-1-1.html
    https://www.cnblogs.com/huxi2b/p/6223228.html
  • kafka jvm 配置
    https://blog.csdn.net/chen88358323/article/details/51824232
    https://blog.csdn.net/xzj9581/article/details/72866225
  • kafka 内存考虑
    https://www.cloudera.com/documentation/kafka/latest/topics/kafka_performance.html#concept_exp_hzk_br__d22306e79
    http://www.cnblogs.com/doubletree/p/4264969.html
    http://www.voidcn.com/article/p-zmwswtfy-bbz.html
    kafka的复制
    https://blog.csdn.net/lizhitao/article/details/51718185
  • kafka和DirectMemory的关系
    http://www.360doc.com/content/13/0502/23/7669533_282552666.shtml
  • java的nio和内存管理介绍
    http://www.importnew.com/17781.html
    https://blog.csdn.net/flyineagle/article/details/1399554
    https://blog.csdn.net/evan_man/article/details/509105
    http://www.importnew.com/21463.html42
    http://blog.chinaunix.net/uid-26863299-id-3559878.html
    https://blog.csdn.net/u010003835/article/details/52957904
  • kafka出现的问题
    https://blog.csdn.net/guoyuqi0554/article/details/48630907
    http://blog.51cto.com/navyaijm/1931962

 

你可能感兴趣的:(消息中间件)