Apache spark spark结构化流式动态串滤波器

Apache spark spark结构化流式动态串滤波器,apache-spark,spark-structured-streaming,Apache Spark,Spark Structured Streaming,我们正在尝试为结构化流媒体应用程序使用动态过滤器 假设我们有以下Spark结构化流媒体应用程序的伪实现: spark.readStream() .格式(“卡夫卡”) .选项(……) ... .load() .filter(getFilter())广播变量在这里应该是正常的。您可以编写类型化筛选器,如: query.filter(x => x > bv.value).writeStream(...) 其中bv是一个广播变量。您可以按如下所述进行更新: 另一种解决方案是提供RCP或RE

我们正在尝试为结构化流媒体应用程序使用动态过滤器

假设我们有以下Spark结构化流媒体应用程序的伪实现:

spark.readStream()
.格式(“卡夫卡”)
.选项(……)
...
.load()

.filter(getFilter())广播变量在这里应该是正常的。您可以编写类型化筛选器,如:

query.filter(x => x > bv.value).writeStream(...)
其中bv是一个
广播
变量。您可以按如下所述进行更新:

另一种解决方案是提供RCP或RESTful端点,并每10分钟询问一次该端点。例如(Java,因为这里更简单):

编辑:针对用户问题的黑客解决方法:

您可以创建单行视图: //confsDF应该在一些驾驶员侧单例中 var confsDF=Seq(某些内容).toDF(“某些列”)

这种黑客依赖于Spark默认执行模型——微批次。在每个触发器中,查询都将被重建,因此应该考虑新的数据

您还可以在线程中执行以下操作:

Seq(some new data).toDF("someColumn).createOrReplaceTempView("conf")
然后在查询中:

.crossJoin(spark.table("conf"))

两者都应该起作用。请记住,它不会在连续处理模式下工作,这里是一个简单的示例,其中我是来自套接字的动态筛选记录。您可以使用任何可以动态更新过滤器或轻量级zookeeper实例的RESTAPI来代替Date

注意:-如果您计划使用任何rest API或zookeeper或任何其他选项,请使用mapPartition而不是filter,因为在这种情况下,您必须一次性调用分区的API/连接

val lines = spark.readStream
  .format("socket")
  .option("host", "localhost")
  .option("port", 9999)
  .load()

// Split the lines into words
val words = lines.as[String].filter(_ == new java.util.Date().getMinutes.toString)

// Generate running word count
val wordCounts = words.groupBy("value").count()

val query = wordCounts.writeStream
  .outputMode("complete")
  .format("console")
  .start()

query.awaitTermination()

谢谢你的回复!我们还使用
def过滤器(conditionExpr:String)
filter-以及字符串和条件。我们希望使用这个函数,避免像你们的例子中那样使用“函数方式”。我想让broadcas
bv.value
返回字符串并定期更新。如果无法使用广播,我们将使用您的第二个建议,但字符串不是函数方式。你介意可以用“串法”吗?我认为作业在提交后是“不可变的”。@VladoDemcak Spark从您的输入中创建一个文本,所以这里不可能使用字符串。文字是不可变的哦。。无论如何,谢谢,关于文字的信息真的很重要。但这很悲哀,因为我们在其中使用了hive的UDF(作为字符串)。您是否知道另一种“变通方法”或其他可以使用的方法,可以获得与我们现在相同的结果(使用
过滤器(字符串条件)
)和动态过滤器?我选中了
where()
,但可能是相同的。@VladoDemcak-where在内部创建了相同的表达式。你如何使用这个自定义项?也许这是可能的,我投入的edit@VladoDemcak这是正确的-Spark将10转换为文本,这是不可变的。Lambda是一个“黑匣子”,不能下推到源代码,但也给了filterIt的ok更具动态风格的机会,这和我写的建议类似。但OP说,他希望fitler成为一根弦,而不是像@T.Gawęda说的那样完全是一根弦。所以我不能给你投票支持这个答案,即使它是有用的。我们不想使用lambda而是string。基本上,我们需要避免只提交多个作业b/c筛选器中的小更改。这是正确的,但您可以生成任何您想要的字符串。它给你所有的可能性。您可以编写一个lamda来调用api并获得有利的字符串。当然,但在OP中比较字符串并不简单。因为我们使用的where表达式不是lambda表达式。当我们调用一个api并得到一个字符串时,这个字符串基本上就是spark的sqlparser将表达式转换成奇怪的代码的地方,正如@T.Gawęda在他的回答中所说的,它是不可变的。我在考虑有一个转换函数或什么的,但需要玩一点
.crossJoin(spark.table("conf"))
val lines = spark.readStream
  .format("socket")
  .option("host", "localhost")
  .option("port", 9999)
  .load()

// Split the lines into words
val words = lines.as[String].filter(_ == new java.util.Date().getMinutes.toString)

// Generate running word count
val wordCounts = words.groupBy("value").count()

val query = wordCounts.writeStream
  .outputMode("complete")
  .format("console")
  .start()

query.awaitTermination()