Pythonのツイストに代わるクリーンで軽量な代替物ですか? [閉まっている]
-
22-07-2019 - |
質問
A(長い)前に、同時要求が同時に発生するようにマルチスレッド化したWebスパイダーを作成しました。それは、 GIL と関連するものを知っていた数日前の、Pythonの若さでしたマルチスレッドコードのために作成する問題(つまり、ほとんどの場合、最終的にはシリアル化されます!)...
このコードを作り直して、堅牢性とパフォーマンスを向上させたいと思います。これを行うには、基本的に2つの方法があります。2.6では、新しいマルチプロセッシングモジュールを使用できます。 +または、何らかのリアクター/イベントベースのモデルに行くことができます。はるかにシンプルでエラーが発生しにくいので、後者の方がいいでしょう。
質問は、どのフレームワークが私のニーズに最も適しているかということです。以下は、これまでに知っているオプションのリストです。
- ツイスト:Pythonリアクタフレームワークの祖父:複雑で少し肥大しているようです。小さなタスクの急な学習曲線。
- イベントレット: lindenlab 。これらの種類のタスク向けのGreenletベースのフレームワーク。私はコードを見ましたが、あまりきれいではありません:非pep8準拠で、プリントが散らばっています(なぜフレームワークでこれを行うのですか??)、APIは少し矛盾しているようです。
- PyEv :未熟、今のところ誰も使っていないようですlibeventに基づいているため、強固なバックエンドを持っています。
- asyncore :stdlibから:überlow-level、like a lot of地面から何かを得るためだけに必要なレッグワーク。
- tornado :これは、動的なWebサイトをサーバーするために設計されたサーバー指向の製品ですが、非同期HTTPクライアントと簡単な ioloop 。それは仕事を成し遂げることができるように見えますが、それが意図したものではありません。 [編集:残念ながらWindowsで実行されないため、私にとってはカウントされません-この不自由なプラットフォームをサポートするための要件です]
見逃したことはありますか?単純化された非同期ネットワーキングライブラリのスイートスポットに適合するライブラリが必ずあるはずです!
[編集: intgr のこのページ。一番下までスクロールすると、このタスクに何らかの方法で取り組むことを目的とするプロジェクトの本当に素晴らしいリストが表示されます。実際、Twistedの開始以来、物事は実際に進んでいるようです。人々は co-routine 従来のリアクター/コールバック指向のソリューションではなく、ベースのソリューション。このアプローチの利点は、より直接的で明確なコードです。特に boost.asio は、コールバックベースのコードは、追跡が難しく、訓練されていない目には比較的わかりにくいデザインにつながる可能性があります。コルーチンを使用すると、少なくとも少し同期したコードを作成できます。今、私のタスクは、私がこれらの多くのライブラリのどれを気に入っているかを見つけ出し、試してみることです!よろしくお願いします...]
[編集:おそらく興味のあるt
解決
Stackaless Pythonマイクロスレッドまたは軽量のGreenletsに依存する concurrence Pythonモジュールが気に入ったスレッド。すべてのブロッキングネットワークI / Oは、単一の libevent
ループを介して透過的に非同期に行われるため、実際の非同期サーバーとほぼ同じくらい効率的です。
この方法でEventletに似ていると思います。
欠点は、そのAPIがPythonの sockets
/ threading
モジュールとはまったく異なることです。アプリケーションのかなりの部分を書き換える(または互換性shimレイヤーを作成する)必要があります
編集: cogen もあるようです。は似ていますが、GreenletではなくPython 2.5の拡張ジェネレーターをコルーチンに使用します。これにより、並行性や他の代替手段よりも移植性が高くなります。ネットワークI / Oはepoll / kqueue / iocpで直接行われます。
他のヒント
Twistedは複雑です、あなたはそれについて正しいです。 Twistedは肥大化していません 。
こちらをご覧ください: http://twistedmatrix.com/trac/browser/ trunk / twisted には、非常に洗練されたネットワークアプリケーションを記述および展開するためのヘルパーコードだけでなく、インターネットの多くのプロトコルの体系的で包括的で非常にテスト済みのスイートがあります。肥大化と包括性を混同しないでください。
Twistedのドキュメントは一見するとユーザーにとって使いやすいものではないことはよく知られていますが、これは不幸な数の人々を追い払うと信じています。しかし、時間を入れると、Twistedはすごいです(IMHO)。私はやったが、それは価値があることがわかったので、他の人に同じことを試してみることをお勧めします。
APIに関しては、意味のある標準ライブラリ(特に、スレッド化およびマルチプロセッシングモジュール)と同じ規則に従います。したがって、 Queue や動作するイベント。
libevent (更新: < href = "http://blog.gevent.org/2011/04/28/libev-and-libevent/" rel = "nofollow noreferrer"> 1.0以降のlibev )をリアクター実装として使用しますが、最大限に活用しますそれは、libevent-httpに基づく高速WSGIサーバーを特徴とし、他のほとんどのライブラリが行うようにスレッドプールを使用するのではなく、libevent-dnを介してDNSクエリを解決します。 (更新: 1.0 c-aresは非同期DNSクエリの作成に使用されるため、スレッドプールもオプションです。)
イベントレットと同様に、グリーンレットを使用して、コールバックと遅延を不要にします。
例を確認します。複数のURLの同時ダウンロード、ロングポーリングウェブチャット。
このようなフレームワークの興味深い比較がNicholas Pi&#235によってコンパイルされました。彼のブログのl:読む価値があります!
これらの解決策のいずれも、GILがCPUの並列処理を妨げるという事実を回避しません。これらは、すでにスレッドで使用しているIO並列処理を取得するより良い方法です。 IOを改善できると思う場合は、必ずこれらのいずれかを実行してください。ただし、ボトルネックが結果の処理にある場合は、マルチプロセッシングモジュール以外は何も役に立ちません。
Twistedを肥大化したとは言いませんが、頭を包むのは難しいです。私はいつも「小さなタスク」のために少し簡単なものが欲しかったので、かなり長い間学習に落ち着くことを避けました。
しかし、もう少し作業を進めたので、すべてのバッテリーが含まれているのはとてもいいことだと言わざるを得ません。
私が取り組んだ他のすべての非同期ライブラリは、見た目ほど成熟していません。 Twistedのイベントループは安定しています。
急なツイスト学習曲線をどのように解くかはよくわかりません。誰かがそれを分岐させて、後方互換性の残骸をすべて削除し、プロジェクトを削除するなど、いくつかのことをクリーンアップすると役立つかもしれません。しかし、それが成熟したソフトウェアの性質だと思います。
私はいくつかのことにねじれを使い始めました。それのほとんどの美しさは、「肥大化」しているためです。ほぼすべての主要なプロトコル用のコネクタがあります。コマンドを受け取ってircサーバーにポストし、それらをメールで送信し、コマンドを実行し、NNTPサーバーから読み取り、Webページの変更を監視するジャバーボットを使用できます。悪いニュースは、それがすべてを行うことができ、OPが説明したような単純なタスクのために物事を過度に複雑にすることができるということです。 pythonの利点は、必要なものだけを含めることです。そのため、ダウンロードは20 MBになる可能性がありますが、2 MBのライブラリのみを含めることができます(これはまだたくさんあります)。ツイストに関する私の最大の不満は、あなたが自分で持っている基本的なtcpサーバーを超えた例が含まれていることです。
Pythonのソリューションではありませんが、最近ではnode.jsがより多くの牽引力を得るのを見てきました。実際、私はより小さなプロジェクトのためにそれを検討することを検討しましたが、javascriptを聞いたとき私はただうんざりしています:)
このテーマに関する良い本があります:「Twisted Network Programming Essentials」、Abe Fettig著。この例は、非常にPythonicなコードを記述する方法を示していますが、個人的には、肥大化したフレームワークに基づいているとは思いません。本の解決策を見てください。もしそれらがきれいでなければ、きれいとはどういう意味か分かりません。
私の唯一の謎は、Rubyのような他のフレームワークと同じです。心配です、スケールアップしますか?スケーラビリティの問題が発生するフレームワークにクライアントをコミットするのは嫌です。
Whizzer は、pyevを使用する小さな非同期ソケットフレームワークです。主にpyevが原因で非常に高速です。わずかな変更を加えて、ツイストされた類似のインターフェースを提供しようとします。
同期なしも試してください。これはコルーチンベースです(したがって、Concurrence、Eventlet、およびgeventに似ています)。 socket.socket、socket.gethostbyname(など)、ssl.SSLSocket、time.sleep、select.selectのドロップイン非ブロッキング置換を実装します。これは速い。 Stackless Pythonとlibeventが必要です。 Cで記述された必須のPython拡張(Pyrex / Cython)が含まれています。
syncless の良さを確認します。 libev(libeventのより新しく、よりクリーンでパフォーマンスの良いバージョン)を使用できます。過去にはlibeventほどのサポートはありませんでしたが、開発プロセスはさらに進んでおり、非常に便利です。
単純で軽量なHTTPリクエストライブラリが必要な場合は、 Unirest が非常に優れている
>PyWorksをご覧ください。まったく異なるアプローチを採用しています。オブジェクトインスタンスを独自のスレッドで実行し、そのオブジェクトへの関数呼び出しを非同期にします。
クラスがオブジェクトではなくタスクから継承するようにし、それが非同期である場合、すべてのメソッド呼び出しはプロキシです。戻り値(必要な場合)は、Futureプロキシです。
res = obj.method( args )
# code continues here without waiting for method to finish
do_something_else( )
print "Result = %d" % res # Code will block here, if res not calculated yet
PyWorksは http://bitbucket.org/raindog/pyworks
にあります。