狠狠撸
Submit Search
Developing an Akka Edge6
?
10 likes
?
2,372 views
saaaaaaki
Follow
Developing an Akka EdgeというAkkaの入門書を読んで勉強しています。 要約して社内勉強会で発表した時のスライドを手直ししたものです
Read less
Read more
1 of 67
Download now
Downloaded 21 times
More Related Content
Developing an Akka Edge6
1.
Developing an Akka
Edge Chapter 6
2.
前回のおさらい (Chapter 6の前に…)
3.
?結局… アクターはメッセージを到着した順に1つずつ処理する メッセージが来たら、あらかじめ定義されたふるまいを実行する
4.
Putting actors to
work アクターを使うのにまず必要な事 ?akka.actor.Actorトレイトを継承したクラスと、そこにreceiveメソッドを定義 ?ActorSystemを作る ?ActorSystemからアクターを生成
5.
メッセージの送り方② ask Futureを返す Futureが含んでいる値(処理済/まだ処理されていない/永遠に処理されない) 永遠に処理されない可能性もあるので、implicit valを使って時間を設定 アクターへ送るメッセージは非同期なので、アクター以外のコード内でレスポンスを得 るにはFutureを使う必要がある
6.
Developing an Akka
Edge Chapter 6
7.
Developing an Akka
Edgeだけでは理解できない部分があったため、 AkkaとJavaのDocument Let it crash Akka Concurrency Java言語で学ぶデザインパターン入門 も参考にしました。 (今回はもはや本の要約じゃないです) これまでと同様に 自分が持っていた知識やいくつかの情報を元にまとめたり、 不慣れな英語を読み進めているため正しくない項目がある可能性があります。
8.
Chapter 6.Dispatchers *この章のポイント* ?いろんな顿颈蝉辫补迟肠丑别谤といろんなパラメータ 2つのexecutor(Fork/JoinとThreadPoolExecutor) ?いろんなMailboxとパラメータ ?ざっくりした使用例とチューニングについて
9.
Chapter 6.Dispatchers DispatcherとRouterは全然別物!! Dispatcherのコンセプト アクターが処理を実行する時のスレッド割当 スレッドプールを持っていて、スレッドをアクターに割り当てる
10.
導入 Dispatcherを使うと…?
11.
Low latency 例:特定のActorに1スレッド丸ごと割り当てると…
12.
Low latency 例:特定のActorに1スレッド丸ごと割り当てると… スレッドが割り当てられるのを待たなくて良いので メッセージをすぐ処理してくれる
13.
Bulkhead Pattern 例:IO処理と計算処理のActor達を別のDispatcherにすると…
14.
Bulkhead Pattern 例:IO処理と計算処理のActor達を別のDispatcherにすると… 計算処理Dispatcherのスレッド数を多くするなど IO と
计算のどっちに比重を置くかチューニングができる
15.
Dispatcherのメリット システムのある一部において 応答性UP 負荷分散 パフォーマンスUP チューニング が可能!! (また、耐障害性もUP?)
16.
顿颈蝉辫补迟肠丑别谤の设定
17.
顿颈蝉辫补迟肠丑别谤の设定 デフォルトの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } }
18.
顿颈蝉辫补迟肠丑别谤の设定 デフォルトの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } } ← Dispatcherの名前 後でコード上から呼び出す時に使う。 好きな名前で
19.
顿颈蝉辫补迟肠丑别谤の设定 デフォルトの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } } ← Dispatcherの種類 Dispatcher PinnedDispatcher BalancingDispatcher CallingThreadDispatcher から選ぶ
20.
顿颈蝉辫补迟肠丑别谤の设定 デフォルトの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } } ←executorの種類 fork-join-executor thread-pool-executor から選ぶ 並列処理の実行の仕方が違う
21.
顿颈蝉辫补迟肠丑别谤の设定 デフォルトの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } } ← throughput この値は、 Actorにスレッドを割り当てた時 1回あたりいくつのメッセージを処理するか (終わったらスレッドプールに戻る)
22.
throughputとfairness throughput = 1の時 Actor1のメッセージを1つ処理 Actor2の… Actor3の… Actor1の… Actor3のMailboxが最初に空になる
23.
throughputとfairness throughput = 100の時 Actor1のメッセージを100つ処理 Actor2の… Actor3の… Actor1のMailboxが最初に空になる throughput
= 1だと公平にメッセージを処理できるが、 切り替えが頻繁に起こるとパフォーマンスが悪くなる
24.
顿颈蝉辫补迟肠丑别谤の设定 デフォルトの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } } ← このへんは スレッド数の設定的な感じ thread-pool-executorを使う時は別の項目
25.
Fork/Join と ThreadPoolExecutor
26.
Fork/Joinとは タスクを分割していって、それらを並列に処理していくフレームワーク Java7から導入された a + b
+ c + d ちゃんと理解してないので雑な説明 …
27.
Fork/Joinとは タスクを分割していって、それらを並列に処理していくフレームワーク Java7から導入された a + b
= e c + d = f a + b + c + d ちゃんと理解してないので雑な説明 …
28.
Fork/Joinとは タスクを分割していって、それらを並列に処理していくフレームワーク Java7から導入された e + f a
+ b = e c + d = f ちゃんと理解してないので雑な説明 …
29.
Fork/Joinとは タスクを分割していって、それらを並列に処理していくフレームワーク Java7から導入された タスクを細分化して…というのがActorの設計と似ているので、相性が良い
30.
fork-join-executorの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } } CPUのコア数×factor ?並列実行するスレッド数 ただし、min < スレッド数
< max
31.
ThreadPoolExecutorとは java.util.concurrent.ThreadPoolExecutor ワーカスレッドを管理するクラス タスクキューを持っていて スレッドプールのスレッドを使ってタスクを実行 ?終わったらスレッドプールにスレッドがもどる というのを繰り返している スレッド
32.
thread-pool-executorの設定 my-thread-dispatcher{ type=Dispatcher executor="thread-pool-executor" thread-pool-executor{ core-pool-min = 4 core-pool-max
= 32 core-pool-factor = 2.0 max-pool-min = 8 max-pool-max = 84 max-pool-factor = 3.0 keep-alive-time = 30ms task-queue-type = “linked” } core-poolとmax-pool それぞれの設定がある
33.
corePoolとmaxPool 新しいタスクが、キューに追加された時 ①corePoolSize > 実行中のスレッド数 新しいスレッドが作成される ②corePoolSize
< 実行中のスレッド数 < maxPoolSize キューが一杯の時のみ新しいスレッドが作成される ③maxPoolSize == 実行中のスレッド数 キューが一杯ならタスクがrejectされる
34.
keep-alive-time corePoolSize < 実行中のスレッド数 の時 タスクキューが空で暇なスレッドがあったら… アイドル状態がkeep-alive-timeを超えるとスレッドが終了する
35.
task-queue-type LinkedBlockingQueue(サイズ上限なし) ArrayBlockingQueue(サイズ上限指定) から選ぶ ※LinkedBlockingQueueを使うと、corePoolSizeの全てのスレッドがbusy状態の時 新しいタスクはキュー内にどんどんたまっていくので corePoolSizeを超えるスレッドは作成されない※ 大きなキューと小さなプールを使用すると、スループットが低下する恐れあり (CPU使用率?context switchingのオーバーヘッドは最小化される)
36.
thread-pool-executorの設定 my-thread-dispatcher{ type=Dispatcher executor="thread-pool-executor" thread-pool-executor{ core-pool-min = 4 core-pool-max
= 32 core-pool-factor = 2.0 max-pool-min = 8 max-pool-max = 84 max-pool-factor = 3.0 keep-alive-time = 30ms } }
37.
いろんな顿颈蝉辫补迟肠丑别谤
38.
いろんな顿颈蝉辫补迟肠丑别谤 Dispatcher デフォルトで使っている PinnedDispatcher BalancingDispatcher CallinThreadDispatcher akka.testkitに入ってるので、9章で登場するかも!?
39.
いろんな顿颈蝉辫补迟肠丑别谤 Dispatcher デフォルトで使っている PinnedDispatcher BalancingDispatcher CallinThreadDispatcher akka.testkitに入ってるので、9章で登場するかも!?
40.
PinnedDispatcher それぞれのアクターに1スレッドずつ割り当てる。 ?全てのアクターがスレッドをフルに使える 特に優先度が高いリソースを持っている時に使う ※このパターンを使いすぎないように!!※
41.
BalancingDispatcher 1つのMailboxをシェアしている。 暇になったActorがメッセージを処理するので、負荷は公平 全て同じ型のActorと使う事を想定されている (型が違っても、受け取れるメッセージが同じなら動きそう)
42.
6种の惭补颈濒产辞虫
43.
6种の惭补颈濒产辞虫 UnboundedMailbox SingleConsumerOnlyUnboundedMailbox BoundedMailbox UnboundedPriorityMailbox BoundedPriorityMailbox Durable
44.
6种の惭补颈濒产辞虫 UnboundedMailbox SingleConsumerOnlyUnboundedMailbox BoundedMailbox UnboundedPriorityMailbox BoundedPriorityMailbox Durable 1つのActorに1つのMailbox (デフォルトはこれ) 他のMailboxが全部シェアしているのかは未確認です …
45.
6种の惭补颈濒产辞虫 UnboundedMailbox SingleConsumerOnlyUnboundedMailbox BoundedMailbox UnboundedPriorityMailbox BoundedPriorityMailbox Durable Mailboxの容量が 有限 or
无限
46.
6种の惭补颈濒产辞虫 容量が有限の時のパラメータ mailbox-capacity Mailboxの容量 mailbox-push-timeout-time Mailboxが一杯の時、空くのを待つ時間(?) -1にすると无限
47.
6种の惭补颈濒产辞虫 UnboundedMailbox SingleConsumerOnlyUnboundedMailbox BoundedMailbox UnboundedPriorityMailbox BoundedPriorityMailbox Durable Mailbox内のメッセージに 優先度付き
48.
6种の惭补颈濒产辞虫 extendsして使う Intで優先度を指定 (0が優先度最高)
49.
6种の惭补颈濒产辞虫 UnboundedMailbox SingleConsumerOnlyUnboundedMailbox BoundedMailbox UnboundedPriorityMailbox BoundedPriorityMailbox Durable Mailboxのメッセージを 永続化できる (ファイルシステム)
50.
ここまで長くなりましたが… 実際にDispatcherを使う
51.
Dispatcherを使う ①ActorにDispatcherを設定する場合 val myActor =
system.actorOf(Props[MyActor].withDispatcher(“my-dispatcher”)) Actorの設定をconfigurationに書いていれば、withDispatcherを使わなくてもよい val myActor = system.actorOf(Props[MyActor],”myactor”) akka.actor.deployment{ /myactor{ dispatcher = my-dispatcher } }
52.
Dispatcherを使う ②FutureのためにDispatcherを使う場合 implicit val executionContext
= system.dispatchers.lookup(“my-dispatcher”)
53.
Mailboxを使う myMailbox{ mailbox-type = “BoundedMailbox” mailbox-capacity
= 1000 mailbox-push-timeout-time = 1 } val myActor = system.actorOf(Props[MyActor].withMailbox(“myMailbox”) Dispatcherの時と同様に、akka.actor.deployのActorの設定内に書いてもよい
54.
使用例 Akka Concurrencyの When to
choose a dispatching method参照
55.
Low latency ? PinnedDispatcherを使う 例:特定のActorに1スレッド丸ごと割り当てると… スレッドが割り当てられるのを待たなくて良いので メッセージをすぐ処理してくれる
56.
Bulkhead Pattern ?
Dispatcherを使う 例:IO処理と計算処理のActor達を別のDispatcherにすると… 計算処理Dispatcherのスレッド数を多くするなど IO と 计算のどっちに比重を置くかチューニングができる
57.
cruch…ボリボリ噛む なるべく全てのActorをbuzyにしたい時 Number cruching ?
叠补濒补苍驳颈苍驳顿颈蝉辫补迟肠丑别谤を使う
58.
IO処理が伴うので、Durableを使う時は他のアクターと分離させる Message durability? DurableとDispatcherを使う
59.
チューニングについて Let it crashの Tuning
Dispatchers in Akka Applications参照
60.
顿颈蝉辫补迟肠丑别谤の设定 デフォルトの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } } なんやかんや言っても デフォルト設定で良い場合が多い
61.
Typesafe Consoleでチェック Dispatcher view
でメッセージハンドリングのlatency、mailbox-sizeなどが見れる (ちゃんと調べてませんが、現在は無料で使えないようです…)
62.
profilingしてheavy computationな部分を特定し ?RouterとBalancingDispatcherを使って外に出す mailbox sizeが増え続けているならRouterを作った方がよい デフォルトでもスレッド数の上限が決まっているので、 コア数を増やしても別のDispatcherを使わないと futureがタイムアウトになったり、スループットが上がらない
63.
type デフォルトの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } } ← Dispatcherの種類 最優先処理がある場合PinnedDispatcher (よっぽど特別な場合だけ使用する) 負荷分散したい時はRouterとBalancingDispatche
64.
executor デフォルトの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } } ←executorの種類 fork-join-executorの方が良い (PinnedDispatcherはthread-pool-のみ)
65.
Let it crashの記事より、thread-poolからfork-joinにしたら1100%増になった Throughput比較 task-queueへのアクセス/ロックが多い
? context switchingが発生しやすい
66.
throughput デフォルトの設定 default-dispatcher{ type=Dispatcher executor="fork-join-executor" throughput=10 fork-join-executor{ parallelism-min=4 parallelism-max=32 parallelism-factor=4.0 } } ← throughput Actor数≒スレッド数なら多め 時間のかかるタスクが多いなら少なめ (頻繁に切り替わると時間がかかる) デフォルト値から初めてチューニングすべし
67.
まとめ ?Actorにスレッドが割り当てられると、数個のメッセージを処理して スレッドプールに戻る ?パフォーマンスが悪い部分を別DispatcherとかRouterで切り出す ?Actorを小さく作れば、どのDispatcherに属させるか柔軟にチューニングできそう(チームの先 輩談)
Download