Akka StreamのDelayで学ぶback-pressure

Akka StreamのDelayで学ぶback-pressure

1a679952cdf455ecd6a15cbde7ae80d5?s=128

Tomohiko Himura

August 08, 2016
Tweet

Transcript

  1. Akka StreamͷDelayͰֶͿ back-pressure 2016-08-06 LTۦಈ28

  2. ͻΉΒ ͱ΋ͻ͜ akka streamͰWebSocketͯ͠༡ΜͰ͍Δ

  3. Akka Stream

  4. Reactive Streamsの実装の一つ Akkaによる実装

  5. Reactive Streams • ノンブロッキング • back pressure • 非同期 •

    ストリーム処理
  6. IUUQTQSBZJPEVTF

  7. 並行処理するのに 抽象度が高い割に 特殊性が低め

  8. see also IUUQXXXTMJEFTIBSFOFU5BO6LLJJIDNQMGVODUJPOBMBOEDPODVSFODZJOTDBMB IUUQXXXTMJEFTIBSFOFULUPTPBLLBTUSFBNTUPLZPKBQBOFTF

  9. Akka Stream してみる

  10. ストリーム処理のパイプライ ンを表現する部品 • Source • 一つの出力をもつ処理単位 • Flow • 1つの入力と1つの出力をもつ処理単位

    • Sink • 1つの入力を持つ処理単位 • RunnableGraph • 入力も出力もない。実行できる状態。 4PVSDF 4JOL 'MPX
  11. 数字を数え続けてみる import akka.actor.ActorSystem import akka.stream.ActorMaterializer import akka.stream.scaladsl.{Flow, Sink, Source} implicit

    val actorSystem: ActorSystem = ActorSystem() implicit val materialize: ActorMaterializer = ActorMaterializer() val source = Source.fromIterator(() => Iterator.from(0)) // ਺஋͕0͔Βॱ൪ʹྲྀΕͯ͘Δ var sink = Sink.foreach[Int](println) // ೖྗΛը໘ʹग़ྗ͢Δ source.runWith(sink) // sourceͱsinkΛ͚ͬͭͯ͘RunnableGraphΛͭͬͯ͘ɺrun͢Δ
  12. 4PVSDF 4JOL   ʜ QSJOUMO

  13. 実行結果: めっちゃはやい 177644 177645 177646 177647 177648 177649 177650 177651

  14. 流れる速度調整してみる

  15. Delay Flowを利用してみる

  16.   ʜ QSJOUMO 'MPX 4PVSDF 4JOL ඵ଴ͭ

  17. import scala.concurrent.duration._ source.delay(1 second).runWith(sink)

  18. 0 1 2 3 4 5 6 7 8 9

    10 11 12 13 14
  19. 0 1 2 3 4 5 6 7 8 9

    10 11 12 13 14 10263496 21548994 33401491 45739489 56124486 67109484
  20. > 突然の1000万 <

  21.   ʜ QSJOUMO 'MPX 4PVSDF 4JOL ඵ଴ͭ  

                  
  22.   ʜ QSJOUMO 'MPX 4PVSDF 4JOL ඵ଴ͭ  

                   ϝϞϦ͕͍ͬͺ͍ʹͳ Βͳ͍Α͏ʹҰ൪ޙΖ ͕ࣺͯΒΕΔ 
  23.   ʜ QSJOUMO 'MPX 4PVSDF 4JOL ඵ଴ͭ  

                  
  24. バッファを減らしてみる

  25. import akka.actor.ActorSystem import akka.stream.ActorMaterializer import akka.stream.scaladsl.{Flow, Sink, Source} import scala.concurrent.duration._

    def materializer(size: Int) = { ActorMaterializer(ActorMaterializerSettings(actorSystem).withInputBuffer(in itialSize = size, maxSize = size)) } implicit val actorSystem: ActorSystem = ActorSystem() implicit val materialize: ActorMaterializer = ActorMaterializer() val source = Source.fromIterator(() => Iterator.from(0)) var sink = Sink.foreach[Int](println) source.delay(1 second).runWith(sink)(materializer(8)) // bufferSize 8
  26. 0 1 2 3 4 5 6 8670996 19224994 29654491

    40506989 50808986 61550484 72043481
  27. back pressure

  28. 上流に流量を調節の
 お願いができる

  29.   ʜ QSJOUMO 'MPX 4PVSDF 4JOL ඵ଴ͭ σʔλ͍ͩ͘͞

  30.   ʜ QSJOUMO 'MPX 4PVSDF 4JOL ඵ଴ͭ σʔλ͍ͩ͘͞ σʔλ͍ͩ͘͞

  31.   ʜ QSJOUMO 'MPX 4PVSDF 4JOL ඵ଴ͭ σʔλ͍ͩ͘͞ σʔλ͍ͩ͘͞

    
  32.   ʜ QSJOUMO 'MPX 4PVSDF 4JOL ඵ଴ͭ 

  33. 0 1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18
  34. いい感じ?

  35. なんか2つ同時に表示される

  36. 我々が本当に欲しかったモノ > 1秒毎にデータが欲しい <

  37. throttle が使えます

  38. source.throttle(1, 1 second, 1, ThrottleMode.Shaping).runWith(sink) 第1引数 第2引数で指定する期間内で出力される要素数 第2引数 期間 第3引数

    第4引数がEnforcingの時つかう 第4引数 上流からのデータが早いときのモード * Enforcing * Shaping
  39. 0 1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18
  40. まとめ

  41. まとめ • Akka Streamは並行処理するのに • 高抽象 • そこそこ一般性がある • Akka

    Streamはback pressureできる • delayで遊んでみると体験しやすかった