27

Akka を使用して着信タスクを処理するシステムを実装するシナリオを考えてみましょう。タスクを受け取り、タスクを処理するいくつかのワーカー アクターにディスパッチするプライマリ アクターがあります。

私の最初の本能は、ディスパッチャーが受信タスクごとにアクターを作成するようにすることで、これを実装することです。ワーカー アクターがタスクを処理した後、停止します。

これは、「1 つのタスク、1 つのアクター」の原則に準拠しているため、私にとって最もクリーンなソリューションのようです。もう 1 つの解決策は、アクターを再利用することですが、これには、クリーンアップといくつかのプール管理が非常に複雑になります。

Akka のアクターが安いことは知っています。しかし、アクターの繰り返しの作成と削除に関連する固有のコストがあるかどうか疑問に思っています。Akka がアクターの簿記に使用するデータ構造に関連する隠れたコストはありますか?

負荷は、1 秒あたり数十または数百のタスクのオーダーである必要があります。これは、要求ごとに 1 つのアクターを作成する実稼働 Web サーバーと考えてください。

もちろん、正しい答えは、入ってくる負荷のタイプに基づいたシステムのプロファイリングと微調整にあります。しかし、誰かが自分の経験から何かを教えてくれませんか?

後で編集:

当面のタスクについて、さらに詳しく説明する必要があります。

  • ある時点で実行できるアクティブなタスクは N 個だけです。@drexinが指摘したように、これはルーターを使用して簡単に解決できます。ただし、タスクの実行は、単純に実行して完了するタイプのものではありません。
  • タスクは、他のアクターまたはサービスからの情報を必要とする場合があるため、待機してスリープ状態になる必要がある場合があります。そうすることで、実行スロットを解放します。スロットは、現在実行する機会がある別の待機中のアクターによって取得できます。プロセスが 1 つの CPU でスケジュールされる方法に例えることができます。
  • 各ワーカー アクターは、タスクの実行に関して何らかの状態を維持する必要があります。

注:私の問題に対する別の解決策を高く評価しており、それらを考慮に入れます。ただし、Akka でのアクターの集中的な作成と削除に関する主な質問への回答もお願いします。

4

4 に答える 4

21

リクエストごとにアクターを作成するのではなく、ルーターを使用して動的な量のアクターにメッセージをディスパッチする必要があります。それがルーターの目的です。詳細については、ドキュメントのこの部分をお読みください: http: //doc.akka.io/docs/akka/2.0.4/scala/routing.html

編集:

トップレベルのアクター(system.actorOf)の作成にはコストがかかります。これは、すべてのトップレベルのアクターがエラーカーネルも初期化するため、コストがかかるためです。(アクター内に)子アクターを作成するcontext.actorOf方がはるかに安価です。

ただし、アクターの作成と削除の頻度によっては、GCにも追加のプレッシャーがかかるため、これを再考することをお勧めします。

edit2:

そして最も重要なのは、アクターはスレッドではないということです。したがって、1Mのアクターを作成した場合でも、それらはプールにある数のスレッドでのみ実行されます。したがって、構成のスループット設定に応じて、スレッドがプールに再び解放される前に、すべてのアクターがn個のメッセージを処理します。

スレッドをブロックすると(スリープを含む)、スレッドはプールに戻されないことに注意してください。

于 2012-12-10T20:59:02.540 に答える
8

作成直後に1つのメッセージを受信し、結果を送信した直後に死ぬアクターは、未来に置き換えることができます。先物は俳優よりも軽量です。

pipeTo完了したら、を使用して将来の結果を受け取ることができます。たとえば、アクターで計算を開始します。

def receive = {
  case t: Task => future { executeTask( t ) }.pipeTo(self)
  case r: Result => processTheResult(r)
}

を返すためにexecuteTask関数はどこにありますか。TaskResult

ただし、@ drexinの回答で説明されているように、プールからルーターを介してアクターを再利用します。

于 2012-12-10T21:09:13.867 に答える
0

アクターは優れた有限状態マシンを作成するため、設計をここで推進するのに役立ちます。リクエストごとに1つのアクターを持つことでリクエスト処理状態が大幅に簡素化される場合は、それを行います。経験則として、アクターは 2 つ以上の状態を管理するのが特に得意であることがわかりました。

ただし、一般的には、独自の状態の一部として保持するコレクション内から要求状態を参照する 1 つの要求処理アクターが一般的なアプローチです。これは、Akka リアクティブ ストリームとスキャン ステージの使用でも実現できることに注意してください。

于 2019-08-03T21:12:20.817 に答える