web-dev-qa-db-ja.com

ディーゼルを同期アクター、actix_web :: web :: blockまたはfutures-cpupoolを使用して実行する必要がありますか?

バックグラウンド

私は、r2d2を通じてディーゼルを使用するactix-webアプリケーションに取り組んでおり、非同期クエリを最適に作成する方法がわかりません。妥当と思われる3つのオプションを見つけましたが、どれが最適かわかりません。

可能なソリューション

俳優の同期

1つは actixの例 を使用できますが、非常に複雑であり、構築するにはかなりの量のボイラープレートが必要です。より合理的な解決策が存在することを願っています。

Actix_web::web::block

別のオプションとして、 actix_web::web::block クエリ関数を将来にラップしますが、これがパフォーマンスに与える影響はわかりません。

クエリは同じTokioシステムで実行されていますか?私がソースで見つけたものから、 それは基礎となるactix-webスレッドプールにスレッドを作成します 。問題ありますか?

コードを正しく読んだ場合、r2d2は接続を取得するときにそのスレッドをブロックします。これにより、コアのactix-webプールの一部がブロックされます。データベースクエリと同じです。これにより、そのプールにスレッドがあるよりも多くのクエリを実行すると、すべてのactix-webがブロックされますか?もしそうなら、大きな問題。

先物-cpupool

最後に、不要なオーバーヘッドが生じる可能性のある安全な賭けは futures-cpupool です。主な問題は、これがプロジェクトに別のクレートを追加することを意味することですが、アプリケーション内に不必要に複数のcpu-poolが浮かんでいるという考えは好きではありません。

R2d2とディーゼルの両方がブロックするので、ここには驚くほど多くのトリッキーなことが存在します。

最も重要なのは、このcpupoolを同じr2d2プールを使用していないものと共有しないことです(作成されたすべてのスレッドは、r2d2接続の待機をブロックし、作業が存在する場合はプール全体をロックダウンする可能性があるため)。

2番目に(少し明らかに)、プール内のスレッドよりも多くのr2d2接続を使用しないでください。逆に、大きい接続はリソースを無駄にするため(接続が未使用/スレッドが常にブロックされているため)(おそらくもう1つのスレッド、おそらくより速く) cpupoolスケジューラーではなくOSスケジューラーによる接続のハンドオーバー)。

最後に、使用しているデータベースとそこにあるパフォーマンスに注意してください。単一の接続r2d2とプール内の単一のスレッドを実行することは、書き込みの多いsqliteアプリケーションで最適な場合があります(そのような場合は適切なデータベースをお勧めします)。

古い答え

機能する可能性のある古いソリューション

https://www.reddit.com/r/Rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/

本質的に、Futures-cpupoolを推奨します。

blocking I/Oをfuture-rsにカプセル化するための最良のアプローチは何ですか?

一般的な場合はFutures-cpupoolをお勧めします。

機能しない古いソリューション

https://www.reddit.com/r/Rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/

古いactix-webバージョンの本当に素晴らしい修正。私が見つけることができるものから、もはやそれらにCPUプールがありません。

10
logina

Futures-cpupoolを使用します。それは私の相互作用のブロッキングの性質による最良の解決策です。

Actix_web :: web :: blockの使用は十分ですが、actixで共有スレッドプールを使用します(ブロッキング呼び出しのため、これを使用してスレッドプール全体をブロックし、actix_webに与えられた他のタスクを妨害することができます)。

データベースの相互作用のためだけに、futures-cpupoolを使用してデータベースごとに個別のスレッドプールを作成することをお勧めします。このようにして、相互に待機する必要があるすべてのタスク(接続よりもタスクが多い場合)を1つのプールにグループ化し、接続を必要としない他のタスクをブロックするのを防ぎ、スレッド数を接続の数(ブロックされないときにのみタスクがスケジュールされるようにするため)。

1つのデータベース接続のみ(またはごくわずか)を使用したい場合は、同期アクターはかなり良いオプションです。これは、1つのスレッドを持つfutures-cpupoolのように動作し、すべてのタスクが一度に1つずつ実行されることを保証します。ただし、別個のスレッドではなく、actix-webの基盤となるスレッドの1つを使用します(したがって、接続数が非常に少ない場合にのみ有効です)。 。ただし、定型文は大きすぎて価値がありません。

2
logina