我对Akka streams
中的粉丝策略感到有些困惑,我读到了
Broadcast
- (1个输入,N个输出)给定一个输入元素发送到每个输出,而Balance
- (1个输入,N个输出)给定一个输入元素发送到其输出端口之一。
你能解释一下我吗:
答案 0 :(得分:5)
从文档...广播向每个消费者发出(发送)元素。余额仅发放给第一个可用的消费者。
发出每个输入元素n个输出。
将流扇出到多个流。每个上游元素都是 向第一个可用的下游消费者发放。
来自评论的编辑:
从你的要点,你应该制作两个averageCarrierDelay函数,每个Z
和F
一个。然后你可以看到发送给每个元素的所有元素。
val averageCarrierDelayZ =
Flow[FlightDelayRecord]
.groupBy(30, _.uniqueCarrier)
.fold(("", 0, 0)){
(x: (String, Int, Int), y:FlightDelayRecord) => {
println(s"Z Received Element: ${y}")
val count = x._2 + 1
val totalMins = x._3 + Try(y.arrDelayMins.toInt).getOrElse(0)
(y.uniqueCarrier, count, totalMins)
}
}.mergeSubstreams
val averageCarrierDelayF =
Flow[FlightDelayRecord]
.groupBy(30, _.uniqueCarrier)
.fold(("", 0, 0)){
(x: (String, Int, Int), y:FlightDelayRecord) => {
println(s"F Received Element: ${y}")
val count = x._2 + 1
val totalMins = x._3 + Try(y.arrDelayMins.toInt).getOrElse(0)
(y.uniqueCarrier, count, totalMins)
}
}.mergeSubstreams
编辑2:为了检查将来的事情,我建议您使用流级的通用记录器,这样您就可以看到正在发生的事情。
def logElement[A](msg: String) = Flow[A].map { a => println(s"${msg} ${a}"); a }
执行此操作可以执行以下操作:
D ~> logElement[FlightDelayRecord]("F received: ") ~> F
D ~> logElement[FlightDelayRecord]("Z received: ") ~> Z
通过这种方式,您可以检查图表中您可能会或可能不会遇到的奇怪行为区域。
答案 1 :(得分:1)
正如其他人已经说过的那样,广播向所有输出端口发出输入,而平衡则根据背压将其输入发送到一个输出端口。
使用GraphStage
时,需要选择要使用的输出端口。考虑这个例子:
val q1 = Source.queue[Int](10, OverflowStrategy.fail)
val q2 = Source.queue[Int](10, OverflowStrategy.fail)
GraphDSL.create(q1, q2)(Keep.both) { implicit b => (input1, input2) =>
import GraphDSL.Implicits._
val broadcast = b.add(Broadcast[Int](2))
val balance = b.add(Balance[Int](2))
val consumer1, consumer2, consumer3, consumer4 = b.add(Sink.foreach[Int](println))
input1 ~> broadcast.in
input2 ~> balance.in
broadcast.out(0) ~> consumer1
broadcast.out(1) ~> consumer2
balance.out(0) ~> consumer3
balance.out(1) ~> consumer4
ClosedShape
}
这里我们将一个输入连接到一个广播舞台,一个输入连接到平衡阶段。然后我们将广播和平衡阶段的不同输出端口连接到相应的消费者。
在这种特殊情况下,当您运行流时,通过第一个输入的元素将传递给consumer1
和consumer2
,因为广播阶段将其输入复制到其所有输出(和这是两个输出),来自第二个输入的元素将根据终端的速度(即consumer3
的速度)在consumer4
和println
之间均匀分布,因为{当函数执行很长时间时,{1}}背压。
请注意,我们已指定广播和平衡阶段各有2个端口(调用其工厂方法时),并且我们已指定连接到哪个消费者的输出端口。