Scala ApacheFlink—实现一个状态可能非常大的流处理器

Scala ApacheFlink—实现一个状态可能非常大的流处理器,scala,apache-flink,flink-streaming,Scala,Apache Flink,Flink Streaming,我希望从一系列事件中投射出一个潜在的非常大的状态。这就是我如何以命令式的方式实现这一点: class ImperativeFooProcessor { val state: mutable.Map[UUID, BarState] = mutable.HashMap.empty[UUID, BarState] def handle(event: InputEvent) = { event match { case FooAdded(fooId, barId) =&g

我希望从一系列事件中投射出一个潜在的非常大的状态。这就是我如何以命令式的方式实现这一点:

class ImperativeFooProcessor {

  val state: mutable.Map[UUID, BarState] = mutable.HashMap.empty[UUID, BarState]

  def handle(event: InputEvent) = {
    event match {
      case FooAdded(fooId, barId) => {
        // retrieve relevant state and do some work on it
        val barState = state(barId)

        // let the world know about what may have happened
        publish(BarOccured(fooId, barId))
        // or maybe rather
        publish(BazOccured(fooId, barId))
      }
      case FooRemoved(fooId, barId) => {
        // retrieve relevant state and do some work on it
        val barState = state(barId)

        // let the world know about what may have happened
        publish(BarOccured(fooId, barId))
        // or maybe rather
        publish(BazOccured(fooId, barId))
      }
    }
  }

  private def publish(event: OutputEvent): Unit = {
    // push event to downstream sink
  }
}
在最坏的情况下,BarState的大小将随着其被添加的次数而增加

相对于每个barId的事件总数,唯一barId的数量非常少

我将如何开始在Flink中表示这种处理结构


如何处理每个BarState都可能变得非常大的事实?

Flink在所谓的状态后端中维护状态。有在工作进程的JVM堆上操作的状态后端MemoryStateBackend和FsStateBackend。这些后端不适合处理大型状态

Flink还具有RocksDBState后端,它基于。RocksDB用作本地数据库,无需在每个工作节点上将其设置为外部服务,并将状态数据写入磁盘。因此,它可以处理超过内存的非常大的状态

Flink提供了一个KeyedStream,它是一个根据特定属性进行分区的流。在您的情况下,您可能希望对同一id的所有访问都转到同一个状态实例,因此您可以使用barId作为密钥。然后,基于barId在所有并行工作线程之间划分状态。这基本上是一个分布式键值存储或映射。因此,您不需要将状态表示为地图,因为它是由Flink自动分发的