繁体   English   中英

从Kafka读取时,Spark缺少99.9%的消息

[英]Spark missing 99.9% messages while reading from Kafka

TL; DR:我的spark应用吸收了从Kafka发送的总msg中的0.1%。 我的主要怀疑者:对于每个批处理间隔(例如1秒),都会实例化新的JVM。 我正在尝试使用延迟加载的.map()转换来摄取数据。 驱动程序和执行程序代码相互穷举是否有可能在此起作用?

详细的长版:

我的事件流程如下:一个Java类,用于生成示例(.json作为字符串)数据并使用Kafka的kafka-run-class.sh脚本运行。 消息收集在kafka中,spark使用java directstream从那里读取消息。 为了简洁起见,假设我的数据生产者发送的json msg值可以为1或0,而Spark应用程序的目的是区分1和0。 数据生成器还将计数值附加到已发送的msg。

问题:在实验中,我正在从数据生成器发送10000 msgs。 我是一个传入数据的kibana仪表板,它显示9600 msg(+-0.1%,但始终可见)

Q1。 其余的400 msgs在哪里丢失了?

现在,spark(批处理间隔为1秒,并在1个线程上运行)读取这些msgs及其输出,然后在另一个可视化下将其输入相同的kibana中。

它始终读取10(或有时20)个味精。

如果读取10 msgs,则其计数值为1-10;如果读取20 msgs,则其计数值为1-10&〜3000-3010

Q2。 为什么Spark只得到10(或最多20)个味精?

我在Spark应用程序中更改了设置“ auto.offset.reset”(最小),但这并没有真正帮助。 它仅从计数1-10读取10 msgs。

Q3。 要使它从kafka主题的开始阅读,需要做些什么?

我可以想到的一件坏事是,我在.map函数中摄取了味精:

JavaDStream<String> lines = stream.map(new Function<Tuple2<String, String>, String>() {
  public String call(Tuple2<String, String> tuple2) {
  my_fn(tuple2._2().toString());
  return tuple2._2();
}

有人可以照亮窗户并减少功能吗?看到总味精的0.1%与火花有什么关系?

注意:我正在使用logstash实例从spark-> kafka,kafka-> elastic迁移数据

我需要在数据生成器脚本中操作json obj。 我正在使用maven和使用json依赖关系并且它构建良好。 但是在尝试使用kafka-run-class.sh运行该类时,它为json对象抛出了classNotFoundException。

Q4。 我该如何使用kafka-run-class方法来运行一个有阴影的jar,或者它是否需要作为独立的Java程序运行,在这种情况下,它会以与使用kafka的即装即用脚本运行时相同的速率发出味精我认为它确实需要并行化和排队以保持背压。

使用这个kafka脚本,我可以在机器上渗出1.4Mpps。

编辑:有关kafka-spark分区和代码逻辑的更多信息

图例:topic_1是生产者(脚本)的数据-> kafka topic_2是Spark-> kafka发出的数据

bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic topic_1 
          Topic:topic_1 PartitionCount:1    ReplicationFactor:1 Configs: 
          Topic: topic_1 Partition: 0   Leader: 0   Replicas: 0 Isr: 0 

curl 'localhost:9200/_cat/indices?v'
health status index          pri rep docs.count docs.deleted store.size pri.store.size 
yellow open   topic_1     5   1   11002386            0    702.1mb        702.1mb 
yellow open   topic_2     5   1       6307            0    786.4kb        786.4kb 
yellow open   .kibana         1   1          9            0       47kb        47kb

Spark,我在1个批处理程序&1个驱动程序和4GB驱动程序&执行程序内存在4个内核上的1个线程上以1秒的批处理间隔运行。在试验10M + msgs时,topic_1收到了几乎正确的数字(上述9600/10000 Q1),而topic_2可以仅收到约6k条消息关于分区,一切都在具有32GB内存和4核的同一台计算机上以独立模式进行。 我的意思是,数据生产者Kafka,ELK,火花。

Data_gen:简单的Java kafka生产者代码,以1:1的比率发送值为0或1的json字符串。 Spark_app:主qn中的代码。 my_fn()获取字符串msg,将其转换为json并查看值是0还是1

map() transformations are lazy so they don’t like to work until asked for.
I was expecting messages in a map() transformation.
put this expectation in rdd.take() which in non-lazy inside foreachRDD()
It worked.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM