Flink:在DataStream和“一组规则”之间实现“连接”

时间:2018-06-04 13:29:49

标签: apache-flink flink-streaming

以下用例的最佳做法建议是什么?我们需要将流与一组“规则”进行匹配,这些“规则”本质上是一个Flink DataSet概念。可以对此“规则集”进行更新,但不经常。每个流事件必须针对所有“规则集”中的记录进行检查,并且每个匹配都会将一个或多个事件生成到接收器数据流中。规则集中的记录数在6位数范围内。

目前我们只是将规则加载到本地规则列表中,并在传入的DataStream上使用flatMap。在flatMap中,我们只是迭代一个列表,将每个事件与每个规则进行比较。

为了加快迭代速度,我们还可以将列表分成几个批处理,实质上是创建一个列表列表,并创建一个单独的线程来迭代每个子列表(使用Java或Scala中的Futures)。

问题:

  1. 有没有更好的方法来进行这种联接?
  2. 如果没有,除了Flink已经在做什么之外,通过在每个flatMap操作中创建新线程来添加额外的并行性是否安全?
  3. 编辑: 这是所要求的示例代码:

    package wikiedits
    
    import org.apache.flink.streaming.connectors.wikiedits.{WikipediaEditEvent, WikipediaEditsSource}
    import org.apache.flink.streaming.api.scala._
    import org.apache.flink.streaming.api.scala.extensions._
    import scala.concurrent.ExecutionContext.Implicits.global
    import scala.concurrent.Future
    
    object WikipediaEditEventProcessor {
    
      def main(args: Array[String])= {
        val see = StreamExecutionEnvironment.getExecutionEnvironment
        val edits = see.addSource(new WikipediaEditsSource())
    
        val ruleSets = Map[Int, List[String]](
          (1, List("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
          (2, List("k", "l", "m", "n", "o", "p", "q", "r", "s", "t")),
          (3, List("u", "v", "w", "x", "y", "z", "0", "1", "2", "3"))
        )
    
        val result = edits.flatMap { edit =>
          ruleSets.map { ruleSet =>
            applyRuleSet(edit, ruleSet._2, ruleSet._1)
          }
        }
        see.execute
      }
    
      def applyRuleSet(event: WikipediaEditEvent, ruleSet: List[String], ruleSetId: Int): Future[List[String]] = {
        val title = event.getTitle
        Future(
          ruleSet.map {
            case rule if title.contains(rule) =>
              val result = s"Ruleset $ruleSetId: $rule -> exists in: $title"
              println(result) // this would be creating an output event instead
              result
            case rule =>
              val result = s"Ruleset $ruleSetId: $rule -> NO MATCH in: $title"
              println(result)
              result
          }
        )
      }
    }
    

1 个答案:

答案 0 :(得分:1)

  

必须针对“规则集”中的所有记录检查每个流事件,   并且每个匹配将一个或多个事件产生到接收器数据流中。   规则集中的记录数在6位数范围内

说你有K规则。如果输入速率快于处理单个事件的K规则所花费的时间,则您的方法很好。 否则,您需要一些方法来并行处理这些K规则。

将它们视为K收费亭。将它们一个接一个地放置,而不是将它们放在单个大房间内。这将简化流媒体引擎的工作。

换句话说,使用简单的for循环迭代所有规则,并为每个规则分别使用flatMap。 因此,它们中的每一个彼此独立,因此可以并行处理。 最后你可以使用K flatMaps来执行。无论您为执行提供何种配置,引擎都可以使用最大并行度。 这种方法将最大可能的并行性限制为K.但是,这对于大量规则来说已经足够了。

  

通过在每个flatMap中创建新线程来实现额外的并行性   操作

完全没有推荐。将并行性留给flink。您可以在flatMap中定义要执行的工作单元。