Apache Flink-异步刷新哈希表

时间:2019-03-01 12:33:27

标签: scala apache-flink

我正在使用Scala API开发Apache Flink应用程序(使用这项技术我还很新)。

我正在使用哈希图存储一些来自数据库的值,我需要每1小时刷新一次这些值。有什么方法可以异步刷新此哈希图?

谢谢!

3 个答案:

答案 0 :(得分:0)

我不确定在Flink工作流程的上下文中“异步刷新此哈希图”是什么意思。

关于它的价值,如果您有一个哈希图由流过工作流的记录中的某些数据作为键,则可以使用Flink对managed key state的支持来存储值(并对其进行检查),然后使其queryable

答案 1 :(得分:0)

我将您的问题解释为意味着您正在Flink中使用某种状态来镜像/缓存来自外部数据库的某些数据,并且您希望定期刷新它。

通常,这种事情是通过将更改数据捕获(CDC)流从外部数据库连续流传输到Flink来完成的。连续流解决方案通常更适合Flink。但是,如果要按小时批量执行此操作,则可以编写一个自定义源或一个ProcessFunction,该源或每小时唤醒一次,对数据库进行查询,并发出记录流,可用于更新持有操作符的操作员。州。

答案 2 :(得分:-1)

您可以使用Apache Flink的用于外部数据访问的异步I / O来实现此目的,有关详细信息,请参见此帖子async io

这是一种使用AsyncDataStream定期刷新地图的方法,方法是创建一个异步函数并将其附加到源流。

class AsyncEnricherFunction extends RichAsyncFunction[String, (String String)] {
  @transient private var m: Map[String, String] = _
  @transient private var client: DataBaseClient = _
  @transient private var refreshInterval: Int = _

@throws(classOf[Exception])
  override def open(parameters: Configuration): Unit = {
    client = new DataBaseClient(host, port, credentials)
    refreshInterval = 1000
    load()
  }

  private def load(): Unit = {
    val str = "select key, value from KeyValue"
    m = client.query(str).asMap    
    lastRefreshed = System.currentTimeMillis()
  }

 override def asyncInvoke(input: String, resultFuture: ResultFuture[(String, String]): Unit = {
    Future {
      if (System.currentTimeMillis() > lastRefreshed + refreshInterval) load()      
      val enriched = (input, m(input))
      resultFuture.complete(Seq(enriched))
    }(ExecutionContext.global)
  }

  override def close() : Unit = { client.close() }
}

 val in: DataStream[String] = env.addSource(src)
 val enriched = AsyncDataStream.unorderedWait(in, AsyncEnricherFunction(), 5000, TimeUnit.MILLISECONDS, 100)