从Kafka阅读时,Spark错过了99.9%的消息

时间:2016-04-23 20:21:12

标签: java apache-spark elasticsearch apache-kafka bigdata

TL; DR:我的火花应用程序正在摄取从Kafka发送的总信息量的0.1%。 我的主要嫌疑人:对于每个批处理间隔(例如1秒),实例化新的JVM。我试图使用延迟加载的.map()转换来摄取数据。驱动程序和驱动程序是否可能?执行者代码相互详尽可能有什么关系吗?

包含详细信息的长版:

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

问题:在试验时,我从数据生成器发送10000个消息。我是这个传入数据的kibana仪表板&它显示9600个消息(+ -0.1%但始终如一)

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

现在火花(批量间隔为1秒,并在1个线程上运行)读取这些消息&它的输出我在另一个可视化下被送入同一个kibana。

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

如果它读取10个消息,那么它们的计数值为1-10&如果它读取20个msgs,则计数值为1-10& 〜3000-3010

Q2。为什么Spark只能获得10(或最多20)msgs?

我在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-&gt; kafka,kafka-&gt; elastic

迁移数据

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

Q4。如何使用kafka-run-class方法运行着色jar或者它是否需要作为独立的java程序运行,在这种情况下它会以与使用kafka开箱即用脚本运行时相同的速率发出msgs因为我认为它确实照顾并行化和&amp;排队以维持背压。

使用这个kafka脚本,我能够在我的机器上渗出1.4Mpps。

编辑:有关kafka-spark partition&amp;的更多信息代码逻辑

注: topic_1是来自生产者(脚本)的数据 - &gt;卡夫卡 topic_2是Spark-&gt; 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个执行器&amp; 1个带4GB驱动器的驱动器执行程序内存在4个核心上的1个线程上,间隔1秒 在试验10M + msgs时,topic_1接收到几乎正确的数字(上面是9600/10000 Q1),同时topic_2只能得到~6k条消息 关于分区,一切都在同一台机器上的独立模式下,32GB ram&amp; 4核心。通过我的意思,数据生产者,卡夫卡,ELK,火花。

Data_gen:简单的java kafka生产者代码,以1:1的比例发送值为0或1的json字符串。 Spark_app:主要qn中的代码。 my_fn()获取字符串msg,将其转换为json&amp;看是否值为0或1

1 个答案:

答案 0 :(得分:0)

def money():