Reactive Streams 入門 #jjug

Reactive Streams 入門 #jjug

2015/06/24 JJUG ナイトセミナー 「Reactive Streams特集」 by @okapies
https://jjug.doorkeeper.jp/events/26547

補足記事: http://okapies.hateblo.jp/entry/2015/06/26/024505

Ef45a84b10aa3cb5acd2ea0c9846bd3b?s=128

Yuta Okamoto

June 24, 2015
Tweet

Transcript

  1. 2.

    Who are you? • Ԭຊ ༤ଠ (@okapies) • ւ֎ͷϚΠφʔͳ Scala

    OSS ͷൃ۷͕झຯ • ʢγΣϧεΫϦϓτ৬ਓʣ • Scala Matsuri 2016 ४උҕһʢ຋༁νʔϜʣ
  2. 5.

    ॻ͍ͨ΋ͷ • ຋༁: • Reactive Manifesto v2.0 (http://www.reactivemanifesto.org/ja) • Effective

    Scala (http://twitter.github.io/effectivescala/index-ja.html) • ໋ྩܕͷίʔϧόοΫɺؔ਺ܕͷϓϩϛε (https://gist.github.com/okapies/5354929) • ϒϩάهࣄ (http://okapies.hateblo.jp/): • ඇಉظετϦʔϜॲཧͷඪ४ԽΛ໨ࢦ͢ “Reactive Streams” ͱ͸ • ʮؔ਺ܕϓϩάϥϚͷͨΊͷ Rx ೖ໳ʯγϦʔζ • ϚΠΫϩαʔϏε͕ Scala ΛબͿ̏ͭͷཧ༝ ࠓ೔ͷ͓୊ʂ
  3. 8.

    Reactive Streams ͱ͸ʁ • ”Back-Pressure ෇͖ͷඇಉظετϦʔϜॲཧ“ͷඪ ४ΛఆΊΔ࢓༷ • ඇಉظετϦʔϜॲཧʹ͖ͭ·ͱ͏ϑϩʔ੍ޚ ͷ՝୊ʢόοϑΝᷓΕ໰୊ʣͷղܾࡦΛఏࣔ

    • ࢓༷ʹ४ڌͨ͠ϥϯλΠϜؒͷ૬ޓ઀ଓੑΛอ ূ͢Δ • ࠷ऴ໨ඪ͸ Java 9 Ͱͷඪ४Խ ΤϯυϢʔβ޲͚ͷ
 API ͸είʔϓ֎
 ʢ࣮૷ຖʹ༻ҙ͢Δʣ
  4. 9.

    ओͳࢀՃϕϯμʔ • (Akka) • (RxJava) • (Reactor) • (Vert.x) (Scala

    ݴޠͷ։ൃݩ) (ถࠃ࠷େखͷ
 ಈը഑৴αʔϏε)
  5. 10.

    ओͳࢀՃऀ • Doug Lea • JSR 166 (java.util.concurrent)
 ͷ Specification

    Lead • “Java Concurrency in Practice”
 ͷஶऀͷҰਓ • ඪ४Խ͸ࢯͷओಋͰਐΊΒΕ͍ͯΔ http://www.amazon.co.jp/dp/4797337206/
  6. 17.

    Ͳ͜Ͱ࢖ΘΕ͍ͯΔ͔ • GUIɾϑϩϯτΤϯυͷ࣮૷ • (ϚΠΫϩ)αʔϏεͷ࣮૷ • Ϗοάσʔλॲཧ • etc… •

    Πϕϯτۦಈ • ඇಉظϓϩάϥϛϯά • ฒߦॲཧ ͕ඞཁͳͱ͜Ζશൠ
  7. 19.

    ී௨ͷ(खଓ͖ܕͷ)ίʔυ A = 1; B = 2; C = (A+1)

    + (B-1)*2; ※”Ͳ͏΍࣮ͬͯߦ͢Δ͔”͸ࣗ໌ ʢʹ ࣮ߦϞσϧʣ
  8. 20.

    σʔλϑϩʔ g1 g2 h Input Input Output f ؔ਺ ೖྗ

    ग़ྗ ؔ਺ͱɺؔ਺ಉ࢜Λܨ͗߹Θͤͨάϥϑ
  9. 21.

    -1 ×2 + +1 A B C σʔλϑϩʔͰදͯ͠ΈΔ A =

    1; B = 2; C = (A+1) + (B-1)*2; 1 2 4 1 2 2 ※Ͳ͏࣮ߦ͢Δ͔͸๨ΕΑ͏ ʢม਺ͱԋࢉࢠͷؔ܎͚ͩݟΔʣ
  10. 22.

    -1 ×2 + +1 A B C ม਺Λߋ৽: खଓ͖ܕͷ৔߹ A

    = 1; B = 2; C = (A+1) + (B-1)*2;
 A = 2; 1 $ 2 2 4 C ʹ͸
 ൓ө͞Εͳ͍ खଓ͖ܕͷ࣮ߦϞσϧ × × × × × ×
  11. 23.

    -1 ×2 + +1 A B C Reactive ͳมߋͷ఻೻ A

    := 1; B := 2;
 C := (A+1) + (B-1)*2;
 A := 2; 1 $ 2 4 $ 5 2 1 $ 3 1 2 A ͷมߋ͕
 C ʹ൓ө͞ΕΔ Reactive ͳ࣮ߦϞσϧ
  12. 24.

    -1 ×2 + +1 A B C Reactive ͳมߋͷ఻೻ 2

    5 $ 7 2 $ 3 1 $ 2 2 $ 4 3 C := (A+1) + (B-1)*2;
 A := 2; B := 3; B ͷมߋ͕
 C ʹ൓ө͞ΕΔ Reactive ͳ࣮ߦϞσϧ
  13. 25.

    -1 ×2 + +1 A B C Reactive ͳมߋͷ఻೻ 2

    $ 0 7 $ 5 3 2 4 3 $ 1 A := 2;
 B := 3;
 A := 0; A ͷมߋ͕
 C ʹ൓ө͞ΕΔ Reactive ͳ࣮ߦϞσϧ
  14. 28.

    ྫ (RxJava): Observable<Integer> a = …; Observable<Integer> b = …;

    ! Observable<Integer> a1 = a.map( (i) -> i + 1 ); Observable<Integer> b1 = b.map( (j) -> j - 1 ) .map( (k) -> k * 2 ); ! ! Observable<Integer> c = Observable.combineLatest(a1, b1, (i, j) -> i + j ); A B C +1 —1 ×2 +
  15. 29.

    ྫ (RxJava): Observable<Integer> a = …; Observable<Integer> b = …;

    ! Observable<Integer> a1 = a.map( (i) -> i + 1 ); Observable<Integer> b1 = b.map( (j) -> j - 1 ) .map( (k) -> k * 2 ); ! ! Observable<Integer> c = Observable.combineLatest(a1, b1, (i, j) -> i + j ); σʔλϑϩʔΛܨ͛Δϝιου ؔ਺ ೖྗ A B C +1 —1 ×2 +
  16. 31.

    Reactive ͳϞσϧͷϝϦοτ • มߋ͕ࣗಈతʹ൓ө͞ΕΔ • ඇಉظԽɾฒྻԽ͠΍͍͢ • ૊Έ߹ΘͤՄೳ (composable) ʹ͠΍͍͢

    } ϥϯλΠϜʹ೚ͤΔ (ੑೳ࠷దԽ΋༰қ) ؔ਺ ೖྗ ग़ྗ ֤ؔ਺͸ೖྗͷΈʹ൓Ԡ͢Δ → ֎෦ͷঢ়ଶʹӨڹ͞Εͳ͍ → ૄ݁߹ʹͳΔʂ
  17. 34.

    RP ͷϓϩάϥϛϯάϞσϧ • ໋ྩܕ Reactive Programming • ΦϒδΣΫτࢦ޲ Reactive Programming

    (OORP) • ؔ਺ܕ Reactive Programming (FRP) • ͦͷଞʢFuture/PromiseɺActorʣ
  18. 35.

    RP ͷϓϩάϥϛϯάϞσϧ • ໋ྩܕ Reactive Programming • ΦϒδΣΫτࢦ޲ Reactive Programming

    (OORP) • ؔ਺ܕ Reactive Programming (FRP) • ͦͷଞʢFuture/PromiseɺActorʣ ୯ʹ “RP” ͱݴ͏ͱ ͜Ε͕ଟ͍…ʁ {
  19. 37.

    ຊདྷͷ FRP • 1997 ೥ʹ Conal Elliott (@conal) Β͕ఏএ •

    FRP ͷຊՈ͸ͬͪ͜Ͱɺݫີͳఆ͕ٛ͋Δ Time A Behavior<A> ≈
 Function1[Time, A] Event<A> ≈ List<Pair<Time, A>> ࿈ଓతͳ ʮ࣌ؒతʹมԽ͢ΔৼΔ෣͍ʯ (t, a) ཭ࢄతͳ
 ʮΠϕϯτετϦʔϜʯ A Time +
  20. 38.

    ΧδϡΞϧͳ FRP • ΠϕϯτετϦʔϜΛؔ਺ܕϓϩάϥϛϯάΛ׆༻͠
 ͏·͘ѻ͏ɺ͘Β͍ͷχϡΞϯε • ੈͷதͰࠓɺΑ͘ݴٴ͞ΕͯΔ ”FRP” ͸େମͬͪ͜ (Rx,

    Bacon.js, Elm, …) Time A Behavior<A> ≈
 Function1[Time, A] Event<A> ≈ List<Pair<Time, A>> ࿈ଓతͳ ʮ࣌ؒతʹมԽ͢ΔৼΔ෣͍ʯ (t, a) ཭ࢄతͳ
 ʮΠϕϯτετϦʔϜʯ A Time +
  21. 39.

    ͳͥ FRP ͳͷ͔ʁ • σʔλϑϩʔΛએݴతʹॻ͚Δ • ෭࡞༻Λ੍ݶ͢Δख๏ಉ࢜Ͱ૬ੑ͕ྑ͍ • ߴ֊ؔ਺ (map,

    fold, filter, …) ͷ׆༻ • ڱٛ΋޿ٛ΋ composability ΛߴΊΔखஈͱ ͯؔ͠਺ܕͷख๏Λ࢖͍ͬͯΔ఺͸ಉ͡
  22. 40.

    Future/Promise • RP ͷ஥ؒʹೖΕΔ͜ͱ͕͋Δ • σʔλϑϩʔ͸͋Δ͕มߋͷ఻೻͸ͳ͍ • ྺ࢙తʹ͸ 1970 ೥୅·ͰḪΔ͜ͱ͕Ͱ͖ɺRP

    ΍ Actor Ϟσϧͱ΋ਂ͍ؔ܎͕͋Δ • JavaScript ͳͲͷϑϩϯτΤϯυͷ΄͔ɺϚΠΫ ϩαʔϏεͷ࣮૷खஈͱͯ͠΋޿͘࢖ΘΕ͍ͯΔ ʢTwitter Finagle ΍ Node.js ͳͲʣ
  23. 41.

    Actor Ϟσϧ • RP ͷ஥ؒʹೖΕͨΓೖΕͳ͔ͬͨΓ͢Δ • ϓϩάϥϛϯάϞσϧతʹ͸ composablity ͕௿ ͍ͷ͕೉఺

    • ۙ೥͸ϥϯλΠϜͱͯ͠ͷଆ໘͕஫໨͞Ε͍ͯΔ • Erlang ͕ఏএ͢Δ ”Let It Crash" ఩ֶʹجͮ͘଱ো ֐ੑɺෛՙ؅ཧɺεέʔϥϏϦςΟ • Actor ϥϯλΠϜͷ্ʹ RP ͷϓϩάϥϛϯάϞσ ϧΛࡌͤͨͷ͕ Akka Streamsʢޙड़ʣ
  24. 46.

    ϚΠΫϩαʔϏε val userAndTweets = Future.join( userService.findByUserId(userId), tweetService.findByUserId(userId) ) find find

    userId userAndTweets User
 Service Tweet
 Service http://www.slideshare.net/knoldus/finagle-by-twitter-engineer/16 join ଞͷϚΠΫϩαʔϏε (UserService, TweetService) ʹΫΤϦΛඇಉظʹ౤͛ ͯɺ݁Ռ͕ೋͭͱ΋ฦ͖ͬͯͨ࣌఺Ͱ
 ଋͶͯग़ྗ ྫ: Twitter Finagle
  25. 53.

    Reactive Manifesto ͱ͸ • ”Reactive Systems” ΁ͷࢧ࣋Λݺͼ͔͚Δจॻ • Reactive ͳγεςϜ͕උ͑Δཁ݅ʹ͍ͭͯड़΂͍ͯΔ

    • Typesafe ࣾ (Scala ݴޠͷ։ൃݩ) ͷϝϯόʔ͕ओಋ • ͦͷଞʹ Dave Farley (”ܧଓతσϦόϦʔ”ͷஶऀ) ΍ Martin Thompson (ݩ LMAX CTO) ͳͲ • ϚʔέςΟϯάจॻͱͯ͠ͷ৭࠼͕ೱ͍ʢํ޲ੑͱͯ͠ ͸ “The Twelve-Factor App” ʹ͍͔ۙ΋ʣ
  26. 54.

    γεςϜ΁ͷཁٻͷมԽ ਺೥લ ݱࡏ αʔό਺ ʙ਺ेϊʔυ ਺ઍҎ্ʙ ཁٻԠ౴࣌ؒ ʙ਺ඵ ʙϛϦඵ ཁٻՔಇ཰

    ਺࣌ؒͷΦϑϥΠϯ
 ϝϯςφϯεΛڐ༰ 100% σʔλྔ ΪΨόΠτ୯Ґ ϖλόΠτ୯Ґ
  27. 59.

    Dave Farley ᐌ͘: ࢲ͕࢓ࣄͰؔΘͬͨɺେ͖ͳγεςϜͷΞʔΩςΫνϟʹ͸ྨ ࣅ఺͕͋ͬͨɻͦ͏ͨ͠γεςϜͰ͸ɺ໰୊ྖҬʹ͓͚Δ໌֬ ͳ Bounded Context Λ࣮૷ͨ͠αʔϏε͕ૄ݁߹Ͱ݁ͼ͍ͭ ͓ͯΓɺޓ͍ͷ௨৴͸ඇಉظϝοηʔδͷΈͰߦ͏ɻ͜ΕΒ

    ͸ɺRDB ͷ্ʹߏங͞Εͨശग़͠ͷඪ४తͳࡾ૚ΞʔΩςΫ νϟͷγεςϜͷ΍Γํͱ͸ࣅͯ΋ࣅ͔ͭͳ͍ɻ ιϑτ΢ΣΞΛ࣮ߦ͢Δϋʔυ΢ΣΞ؀ڥ͕มΘΓͭͭ͋Δɻ RAM ͱσΟεΫͷՁ͕֨ࠩॖ·ΓɺRAM ༰ྔ͸ܶతʹ૿Ճɻ ࠓ΍෼ࢄϓϩάϥϛϯά͸ඪ४ͰɺωοτϫʔΫ͸σΟεΫ ΑΓ଎͍ɻେ༰ྔͷඇشൃੑ RAM ͷ࣮༻Խ͸ؒۙͩɻ͜Ε͸ ͭ·Γɺʮඪ४తΞϓϩʔνʯΛࢧ࣋͢ΔԾઆ͕มԽͨ͠ͱ ͍͏͜ͱͩɻ “The Reactive Manifesto | Dave Farley's Weblog” ΑΓົ༁
  28. 61.

    STORAGE & RETRIEVAL LOGIC PRESENTATION ROUTING Redis Memcache Flock T-Bird

    MySQL Tweet User Timeline Social Graph DMs API Web Monorail TFE HTTP Thrift “Stuff” http://monkey.org/~marius/scala2015.pdf ࣮ࡍͷϚΠΫϩαʔϏε
 (Twitter)
  29. 62.

    ϚΠΫϩαʔϏε ⊂ RSʁ • ϚΠΫϩαʔϏε͸ Reactive Systems ͷ۩ମ ྫͷҰͭͩͱߟ͑ͯΑͦ͞͏ •

    ஶऀୡ΋ΠϯλϏϡʔ౳ͰϚΠΫϩαʔϏε ͱͷؔ܎ʹݴٴ͍ͯ͠Δ[1][2] [2]: http://www.infoq.com/jp/news/2014/11/thompson-reactive-manifesto-2 [1]: http://www.infoq.com/articles/reactive-programming-anti-patterns
  30. 63.

    vs. Reactive Programming • Reactive Manifesto ͸ Reactive Programming ͔Β༻ޠΛआΓ͖ͯͨผ෺ͱߟ͑Δͷ͕ྑ͍

    • Reactive ͷʮ֎෦͔Βͷܹࢗʹ൓Ԡ͢Δʯͱ ͍͏ҙຯ߹͍Λڧௐ͍ͯ͠Δ
 ʢΠϕϯτɺෛՙɺো֐ɺϢʔβɺ…ʣ
  31. 64.

    vs. Reactive Programming • ͱ͸͍͑…ϝοηʔδۦಈʹΑΔඇಉظϓϩ άϥϛϯά͕େલఏʹͳΔͷͰɺ࣮૷खஈͷ Ұͭͱͯ͠ Reactive Programming ͸༗ྗ

    Reactive Manifesto Reactive Programming Callback- based … ??? ϓϩάϥϛϯά Ϟσϧ ϥϯλΠϜ ΞʔΩςΫνϟ Actor Model
  32. 65.

    Programming × Systems • Reactive Manifesto ͷ໨ࢦ͢ੈք: • େن໛σʔλΛѻ͑ΔεέʔϥϒϧͰՄ༻ ੑͷߴ͍෼ࢄγεςϜ

    • RM ͷจ຺Ͱ RP Λ׆༻͢Δʹ͸ɺେن໛ॲཧ ʹରͯ͠ responsive ͳϥϯλΠϜ͕ඞཁ
  33. 72.

    σʔλϑϩʔͷܾյ • Publisher ͸ Subscriber ΁ϝοηʔδΛૹΔ Publisher Subscriber … 3

    msgs/sec 3 msgs/sec ϝοηʔδόοϑΝ ॲཧೳྗ ૹ৴ೳྗ =
  34. 75.

    Back-Pressure • Publisher ͸ϦΫΤετ͞Εͨ෼͚ͩϝοηʔ δΛૹΔ → ҆શ … 100 msgs/sec

    [Request(3)] Publisher Subscriber 3 msgs/sec ࣍ɺ3 ݸ͍ͩ͘͞ ͍͋Αʔ
  35. 77.

    SPI ͷΠϯλϑΣʔε public interface Publisher<T> { public void subscribe(Subscriber<? super

    T> s); } public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); } public interface Subscription { public void request(long n); public void cancel(); } ͢΂ͯ໭Γ஋ͳ͠ʹඇಉظ ޠኮ͸ RxJava ͕ϕʔε
  36. 79.

    ओͳ࣮૷ • Akka Streams (Typesafe) • Ratpack • Reactor (Spring)

    • RxJava (Netflix) • Vert.x 3.0 (Red Hat)
  37. 80.

    DB ΞΫηεϥΠϒϥϦͷ࣮૷ • Slick 3.0 a.k.a “Reactive Slick” (JDBC) •

    ReactiveMongo • Reactive Rabbit (AMQP) • Reactive Kafka • etc…
  38. 81.

    ͳͥ Reactive ͳ DB Ξμϓλ͕ඞཁʁ • ྫ͑͹ɺJDBC ͸ಉظ API ͳͷͰɺඇಉظͳ

    ϑϨʔϜϫʔΫΛ࢖͍ͬͯͯ΋ worker thread ΁ͷॲཧͷҕৡΛࣗ෼Ͱॻ͘ඞཁ͕͋ͬͨ • context switch ͷίετɺεϨου਺ʹԠ͡ ͨϝϞϦফඅɺεϨουؒ௨৴ͷϩοΫڝ߹ • ϫʔΧεϨου਺ͱɺDB ίωΫγϣϯϓʔϧ ͷαΠζΛ”ਖ਼͘͠”ઃఆ͢Δඞཁ͕͋Δ
  39. 82.

    ͢΂͕ͯ Reactive ʹͳΔ • Reactive ͳ DB Ξμϓλ͕ग़ἧͬͨ͜ͱͰɺ ೖޱ͔Βग़ޱ·Ͱ Reactive

    Streams ४ڌͷ෦ ඼Ͱ૊Έ্͛ΒΕΔΑ͏ʹͳͬͨ AMQP Rx
 Java Akka Vert.x RDB ྫ:
  40. 83.

    Reactive Streams ͷࠓޙ • Java 9 Ͱͷඪ४Խ (j.u.c.Flow) • ೿ੜϓϩδΣΫτ

    • JavaScritp Interface (reactive-streams-js) • Network Protocol (reactive-streams-io) • Reactive IPC (http://reactive-ipc.io)
  41. 85.

    Akka Streams ͱ͸ • Akka Λϕʔεʹͨ͠ Reactive Streams ࣮૷ͷ ͻͱͭ

    • σʔλϑϩʔΛهड़͢Δܕ҆શͳ DSL Λఏڙ ͢ΔʢJava ˍ Scalaʣ • কདྷతʹ͸ Play Framework ͷج൫ʹͳΔ༧ఆ
  42. 86.

    جຊతͳߟ͑ํ • σʔλϑϩʔ
 
 
 
 Λ Actor ౳Λ࢖ͬͯ۩ݱԽ (materialize)

    ͢Δ • ૊Έ্͛ͨ FlowGraph ࣗମ͸ઃܭਤ (blueprint) ͳͷͰɺ৭ʑͳ Source ΍ Sink Ͱ࢖͍ճͤΔ Source Flow Sink
  43. 87.

    ίʔυྫ (Scala) implicit val system = ActorSystem() implicit val mat

    = ActorFlowMaterializer() ! val source = Source[Int](1 to 5) val sink = Sink.foreach[Int](println) ! source.map(_ * 2).runWith(sink) Source ×2 Sink Actor ͷ४උ Materializer Λ࢖࣮ͬͯߦ
  44. 88.

    FlowGraph DSL val g = FlowGraph { implicit builder =>

    import akka.stream.scaladsl.FlowGraphImplicits._ ! source ~> f1 ~> bcast ~> f2 ~> merge ~> f3 ~> sink bcast ~> f4 ~> merge } Source f2 Sink f4 f1 Broadcast f3 Merge
  45. 89.

    Materializer ͷਐԽ • ݱࡏͷ Materializer ͸ Akka Actor ༻ͷΈ •

    FlowGraph Λ࣮ߦϓϥϯ (execution plan) ͱΈͳ ͢ͱɺ৭ʑͳ͜ͱΛ࣮ݱ͢Δ༨஍͕͋Γͦ͏ • άϥϑͷ࠷దԽ΍ݕূɺ݁ՌͷΩϟογϡ • akka-cluster ͱ૊Έ߹Θͤͯ෼ࢄΫϥελରԠ • ཧ۶্͸ Spark ରԠ΋Մೳ…ʂʁ
  46. 90.
  47. 92.

    ·ͱΊ • য఺͸͢ͰʹϥϯλΠϜ΍γεςϜΞʔΩςΫ νϟ΁ҠΓͭͭ͋ΔͷͰ͸ͳ͍͔ • Reactive Streams ͕࡞Γग़͢ΤίγεςϜ
 → ैདྷܕ

    Web ΞʔΩςΫνϟ΁ͷ௅ઓ • ϥϯλΠϜͷੑೳɺ଱ো֐ੑɺӡ༻ੑ͕બ ఆج४ͱͯ͠ΑΓॏཁʹ ҰํͰʮԿͰॻ͔͘ʯ͸
 ͲΜͲΜऔΓସ͑ՄೳʹͳΔʁ