Pythonのツイストのクリーンで軽量な代替手段ですか?[閉まっている]


222

ずっと前に、同時要求を同時に発生させるためにマルチスレッド化したWebスパイダーを作成しました。それは私のPythonの青年期で、GILとそれがマルチスレッドコードに対して作成する関連の問題を知る前の数日間でした(つまり、ほとんどの場合、シリアル化されたものです!)...

このコードを作り直して、コードをより堅牢にし、パフォーマンスを向上させたいと思います。これを行うには、基本的に2つの方法があります。2.6以降の新しいマルチプロセッシングモジュールを使用する方法と、何らかのリアクター/イベントベースのモデルを使用する方法です。後者のほうがはるかに簡単で、エラーが発生しにくいので、後者を使用したいと思います。

質問は、どのフレームワークが私のニーズに最も適しているかに関するものです。以下は、私がこれまでに知っているオプションのリストです。

  • Twisted:Python reactorフレームワークのおじいさん:複雑で少し膨らんでいるように見えます。小さなタスクのための急な学習曲線。
  • Eventlet:で、みんなからリンデン・ラボ。これらの種類のタスクを対象としたGreenletベースのフレームワーク。私はコードを見てみましたが、あまりきれいではありません。pep8に準拠せず、印刷物が散在しています(なぜフレームワークでこれを行うのですか?)、APIは少し矛盾しています。
  • PyEv:未熟です。libeventに基づいているため、現時点ではだれも使用しているようには見えないため、確実なバックエンドがあります。
  • asyncore:stdlibから:非常に低レベルで、何かを実現するためだけに多くのレッグワークが必要なようです。
  • tornado:これは動的Webサイトをサーバーするように設計されたサーバー指向の製品ですが、非同期HTTPクライアントと単純なioloopを備えています。それは仕事を成し遂げることができるように見えますが、それが意図したものではありません。[編集:残念ながらWindowsでは動作しません。これは、私にとってそれを数えます-私がこの不完全なプラットフォームをサポートするための要件です]

見逃したことはありますか?確かに、簡素化された非同期ネットワーキングライブラリのスイートスポットに合うライブラリがそこにあるはずです!

[編集:このページへのポインタを提供してくれたintgrに感謝します。一番下までスクロールすると、このタスクに何らかの形で取り組むことを目的としたプロジェクトの非常に優れたリストが表示されます。実際、Twistedの誕生以来、物事は実際に進んでいるようです。人々は、従来のリアクタ/コールバック指向のソリューションではなく、コルーチンベースのソリューションを好むようです。このアプローチの利点は、より明確で直接的なコードです。特に、boost.asioを使用している場合は、確かに過去に見つかりました。C ++では、コールバックベースのコードは、追跡が困難で、訓練されていない目からは比較的わかりにくい設計につながる可能性があります。コルーチンを使用すると、少なくとも少し同期が取れているように見えるコードを書くことができます。私の今の仕事は、これらの多くのライブラリのどれが私が見た目で気に入っているかを調べて試してみることです!私が今尋ねたのはうれしい...]

[編集:おそらく、この質問をフォローしたりつまずいたり、このトピックについて何らかの意味で気にかけている人にとって興味深いものです。この仕事に利用できるツールの現在の状態について非常にすばらしい記事を見つけました]


14
Python マルチスレッド化されており、2つのスレッドが同時にPythonコードを実行することを許可していません。
intgr 2009

86
私はあなたの質問に対する答えよりも多くのことを学びました。
Denis Otkidach、2009

2
@Denis:ええ、私は推測してくれてありがとう!回答、特にintgrにもいくつかの良い指針があります。私は多くのオプションを知っていて、答えを詰め込んでほしくなかったので、私が知っていることをスペルアウトする問題に行くと思いました:)
jkp

5
>人々は今や、従来のリアクタ/コールバック指向のソリューションではなく、コルーチンベースのソリューションを好むようです。これは賢明な比較ではありません。「コルーチンベースのソリューション」と「リアクター指向」のソリューションは直交しています。(Pythonにコルーチンがないという事実を無視して)TwistedのinlineCallbacksを見て、複雑なプラットフォームの特異性にさらされることのない、堅牢で成熟したネットワーキングレイヤーで、好みのプログラミングスタイルを実現する方法を確認してください。
Jean-Paul Calderone、

2
追加するいくつかのポイント:1.トルネードはWindowsで非常によく動作します。selectI / O多重化に使用するため、パフォーマンスやスケーラビリティが劣るだけです。しかし、tornado-pyuvを使用すると、適切なパフォーマンスを得ることができるはずです。2. Python 3.3以降とそのバックポートトロリウスにasyncioが追加され、イベントループでTornadoアプリケーションを実行できるようになりました(Twistedはまもなくサポートされます)。
シュラマー2014年

回答:


28

Stackless PythonマイクロスレッドまたはGreenletのいずれかを使用して軽量スレッドを実行する同時実行 Pythonモジュールが気に入りました。すべてのブロッキングネットワークI / Oは単一のlibeventループを介して透過的に非同期になるため、実際の非同期サーバーとほぼ同じくらい効率的です。

この点でEventletに似ていると思います。

欠点は、そのAPIがPythonのsockets/ threadingモジュールとはかなり異なることです。アプリケーションのかなりの部分を書き直す必要がある(または互換性シム層を書く)

編集:同様のcogenもあるようですが、Greenletsの代わりに、コルーチンにPython 2.5の拡張ジェネレーターを使用しています。これにより、並行処理や他の代替手段よりも移植性が高くなります。ネットワークI / Oは、epoll / kqueue / iocpを使用して直接行われます。


@intgr:素晴らしいリンク。私はかつて一度にそれらの両方を見たことがあります、それらは私が紅潮して見たいと思っていたようなものです。+1
jkp 2009

3
並行処理は、4年前の最後の更新である死んだプロジェクトのようです。
Gewthen 2013

プロジェクトは死んでいるので、ハイブも死んでいます
バハディールカンベル2014年

1
Python 2.5以降、多くのことが起こりました。Python 3.5のasyncioは素晴らしいです。
ジョセフシーディ

99

Twistedは複雑ですが、あなたはその通りです。ツイストは膨らんでいません

ここを見てみると、http//twistedmatrix.com/trac/browser/trunk/twistedには、インターネットの多くのプロトコルの体系化された包括的で非常に十分にテストされたスイートと、ヘルパーコードが記述されています。非常に洗練されたネットワークアプリケーションを展開します。膨張と包括性を混同しないでください。

Twistedのドキュメントが一見すると最もユーザーフレンドリーではないことはよく知られていますが、これは不幸な人たちを排除するものだと思います。しかし、時間に入れれば、ツイステッドは素晴らしいです(私見)。私はそうしました、そしてそれはそれの価値があるとわかりました、そして私は同じことを試みることを他の人に勧めます。


4
@clemesha:多分あなたは正しい、そしてそれは荷を下されていませんが、単純なことをするために私の頭を動かすには少し多すぎるように感じます。私は非同期プログラミングを理解し、C ++でboost :: asioを使用して作業したので、概念は新しいものではありませんが、ねじれたものを実行することと競合するすべての大胆なものです。繰り返しますが、Webの作業をしているときは、軽量のWSGIコードを使用して、必要なものだけを接続します。私が推測するコースのための馬。
jkp 2009

7
@clemesha:えーと、今日は思い切って見てみました:ツイストした重量は20MBです!コアも12MBです。もしそれが膨らまなければ、私はそれが何であるかはよくわかりません。
jkp 2009

29
基本的なTwisted APIはかなり小さい(リアクター、遅延、プロトコル)。Twistedコードのほとんどは、これらの基本を使用した非同期プロトコル実装です。「Bloat」はここでは有用な形容詞ではありません(実際、ほとんどの場合)。Twistedのサイズは、それが行うものの量に対して妥当です。
daf、

56

geventクリーンアップされたイベントレットです。

APIに関しては、標準ライブラリ(特に、スレッド化モジュールおよびマルチプロセッシングモジュール)と同じ規則に従っており、意味があります。キューイベントなど、使い慣れたものがあります。

それはリアクター実装としてlibeventupdate: libev 1.0以降)のみをサポートしますが、他のほとんどのライブラリのようなスレッドプールを使用するのではなく、libevent-httpに基づく高速WSGIサーバーを備え、libevent-dnを介したDNSクエリを解決します行う。(更新: 1.0以降、非同期DNSクエリを作成するためにc-aresが使用されます。スレッドプールもオプションです。)

eventletのように、それは使用して、コールバックとDeferredの作り方が不要になりgreenletsを

例を確認してください:複数のURLの同時ダウンロードロングポーリングWebチャット


4
私は2番目のgeventをします-多くの解決策を検討した後、geventは私にとって非常にうまくいきました。これにより、既存のプログラムのより良い部分を保持でき、必要な変更は簡単でした-何よりも、コードを3、4、5、...年後に維持する必要がある場合でも、 geventに不慣れな人にとっては、Twistedの最大のショートッパーは強力な学習曲線です。これは、実装時だけでなく、メンテナンス中にさらに問題を引き起こします...
Martin Tournoij

27

このようなフレームワークの非常に興味深い比較は、ニコラスピエルのブログでまとめられています。一読の価値は十分あります。


2
記事が興味深い読み物であったことに同意しますが、提示されたベンチマークの有効性を検討することは価値があると思います。ここのコメントを参照してください:reddit.com/r/programming/comments/ahepg/…– clemesha
12/27

1
@clemesha、そのredditページのポイントは注目に値しますが、ベンチマークはデュアルコアマシンで行われ、記述された致命的な欠陥に悩まされていなかった可能性があります。クライアントとサーバーの両方が同じコアで実行された可能性はあると思いますが、そうは思われません。
Peter Hansen、

15

これらのソリューションはいずれも、GILがCPUの並列処理を妨げるという事実を回避しません。これらは、すでにスレッドで使用しているIO並列処理を取得するためのより良い方法です。IOを改善できると思われる場合は、必ずこれらのいずれかを実行してください。ただし、ボトルネックが結果の処理にある場合は、マルチプロセッシングモジュールを除いて、ここでは役に立ちません。


複数のプロセスを使用することの何が問題になっていますか?
Emil Ivanov

3
何もないため、マルチプロセッシングモジュールを使用することをお勧めします。
Adam Hupp、2010年

11

Twistedを肥大化させるとは言えませんが、頭を回すのは難しいです。「小さなタスク」には少し簡単なものを常に望んでいたので、私はかなり長い間学習に落ち着くのを避けました。

しかし、私はそれでさらに作業をしたので、すべてのバッテリーが含まれていることは非常に素晴らしいと言わざるを得ません。

私がこれまで取り組んできた他のすべての非同期ライブラリは、表示されるほど成熟していない。Twistedのイベントループはしっかりしています。

ツイストの急な学習曲線をどのように解決するのか私にはよくわかりません。誰かがそれをforkして、後方互換性の残骸や死んだプロジェクトをすべて削除するなど、いくつかのことをクリーンアップする場合に役立ちます。しかし、それは私が推測する成熟したソフトウェアの性質です。


Windowsでgtkリアクターがどのように実装されているかを調べたことがある場合(ハードコアポーリング:10ミリ秒ごと:twistedmatrix.com/trac/browser/trunk/twisted/internet/…)、「成熟」とは言えません...
schlamar

2
こんにちは@schlamar。この厄介なハックは、GTK +のかなり深刻なバグの回避策として実装されました。当時は、電力効率についての懸念がはるかに少なかったのです。しかし、Twistedの優れた点は、このバグを1度取得し、フレームワークで修正できることです。ユーザーが心配する必要はありません。この問題に対処し、取り除く(非推奨にして後で削除する)修正を提供しますPortableGtkReactorか?
グリフ2013

1
@Glyph これらの問題の一部がまだ存在するため、他の誰かがこの問題に取り組みたい場合は、twistedmatrix.com / trac / ticket / 4744#comment:2に役立つアドバイスを追加しました。ところで、2つのイベントループ間でコールバックをスケジュールすることで、これをはるかに効率的に解決できます。
シュラマー2014年

7

カメリアはまだ言及されていません。その並行性モデルは、受信ボックスと送信ボックスの間でメッセージが渡されるコンポーネントを一緒に配線することに基づいています。ここでは簡単な概要です。


5
私はアプリにカメリアを使いました-それは非常に苦痛でした。私見Pythonでの一致には他にも優れたオプションがあります(そのほとんどは上記で説明されています)
Ben Ford

7

ツイストを使うようになりました。それの美しさはほとんどそれが「肥大化している」からです。そこにあるほぼすべての主要プロトコル用のコネクタがあります。コマンドを受け取ってircサーバーに投稿したり、誰かにメールで送信したり、コマンドを実行したり、NNTPサーバーから読み込んだり、Webページの変更を監視したりするジャバーボットを持つことができます。悪い知らせは、それがそのすべてを行うことができ、OPが説明するような単純なタスクでは物事を過度に複雑にする可能性があることです。Pythonの利点は、必要なものだけを含めることです。したがって、ダウンロードは20MBになる可能性がありますが、2MBのライブラリのみを含めることができます(まだ大量です)。ツイストに関する私の最大の不満は、例が含まれていますが、基本的なtcpサーバーを超えて自分で使用しているものです。

pythonソリューションではありませんが、node.jsは最近、より多くの牽引力を獲得するのを見てきました。実際、私は小さなプロジェクトのためにそれを調査することを検討しましたが、javascriptを聞いたとき私はちょうどうんざりしています:)


私はPythonの大ファンです。–ダグラス・クロックフォードの「Javascript –良い部分」をチェックしてください(3、4ビデオ)。そして、CoffeeScriptをのぞいてみてください。JSには、構文以外のPythonに必要なものが含まれていることがわかりました。CSはそれを軽減しようとしましたが、少し不器用です...
Robert Siemer

4

この件に関しては、Abe Fettigによる「Twisted Network Programming Essentials」という優れた本があります。これらの例は、非常にPython的なコードを記述する方法を示しています。個人的には、肥大化したフレームワークに基づいているとは思わないでください。本の解決策を見てください、もしそれらがきれいでないなら、私はきれいが何を意味するのかわかりません。

私の唯一の謎は、Rubyのような他のフレームワークと同じです。私は心配します、それはスケールアップしますか?スケーラビリティの問題が発生するフレームワークにクライアントをコミットするのは嫌です。


4

Whizzerは、pyevを使用する小さな非同期ソケットフレームワークです。主にpyevのため、非常に高速です。これは、いくつかのわずかな変更を加えた、同様のインターフェースを提供しようとします。


2

Synclessもお試しください。コルーチンベースです(したがって、Concurrence、Eventlet、geventに似ています)。socket.socket、socket.gethostbyname(etc。)、ssl.SSLSocket、time.sleep、select.selectのドロップイン非ブロッキング置換を実装しています。これは速い。Stackless Pythonとlibeventが必要です。C(Pyrex / Cython)で記述された必須のPython拡張が含まれています。


2

シンクレスの良さを確認。libev(libeventの新しい、よりクリーンでより良いパフォーマンスバージョン)を使用できます。以前はlibeventほどサポートされていませんでしたが、現在は開発プロセスがさらに進んでおり、非常に便利です。



0

まったく異なるアプローチを取る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にあります。


1
これは興味深いものであり、一部のタスクには適しているかもしれませんが、ネットワーキングにスレッドを使用するとパフォーマンスが低下します(特にPythonではGILが原因です)。そしてこれはまさに問題でした:イベントフレームワークまたはマルチプロセッシング。だからあなたの答えは明らかに範囲外です...
シュラマー2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.