web-dev-qa-db-ja.com

akka / erlangでアクターを使用するのがよくないのはいつですか?

私はakkaと毎日7〜8か月間作業しています。私が始めたとき、私はアプリケーションに取り組んでいて、アクターはほとんどのオブジェクト間で通信するためにアクターシステム内で一度基本的にどこでも使用されることに気づきました。だから私は同じことをした-別の俳優をx/y/zにスピンアップする。

これは無差別であり、必要のないところに複雑さを加えているように思えますが、アクターとプレーン同期ロジック、またはフューチャー経由の非同期ロジックをどこで使用するべきかについての議論はありません。同僚が似たようなことを言った後、私は自分のスタンスを考え始めました。最近、いくつかのケースに気づきました。タスクを熟考し、不変の実装で同じ結果を安全に得ることができるため、別のアクターの作成を避けました。たとえば、非常に頻繁にアクセスしない場所でdbまたはファイルから構成値を取得するようなものです。結果が実際の使用例になるまで待ちます。

特に、不変の状態で操作している場合、アクターは複雑さを生み出し、スループットを制限します。たとえば、オブジェクト内の純粋な関数は、並行性のレベルを問わずリスクなしで同時に呼び出すことができます。アクターは一度に1つのメッセージしか処理できません。もう1つの考慮事項は、futureの使用を開始しない限り結果を待つ必要がある場合にスレッドをパークすることですが、非同期メッセージングやスケールについて心配する必要がない場合は、アクターを採用するのはやり過ぎかもしれません。

だから私の質問は-俳優を使うのに悪い時間はありますか?私はアーランがどのように見えるか知りたいと思っています。他の人の洞察を本当に望んでいます。または、俳優の使用に関するいくつかの原則がある場合。

61
JasonG

これは私が興味を持っている質問であり、いくつかの研究を行っています。他の視点については、スタックオーバーフローの Noel Walshによるブログ投稿 または この質問 を参照してください。私が提供したいいくつかの意見があります:

  • Akkaはメッセージで機能するため、「プッシュ型の考え方」を奨励すると思います。しばしば、並行性のために、これはあなたが望むものではないと主張します。プルははるかに安全です。たとえば、分散システムの一般的なパターンの1つは、一連の キュー内の情報を処理するワーカー を持つことです。明らかに これはAkkaで可能です ですが、必ずしも 人々が試す最初のアプローチ であるとは限りません。 Akkaは 耐久性のあるメールボックス も提供していますが、使用方法によって異なります。単一の共有キューは、作業の分散/再割り当てに関して、ワーカーキューごとよりもはるかに柔軟です。
  • クラスをアクターに置き換えるという考え方に入るのは簡単です。実際、一部の人々は 俳優は1つのことだけを行う必要があります と言ってそれを支持しているようです。これは論理的な結論であり、Jasonが説明するようにコードの複雑さが増します。すべてのクラスがアクターである場合、それは多くの余分なメッセージであり、ブロックを受信/送信するためです。また、インターフェースの形式性が失われるため、コードの理解とテストが難しくなります。 コメントはこれに対する解決策です だとは思いません。また、 Akkaの伝説的な効率性 にも関わらず、アクターの増殖はパフォーマンスの点で良いアイデアではないと思います。Javaスレッドを使用する場合、それらは貴重であり、それらを適切に保護します。
  • それは前のポイントに関連していますが、もう1つの不快な点は、NoelとPinoが強調する型情報の損失です。私たちの多くは、Pythonなどの他の言語ではなくScalaを使用している理由です。これにはいくつかの方法がありますが、それらは 非標準非推奨 または 実験的 のいずれかです。
  • 最後に、 "let it crash" マインドセットがあっても、並行性は困難です。 代替プログラミングモデル は役立ちますが、問題を解決しません-それらを変更します-それが 正式に考える に適している理由です。 Joe Average開発者がRabbitMQ、Storm、Hadoop、Spark、KafkaまたはNoSQLデータベースなどの既製のツールを入手する理由もここにあります。Akkaにはいくつかのビルド済みのツールとコンポーネントがあります。はかなり低レベルだと感じているので、分散システムの一般的な要素をすぐに構築できるようにしておくと、開発者の助けとなり、システムが正しく構築されます。

ジェイソンのように、私はここで他の人々の洞察を聞きたいと思っています。上記の問題のいくつかに対処し、Akkaをよりよく使用するにはどうすればよいですか?

23
Mark Butler

アクターモデルの用途を検討する価値があります。アクターモデルは

  1. 並行性モデル
  2. 可変状態への同時アクセスを回避します
  3. 非同期通信メカニズムを使用して並行性を提供する。

複数のスレッドから共有状態を使用することは、特に同期を維持する必要がある共有状態のさまざまなコンポーネント間に関係がある場合、非常に困難になるため、これは価値があります。ただし、次のようなドメインコンポーネントがある場合:

  • 同時実行を許可しない、または
  • (関数型プログラミングのように)変更可能な状態を許可しない、または
  • いくつかの同期通信メカニズムに依存する必要があります。

その場合、アクターモデルは(もしあれば)多くの利点を提供しません。

お役に立てば幸いです。

21
Aidan Cully

あなたの直感は正しいです、私見。どこでも俳優を使用することは、ことわざのハンマーを持って釘だけを見ているようなものです。

Erlangのベストプラクティスは、同時に発生するすべてのアクティビティにプロセス/アクターを使用することです。つまり、実生活と同じです。正しい粒度を見つけるのが難しい場合もありますが、ほとんどの場合は、モデル化されたドメインを見て、常識を少し使用するだけでわかります。それより良い方法はないと思いますが、それが役に立てば幸いです。

12
Vlad Dumitrescu

入力/出力メッセージングで:

私は最近、アクターモデルが実際に同時実行性の問題を引き起こしたakkaベースのアプリケーションに出会いました。単純なモデルは、負荷がかかった場合により十分なものになります。

問題は、着信メッセージが異なる「レーン」で(異なるアクターパスを介して)移動していたが、コードはメッセージが到着したのと同じ順序でメッセージが最終的な宛先に到着すると想定したことでした。データが十分に大きな間隔で到着する限り、宛先に向かって競合するメッセージが1つしかないため、これは機能しました。間隔が減少したとき、彼らは順不同で到着し、奇妙な行動を引き起こし始めました。

問題は少し少ないアクターで正しく解決できたかもしれませんが、それらを使いすぎた場合に犯しやすい間違いです。

0
DHa