Spark Structured Streaming与ElasticSearch集成

时间:2017-12-21 13:37:24

标签: apache-spark elasticsearch spark-structured-streaming

我正在构建一个将一些数据发送到我的群集的应用程序。 我将此数据存储到特定的HDFS文件夹中,其中正在运行Spark Streaming应用程序。

在这个streamApp中,我会快速做一些& amp;便宜的数据科学。 之后,我必须将结果索引到ElasticSearch,以便为我的AngularApp提供数据。

一切都很好,

但是......我无法用ES索引我的结果。 事实是......我可以将我的结果DataFrame转换为RDD,因为它使用一些Dataframe Stream作为输入

这是我的伪代码:

val schema = StructType(
    StructField("id", StringType, nullable = false) ::
    StructField("code", StringType, nullable = false) :: Nil)


val lines = spark.readStream
  .format("json")
  .schema(schema)
  .load(HDFSPath)

// Do some basics stuff here

import spark.implicits._

val linesRDD = lines.rdd.map(row => 
        StreamingObj(row(0).toString,row(1).toString))  // RDD[StreamingObj]
linesRDD.saveToEs("stream/stream")           // ES
val linesDF= linesRDD.toDF()

val queryNode = linesDF
    .writeStream
    .format("console")
    .outputMode(OutputMode.Append)
    .trigger(Trigger.ProcessingTime(4.seconds))
    .start

当我尝试将我的DataFrame转换为RDD时,它失败了。

我必须转换为RDD才能索引数据。

在lines.rdd.map上,我知道了。

Exception in thread "main" org.apache.spark.sql.AnalysisException: Queries with streaming sources must be executed with writeStream.start();;

是否可以在ES中索引DataStreaming spark?

感谢您的帮助。

尝试更简单的案例:

   val lines = spark.readStream
      .format("json")
      .schema(schema)
      .load(HDFSPATH).as[StreamingObj]

  lines.writeStream
      .format("org.elasticsearch.spark.sql")
      .outputMode("append")
      .start("index/stream")
  

17/12/21 15:37:55 INFO util.Version:Elasticsearch Hadoop v5.4.2   [a478aabe9e]线程" main"中的例外情况   java.lang.UnsupportedOperationException:数据源   org.elasticsearch.spark.sql不支持流式写入

我做的事与docs =>相同https://www.elastic.co/guide/en/elasticsearch/hadoop/current/spark.html#spark-sql-streaming

甚至是这个例子:https://discuss.elastic.co/t/spark-structured-streaming-sink-in-append-mode/105664/4

或者这个:

https://discuss.elastic.co/t/structured-streaming-failed-to-find-data-source-es/112144

这是我的Maven依赖:

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch-spark-20_2.11</artifactId>
    <version>5.4.2</version>
</dependency>

这是好的吗?我无法使用格式(&#39; es&#39;),它最密集的找到它。

似乎ES中的Spark结构化流媒体只是&gt; 6.0

请参阅https://www.elastic.co/blog/structured-streaming-elasticsearch-for-hadoop-6-0

2 个答案:

答案 0 :(得分:2)

问题出在这里

df <- read.table(text = "Date
2014-01-02
                 2014-01-02
                 2014-01-02
                 2014-01-03
                 2014-01-03
                 2014-02-01
                 2014-02-01
                 2014-02-02
                 2014-02-02", header = T)
df

library(dplyr)
df %>% 
  group_by(ym = format(as.Date(Date, "%Y-%m-%d"), "%Y-%m")) %>% 
  mutate(Count = n()) %>% 
  ungroup() %>%
  select(-ym)

结构化流式传输查询中不允许转换为val linesRDD = lines.rdd.map(row => StreamingObj(row(0).toString,row(1).toString)) // RDD[StreamingObj] 。你可以尝试直接写:

RDD

或使用lines .writeStream .format("org.elasticsearch.spark.sql") ...

ForeachWriter

答案 1 :(得分:0)

要在Elasticsearch 5.x中实现此功能,您需要在this answer中实现CustomSink和CustomSinkProvider。

然后在lines.writeStream.foreach(...)中,您可以在format中指定提供商。