Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

並行処理初心者のためのAkka入門

42,293 views

Published on

Concurrent programing explanation for akka beginers.
並行処理初心者のためのAkka入門

akka meetup 2014/09/28(日)
http://connpass.com/event/8622/
このイベントの導入説明のために書かれました。
内容には、並行処理、アクターモデル、Akkaの機能の説明となっています。

Published in: Technology

並行処理初心者のためのAkka入門

  1. 1. 並行処理初心者のための Akka入門 株式会社ドワンゴ 吉村総一郎 @sifue
  2. 2. 今日はAkkaの勉強会
  3. 3. そもそもAkkaとは 何か?
  4. 4. そんな人のための プレセッション
  5. 5. Akkaとは • ScalaとJavaのApach2ライセンスで提供され ているOSSのライブラリ • アクターモデルを適用したスケーラビリティや 耐障害性に優れた並行処理が書けるライブラリ • Play Framework 2でも利用されている http://akka.io/
  6. 6. Akkaを知る前に • 並行処理 • アクターモデル この二つを知らないといけない。 今から上記二つをざっくり説明して、 Akkaの機能もざっくり解説する
  7. 7. 並行処理プログラミングとは ブライアン・ゲーツ ダグ・リー Java並行処理プログラミング ―その「基盤」と「最新API」を究める― • この本の内容をざっくり • まだ書店にはあるかも?
  8. 8. 並行処理の歴史 1. OSのプロセスによる並行処理 • 資源の有効利用: 入出力のような外部操作の待ち時間 • 公平性: 複数のユーザーで複数の処理 • 利便性: 一つのプログラムで一つのタスクの方がシンプル ➡タイムシェアリングシステムでメモリは別 2. スレッド (軽量プロセス)による並行処理 • プロセスと同じ動機 • ひとつのプロセス内で複数のお仕事 • メモリ、ファイルハンドルは共有 • 共有データへのアクセスは明示的な同期化が必要
  9. 9. スレッドの利点 • マルチプロセッサの有効利用 • 1つのスレッドに1つのタスクで設計 の単純化※ • サーバーへのクライアント接続などの 処理を単純化※ • 応答性の良いUIの実現 ※問題点でもある
  10. 10. スレッドのリスク: 安全性の危機 インクリメントと取得が 別スレッドで交互に実行 p.7より
  11. 11. スレッドのリスク: デッドロック リソースをロックし 合って永遠に待つ パターン p.233より
  12. 12. スレッドのリスク: 実行性能の危機 • スレッドが増えると、プロセス上のス レッドの入れ替えのためのコンテキス トスイッチのコストが増大
  13. 13. スレッドセーフの解決案 1.ステートレスにする 2.ロックして同期化処理を行う • メモリの可視性にはすごく注意が必要 (激難) 変数の更新が 別スレッドからは 見えない p.40より
  14. 14. オブジェクトの 共有の難しさ • synchronizedによるlockでの同期 • volatileによる揮発性変数の利用 • ただし同一スレッドからの書き込みの みの場合に限る • 同期化されてない内部変数を逸出しない ような入念なチェックが必要
  15. 15. 並行処理プログラミング ってとてもむずかしい... → concurrentパッケージのお陰 でなんとか
  16. 16. ちなみにJavaの concurrentパッケージの概要 名前内容 Executor フレームワークスレッドを、CallableとFutureで扱えるようにしたり、 並列度やリトライ、スケジュールを制御できる Concurrent コレクションJavaのコレクションをマルチスレッドで扱えるようにし たコレクション群、putIfAbsentとかもある。 Atomic パッケージAtomicLongやAtomicReferenceなど、並行処理で変更 しても問題が起こらない値や参照のクラス群 ReentrantLock 再利用可能なロック。いわゆる排他処理とかMutexとか いわれるものを実現。tryLockとlockの両対応。 CyclicBarrier 全スレッドがバリアに到達するまで待って、何かを実行 してくれる部品 CountDownLatch 指定した数まで処理が実行されるまで、全スレッドを待 たせてくれる部品 Semaphore 一度に指定された数のスレッドしか実行されないように してくれる部品 DelayQueue 特定の時間が経過すると中身を取得できるようになる キュー
  17. 17. とはいえ、チーム開発してると よくわからんバグが起こりやすい → なぜかテストが2回に1回落ちるw
  18. 18. 誰かが界王拳みたいな ものだと言ってた (数倍の力出るけど死ぬかもしれない...)
  19. 19. そこで登場
  20. 20. アクターモデル
  21. 21. アクターモデルの歴史 • 将来的に「数百・数千のマイクロプロ セッサから構成され、個々にローカル メモリを持ち、高性能通信ネットワー クで通信を行う並列コンピュータが近 い将来登場するとの予測」から開発さ れた
  22. 22. 現状スケールのためには • マルチコア • クラスタ構成 が、今の大規模サービスの基本戦略な ので、すごく今の現状にマッチ 1985年ぐらいにアクターモデル理論として完 成したらしい…ここらへんの学術的な話は→ Wikipediaのアクターモデルを見てください
  23. 23. アクターモデルとは メールボックス アクター メッセージ address address address address address address ループ
  24. 24. アクターという処理行い、状態を持つオブジェクト メールボックス アクター メッセージ address address address address address address ループ
  25. 25. それぞれメールボックスとアドレスがある メールボックス アクター メッセージ address address address address address address ループ
  26. 26. アクター内ではループで逐次処理しながら、メッセージを別 なアクターに投げたりして、メールボックスに溜まった命令を 順不同で処理 (Akkaではデフォルトでは到着順で処理) メールボックス アクター メッセージ address address address address address address ループ
  27. 27. メッセージパッシングすることで非同期に処理し、 単一のループで逐次処理しているので、並行処理のロックや同期が不要 メールボックス アクター メッセージ address address address address address address ループ
  28. 28. さらにAkkaでは、子どものActorを作り、それぞれに ラウンドロビンでメッセージをブロードキャストしたりすることもできる メールボックス アクター メッセージ address address address address address address ループ
  29. 29. すばらしい! メールボックス アクター メッセージ address address address address address address ループ
  30. 30. Akka Actorの主な特徴 • ActorSystemというActorの実行コン ポーネントが内部的にスレッドプールを 持っており、tellによるメッセージパッシ ングのイベント駆動モデルと、マルチス レッドによる実行の融合がなされている • デフォルトでは、単一実行するMailboxの 実装により逐次メッセージが処理される
  31. 31. Actor同士がリモートで メッセージを送信できる • ActorPathというアドレスを利用 • ロケーション透過性があり、アク ターの物理的な位置をAkka上で は考慮する必要が無い • ポートは自由に設定可能
  32. 32. 耐障害性の機能 • SupervisorがActorを監視しており、処理中 に例外を吐いた時に再実行を行わせたりする ことができる • SupervisorStrategyにより子どものアクター が起こしたエラーの挙動を変えられる • let-it-crashという考え (とっとと壊して新し いモノを再度作ったり、やり直したりする)
  33. 33. Akkaで実現できる機能 • 並行処理 • 分散処理のために子どものアクターを作る • アクターが失敗した時に再実行する • アクターのメッセージの結果をFutureで受け取る (ask) • メッセージの送信元を知る • メッセージ送信のスケジューリング • リモートのアクターへのメッセージ送信 • アクター同士のゴシッププロトコルによるクラスタリング • トランザクションの実行とロールバック • ロギング
  34. 34. どんな用途に向いているか スケールアップ、スケールアウト、耐障害性の必要な • トランザクション処理 • サービスのバックエンド処理 • 並行処理 • 大規模なシミュレーション計算 • バッチ処理 • コミュニケーションハブ • オンラインゲーム、賭けなどの実装 • BIやデータマイニング • 複雑なイベントストリーム処理 http://doc.akka.io/docs/akka/2.3.6/intro/use-cases.html
  35. 35. Akkaの基本的な機能の解説 • Actor • ActorSystem • tell, ask • SupervisorStrategy • ActorPath • DeadLetter • Akka Cluster
  36. 36. Actor • メッセージを受信するためのMailboxと、メッ セージの対する処理を記述するreceiveを持つ • それぞれのActorは、並列に動作するが、1つ のActorは並列にメッセージを処理することは ない • そのため、Actorでスレッドセーフを意識する 必要はない
  37. 37. HelloWorld • Actorにメッセージを送信して表示する
  38. 38. ActorSystem • 複数のActorを構成するために必要な もろもろを管理するクラス • ActorSystemからActorを作っていく ことができる
  39. 39. tell, ask • Actorにメッセージを送信する
  40. 40. tell (別名: “!”) • Actorにメッセージを投げて、 返答を待たない
  41. 41. ask (別名: “?”) • Actorにメッセージを投げて、 返答を待つ ブロッキングするのではなく、 Futureオブジェクトが返る
  42. 42. SupervisorStrategy • Actorは複数の子供Actorを持つことが できる http://doc.akka.io/docs/akka/snapshot/scala/fault-tolerance.html
  43. 43. 親Actor • 子供Actorを管理するための戦略、SupervisorStrategy を持つことができる • 自分で定義することもできるがすでに2つ定義されている 1. OneForOneStrategy - ある子供Actorが例外で停止した時、その子供Actor だけを再起動する 2. OneForAllStrategy - ある子供Actorが例外で停止した時、全ての子供 Actorを再起動する
  44. 44. SupervisorStrategyの 設定の例
  45. 45. ActorPath • ActorにはURIが付いており、それで メッセージを送信できる akka://system/user/MyActor
  46. 46. ActorPathはActorの 親子関係に対応 • MySupervisorがMyActorという子供 Actorを持っている場合 akka://system/user/MySupervisor/MyActor
  47. 47. ActorPathからActorに メッセージを投げる
  48. 48. 存在しないAcotorにメッセー ジを投げたらどうなるの? • DeadLetterになる
  49. 49. DeadLetter • メッセージを投げたけど届かなかった場合 にメッセージはDeadLetterとなる • 以下の場合もDeadLetterになる - 送信したがActorが停止してしまった場合 - Actorが持つメールボックス(メッセージ の入れ物)に追加できなかった場合 ‣ 容量制限に引っかかるなど
  50. 50. Akka Cluster • Akka Remoteを利用した、複数ノード構成 のAkkaアプリケーションを構築するエクス テンション • ノードのメンバー管理、クラスタへのノード のJoin・Leaveを行ってくれている • 参加のやりとりはゴシッププロトコル • 論理時間はベクタークロックアルゴリズム
  51. 51. ノードの役割 • シードノード - 最初にクラスタに参加するノードが接続するためのエン トリーポイント • リーダー - クラスタを管理するノード、リーダーがクラスタから落 ちると別のノードがリーダーに昇格する • ロール - 各ノードに複数のロールを持たせることができる (ただの 文字列)
  52. 52. ノードの一生 • クラスタにJoinしてLeaveするまでの ライフサイクルが存在する
  53. 53. ノードの状態 • ノードは一生の中でいくつかの状態を取る • この状態の管理はリーダーノードが行い、 クラスタ全体で共有される 状態意味 joining クラスタに入ろうとしている up クラスタに正常に入った状態 leaving/exiting クラスタから正常に抜けようとしてる状態 down ノードが落ちた状態 removed クラスタから削除された
  54. 54. Unreachable • 特別な状態、あるノードが通信不能、 ハートビートがタイムアウトした時など • この状態はdown状態と似ているが、ク ラスタ全体で共有されるわけではなく ノードごとに保持している
  55. 55. Unreachableの検出 • 任意のノードがUnreachableかどうか は、ノードのFailureDetector(*fd)と呼 ばれる仕組みにより検出される • 他のノードからはUnreachableではな くとも、自分からはUnreachableであ ることもある
  56. 56. 利用する時に 気をつけること • ActorSystemをたくさん作らない • メッセージに型がない • シリアライズ不可能なメッセージを投げない • DeadLetterに注意する • Mailboxのサイズに注意する • ActorPathに注意する
  57. 57. ActorSystemを たくさん作らない • スレッドプールができるので生成コストが 大きい • ちなみに、以下の2つのActorSystemは 同値ではないので要注意
  58. 58. シリアライズ不可能な メッセージを投げない • Actorはノードをまたいで実行される時 もある • シリアライズ不可能なクラスのインス タンスを投げないこと ➡例外投げて落ちる
  59. 59. メッセージに型がない • Actorが受け取る事のできるメッセージは全部Any • TypedActorというものもあったりするが基本、 メッセージ型を作ったほうが便利 • Actorが処理することができないメッセージを投げ ても、Actorに無視されるだけ ➡DeadLetterにならない ➡Unhandledになる、Loggerで拾うことは可能
  60. 60. DeadLetterに注意する • Actorに処理して欲しいはずなのに処理 してもらっていない • DeadLetterをログに全て出力している の設定を確認する • 何個まで出すかなどの設定がある http://doc.akka.io/docs/akka/2.3.4/scala/logging.html
  61. 61. MailBoxのサイズに 注意する • メッセージが無限に入るので処理が遅 れてることに気がつかない • 対策としては、Mailboxにサイズ制限を 設ける • デフォルトでは無制限
  62. 62. ActorPathに注意する • メッセージを投げたいActorの実装が 変わってActorPathが変わるかもしれ ない • 対策としては、ActorPathのBuilderク ラスを用意したほうが無難
  63. 63. もっとAkkaについて 知りたい • akka-user、akka-devを見る • akkaのコードを読む (https://github.com/ akka/akka) • Effective Akkaという洋書がKindleで読める
  64. 64. 以上 ご静聴ありがとう ございました Special thanks for @suikwasha (Shoshi TAMAKI)
  65. 65. おまけ
  66. 66. Akka Streamsについて • 2014年9月現在実験的機能として公開中 • Akkaの分散、耐障害性の仕組みを利用してス トリーム処理ができる
  67. 67. Akka Streamsの用途 • バルクデータの転送 • リアルタイムデータソース • 巨大データセットのバッチ処理 • 監視/解析 http://www.slideshare.net/rolandkuhn/reactive-streams
  68. 68. Akka StreamsでのFlowの処理例 • データをストリー ムとして処理 • Flowの情報受取 元はTCPを選択す ることもできる http://typesafe.com/activator/template/akka-stream-scala

×