在akka-streams中没有正确处理背压

时间:2015-12-22 18:51:14

标签: akka-stream

我使用akka-streams api编写了一个简单的流,假设它将处理我的源代码,但不幸的是它没有。我确信我的来源做错了。我只是创建了一个迭代器,它生成了大量的元素,假设它无关紧要,因为akka-streams api会处理背压。我做错了什么,这是我的迭代器。

def createData(args: Array[String]): Iterator[TimeSeriesValue] = {
var data = new ListBuffer[TimeSeriesValue]()
for (i <- 1 to range) {
  sessionId = UUID.randomUUID()
  for (j <- 1 to countersPerSession) {
    time = DateTime.now()
    keyName = s"Encoder-${sessionId.toString}-Controller.CaptureFrameCount.$j"
    for (k <- 1 to snapShotCount) {
      time = time.plusSeconds(2)
      fValue = new Random().nextLong()
      data += TimeSeriesValue(sessionId, keyName, time, fValue)
      totalRows += 1
    }
  }
}
data.iterator

}

1 个答案:

答案 0 :(得分:2)

问题主要出在

data += TimeSeriesValue(sessionId, keyName, time, fValue)

您不断向ListBuffer添加“非常多的元素”。这会扼杀你所有的RAM。 data.iterator行只是将一个巨大的ListBuffer blob包装在一个迭代器中,一次提供一个元素,它基本上只是一个强制转换。

你的假设是“因为...背压无关紧要”,部分原因是akka Stream会反应性地处理TimeSeriesValue值,但是你甚至在得到之前就会创建大量的值到Source构造函数。

如果你希望这个迭代器是“懒惰的”,即只在需要时产生值而不消耗内存,那么进行以下修改(注意:我拆开了代码以使其更具可读性):

def createTimeSeries(startTime: Time, snapShotCount : Int, sessionId : UUID, keyName : String) = 
  Iterator.range(1, snapShotCount)
          .map(_ * 2)
          .map(startTime plusSeconds _)
          .map(t => TimeSeriesValue(sessionId, keyName, t, ThreadLocalRandom.current().nextLong()))

def sessionGenerator(countersPerSession : Int, sessionID : UUID) = 
  Iterator.range(1, countersPerSession)
          .map(j => s"Encoder-${sessionId.toString}-Controller.CaptureFrameCount.$j")
          .flatMap { keyName => 
    createTimeSeries(DateTime.now(), snapShotCount, sessionID, keyName)
  }

object UUIDIterator extends Iterator[UUID] {
  def hasNext : Boolean = true
  def next() : UUID = UUID.randomUUID()
}

def iterateOverIDs(range : Int) = 
  UUIDIterator.take(range)              
              .flatMap(sessionID => sessionGenerator(countersPerSession, sessionID))

上述每个函数都返回一个迭代器。因此,调用iterateOverIDs应该是即时的,因为没有立即完成工作并且正在消耗de mimimis内存。然后可以将此迭代器传递到您的Stream ...