파이썬의 트위스트에 대한 깨끗하고 가벼운 대안? [닫은]


222

(오래 전에) 동시 요청이 동시에 발생할 수 있도록 멀티 스레드 된 웹 스파이더를 작성했습니다. 그것은 GIL 과 멀티 스레드 코드 (IE, 대부분의 경우 물건이 직렬화됩니다!

이 코드를 다시 작성하여 더욱 강력하고 성능을 향상 시키려고합니다. 기본적으로 두 가지 방법이 있습니다. 2.6+에서 새로운 멀티 프로세싱 모듈 을 사용 하거나 일종의 리액터 / 이벤트 기반 모델을 사용할 수 있습니다. 훨씬 간단하고 오류가 적기 때문에 나중에 수행하려고합니다.

따라서 질문은 내 요구에 가장 적합한 프레임 워크와 관련이 있습니다. 다음은 지금까지 내가 알고있는 옵션 목록입니다.

  • 뒤틀린 : 파이썬 반응기 프레임 워크의 할아버지 : 복잡하고 약간 부풀어 오른 것처럼 보입니다. 작은 작업을위한 가파른 학습 곡선.
  • 이벤트 : lindenlab 의 사람들 로부터 . 이러한 종류의 작업에 맞춰진 Greenlet 기반 프레임 워크. 나는 코드를 살펴 보았지만 너무 아름답 지 않습니다 : pep8과 호환되지 않고 인쇄물에 흩어져 있습니다 (왜 사람들이 프레임 워크에서 이것을합니까!?), API는 약간 일치하지 않는 것 같습니다.
  • PyEv : 미성숙합니다. libevent를 기반으로하지만 지금은 아무도 사용하지 않는 것처럼 보이므로 확실한 백엔드가 있습니다.
  • asyncore : stdlib에서 : über low-level, 그냥 뭔가를 얻기 위해 많은 레그 워크가 필요합니다.
  • 토네이도 :이 제품은 동적 웹 사이트를 위해 설계된 서버 지향 제품이지만 비동기 HTTP 클라이언트 와 간단한 ioloop를 갖추고 있습니다. 작업을 수행 할 수는 있지만 의도 한 작업이 아닌 것 같습니다. [편집 : 불행히도 Windows에서 실행되지 않습니다.이 기능은 나에게 도움이됩니다.이 절름발이 플랫폼을 지원해야합니다.]

내가 놓친 것이 있습니까? 분명히 간단한 비동기 네트워킹 라이브러리의 스위트 스팟에 맞는 라이브러리가 있어야합니다!

[편집 : 이 페이지에 대한 그의 포인터에 대해 intgr 에게 감사드립니다 . 맨 아래로 스크롤하면이 작업을 한 가지 방법으로 해결하려는 정말 훌륭한 프로젝트 목록이 표시됩니다. 실제로 Twisted가 시작된 이래로 상황이 실제로 이동 한 것 같습니다. 사람들은 이제 기존의 리액터 / 콜백 지향 솔루션이 아닌 코 루틴 기반 솔루션 을 선호하는 것 같습니다 . 이 접근법의 이점은 더 분명한 직접 코드입니다. 과거에 특히 boost.asio로 작업 할 때 발견했습니다.C ++에서 콜백 기반 코드는 따르기 어렵고 훈련되지 않은 눈에 비교적 모호한 디자인으로 이어질 수 있습니다. 코 루틴을 사용하면 적어도 좀 더 동 기적으로 보이는 코드를 작성할 수 있습니다. 이제 내 임무는이 많은 라이브러리 중 하나를 내가 좋아하는 모양으로 만들어서 해결하는 것입니다. 다행이다 ...]

[편집 : 아마도 다음에 또는 어떤 의미에서이 주제에 대한이이 질문이나 염려에 우연히 사람의 관심 : 난의 현재 상태 정말 좋은 작성자 발견 가능한 도구를 이 작업]


14
파이썬 멀티 스레드 방식이므로 두 개의 스레드가 동시에 파이썬 코드를 실행할 수 없습니다.
intgr 2009

86
나는 당신의 질문에서 대답보다 훨씬 더 많은 것을 배웠습니다.
Denis Otkidach 2009

2
@ 데니스 : 흠, 고마워요! 답변에 좋은 포인터, 특히 intgr이 있습니다. 나는 거기에 많은 옵션에 대해 알고 있었고 그 답변으로 가득 찬 답변을 원하지 않았기 때문에 내가 아는 것을 철자하는 데 어려움을 겪을 것이라고 생각했습니다. :)
jkp

5
> 사람들은 이제 전통적인 리액터 / 콜백 지향적 인 솔루션보다는 코 루틴 기반 솔루션을 선호하는 것 같습니다. 이것은 합리적인 비교가 아닙니다. "공동 루틴 기반 솔루션"및 "반응기 지향"솔루션은 직교합니다. (Python에 코 루틴이 없다는 사실을 무시 함) Twisted의 inlineCallbacks를 살펴보면 복잡한 플랫폼 특유성에 노출되지 않는 강력하고 성숙한 네트워킹 레이어로 선호하는 프로그래밍 스타일을 얻는 방법을 볼 수 있습니다.
Jean-Paul Calderone

2
몇 가지 추가 할 점 : 1. Tornado는 Windows에서 매우 잘 실행됩니다. selectI / O 멀티플렉싱에 사용 하기 때문에 성능과 확장 성이 떨어 집니다. 그러나 당신은 tornado-pyuv를 사용하여 적절한 성능을 얻을 수 있어야합니다 . 2. 이제 Python 3.3+ 및 백 포트 trollius에 asyncio 가있어 이벤트 루프에서 Tornado 애플리케이션을 실행할 수 있습니다 (Twisted는 곧 지원 될 예정 임).
schlamar

답변:


28

경량 스레딩을 위해 Stackless Python 마이크로 스레드 또는 Greenlets에 의존 하는 동시성 Python 모듈이 마음에 들었습니다 . 모든 차단 네트워크 I / O는 단일 libevent루프를 통해 투명하게 비동기 적으로 이루어 지므로 실제 비동기 서버만큼 효율적이어야합니다.

이런 식으로 Eventlet과 비슷하다고 가정합니다.

단점은 API가 Python의 sockets/ threading모듈 과 상당히 다르다는 것입니다 . 응용 프로그램의 상당 부분을 다시 작성하거나 호환성 심 레이어를 작성해야합니다.

편집 : 또한있을 것으로 보인다 열병합 유사하다, 그러나 파이썬 2.5의 사용 개선 발전기를 대신 Greenlets의 그 코 루틴을 위해. 이것은 동시성 및 다른 대안보다 이식성이 뛰어납니다. 네트워크 I / O는 epoll / kqueue / iocp를 사용하여 직접 수행됩니다.


@intgr : 훌륭한 링크. 나는 한 번에 두 가지를 모두 보았는데, 그것들은 내가 쏟아지기를 바라는 종류의 것들입니다. +1
jkp 2009

3
동시성은 4 년 전 마지막 업데이트 인 죽은 프로젝트 인 것 같습니다.
Gewthen

프로젝트는 죽었고, 하이브도 마찬가지입니다!
Bahadir Cambel

1
파이썬 2.5 이후로 많은 일이 일어났습니다. 파이썬 3.5의 asyncio는 훌륭합니다.
Joseph Sheedy

99

뒤틀린 것은 복잡합니다. 뒤틀린 것은 팽창 되지 않습니다 .

여기 ( http://twistedmatrix.com/trac/browser/trunk/twisted) 를 살펴보면 체계적이고 포괄적이며 잘 테스트 된 많은 인터넷 프로토콜 모음과 작성하는 도우미 코드가 있습니다. 매우 정교한 네트워크 응용 프로그램을 배포합니다. 나는 팽창과 포괄 성을 혼동하지 않을 것이다.

Twisted 문서는 언뜻보기에 가장 사용자 친화적이지 않은 것으로 잘 알려져 있습니다. 그러나 시간을 내면 트위스트는 놀랍습니다 (IMHO). 나는 그만한 가치가있는 것으로 판명되었으며 다른 사람들에게도 같은 것을 시도해 볼 것을 권합니다.


4
@ clemesha : 아마도 당신이 옳고, 부러지지 않았지만, 간단한 일을하기 위해 머리를 돌리기에는 너무 많은 것처럼 느껴집니다. 나는 비동기 프로그래밍을 이해하고, 나는 boost :: asio와 함께 C ++에서 일했다. 그래서 개념은 새로운 것이 아니지만 꼬인 것들을 수행하는 것에 대한 모든 놈 : 장고가 웹 물건을위한 것처럼 완전히 새로운 세계이다. 다시 웹 작업을 할 때 경량 WSGI 코드로 작업하고 필요한 것만 함께 연결합니다. 내가 생각하는 과정에 대한 말.
jkp 2009

7
@clemesha : 음, 오늘 살펴 보았습니다. 트위스트 무게는 20MB입니다! 핵심조차도 12MB입니다 .... 부풀어 오르지 않으면 확실하지 않습니다.
jkp

29
기본 Twisted API는 매우 작습니다 (리액터, 지연, 프로토콜). Twisted 코드의 대부분은 이러한 기본 사항을 사용하는 비동기 프로토콜 구현입니다. "Bloat"는 여기서 유용한 형용사가 아닙니다 (또는 대부분의 경우). 뒤틀린 크기는 물건의 양에 합리적입니다.
daf

56

geventeventlet이 정리되었습니다 .

API 측면에서는 표준 라이브러리 (특히 스레딩 및 다중 처리 모듈)와 동일한 규칙을 준수합니다. 따라서 대기열이벤트 와 같은 익숙한 기능 이 있습니다.

리액터 구현으로 libevent ( update : libev since 1.0 ) 만 지원 하지만 libevent-http 기반의 빠른 WSGI 서버를 특징으로하며 대부분의 다른 라이브러리와 같은 스레드 풀을 사용하는 대신 libevent-dns를 통해 DNS 쿼리를 해결합니다. 하다. ( 업데이트 : 1.0 c-ares부터 비동기 DNS 쿼리를 만드는 데 사용되며 스레드 풀도 옵션입니다.)

eventlet과 마찬가지로 greenlet을 사용하여 콜백 및 지연을 불필요하게 만듭니다 .

여러 URL의 동시 다운로드 , 긴 폴링 웹챗 예를 확인하십시오 .


4
gevent 두 번째-많은 솔루션을 검토 한 후 gevent가 매우 효과적이었습니다. 기존 프로그램의 더 나은 부분을 유지할 수 있었고 필요한 변경 사항은 사소한 것이 었습니다. 무엇보다 코드를 3, 4, 5, ... 년 안에 유지해야하는 경우에도 여전히 gevent에 익숙하지 않은 사람에게는 Twisted의 가장 큰 쇼 토퍼는 강력한 학습 곡선이며, 이는 구현할 때뿐만 아니라 유지 보수 중 문제를 야기합니다 ...
Martin Tournoij

27

정말 흥미로운 비교 와 같은 프레임 워크는 자신의 블로그에 니콜라스 피엘로 컴파일 : 그것은 가치가 읽기 물론입니다!


2
나는이 기사가 흥미로운 기사라는 데 동의하지만 제시된 벤치 마크의 유효성을 고려하는 것이 가치가 있다고 생각합니다. 여기에 의견을 참조하십시오 : reddit.com/r/programming/comments/ahepg/…
clemesha

1
@clemesha, reddit 페이지의 요점은 주목할 가치가 있지만 벤치 마크는 이중 코어 시스템에서 수행되었으며 치명적인 결함으로 고통받지 않았을 가능성이 있습니다. 나는 그것의 가정 가능한 클라이언트와 서버 달렸다 모두 동일한 코어,하지만 가능성이 보이지 않는다.
피터 한센

15

이러한 솔루션 중 어느 것도 GIL이 CPU 병렬 처리를 방지한다는 사실을 피할 수는 없습니다. 스레드와 함께 이미 가지고있는 IO 병렬 처리를 얻는 더 좋은 방법 일뿐입니다. 더 나은 IO를 할 수 있다고 생각한다면, 반드시 이들 중 하나를 추구하십시오. 그러나 병목 현상이 결과를 처리하는 경우 멀티 프로세싱 모듈을 제외하고는 아무런 도움이되지 않습니다.


여러 프로세스를 사용하는 데 어떤 문제가 있습니까?
Emil Ivanov 2019 년

3
다중 처리 모듈을 사용하는 것이 좋습니다.
Adam Hupp

11

Twisted bloated까지는 가지 않겠지 만 머리를 감는 것은 어렵습니다. 나는 항상 '작은 작업'을 위해 조금 더 쉬운 것을 원했기 때문에 꽤 오랫동안 학습에 정착하지 않았습니다.

그러나 이제는 함께 작업 했으므로 모든 배터리를 포함시키는 것이 매우 좋습니다.

내가 작업 한 다른 모든 비동기 라이브러리는 표시보다 성숙도가 떨어집니다. 트위스티드의 이벤트 루프는 확실합니다.

가파른 꼬인 학습 곡선을 해결하는 방법을 잘 모르겠습니다. 이전 버전과의 호환성 문제와 죽은 프로젝트를 제거하는 것과 같이 누군가가 포크로 만들고 몇 가지를 정리하면 도움이 될 수 있습니다. 그러나 그것이 내가 생각하는 성숙한 소프트웨어의 본질입니다.


Windows에서 gtk 리액터가 어떻게 구현되는지 살펴보면 (10ms마다 하드 코어 폴링 : twistedmatrix.com/trac/browser/trunk/twisted/internet/… ), "성숙"이라고 부르지 않을 것입니다.
schlamar

2
안녕하세요 @schlamar. 이 불쾌한 해킹은 GTK +의 꽤 심각한 버그에 대한 해결 방법으로 구현되었습니다. 그러나 Twisted의 장점은이 버그를 한 번만 가지고 프레임 워크에서 수정하여 사용자가 걱정할 필요가 없다는 것입니다. 이 문제를 해결하고 제거되는 수정 프로그램을 제공 하시겠습니까 (더 이상 사용되지 않으며 나중에 제거) PortableGtkReactor?
글리프

1
@Glyph 다른 사람 이이 문제를 해결하려는 경우 twistedmatrix.com/trac/ticket/4744#comment:2 에 유용한 조언을 추가했습니다 . 이러한 문제 중 일부는 여전히 존재하기 때문입니다. BTW, 두 이벤트 루프 사이에서 콜백을 예약하여이 문제를 훨씬 더 효율적으로 해결할 수있었습니다.
schlamar

7

Kamaelia 는 아직 언급되지 않았습니다. 동시성 모델은받은 편지함과 보낼 편지함간에 메시지가 전달되는 구성 요소를 서로 연결하는 것을 기반으로합니다.다음 은 간단한 개요입니다.


5
나는 앱에 kamaelia를 사용했습니다-그것은 매우 고통 스럽습니다. IMHO는 파이썬에서 동시성에 대한 다른 더 나은 옵션이 있습니다 (대부분 위에서 언급했습니다)
Ben Ford

7

나는 몇 가지 일에 꼬임을 사용하기 시작했습니다. 그것의 아름다움은 거의 그것이 부풀어 오르기 때문입니다. 거의 모든 주요 프로토콜에 대한 커넥터가 있습니다. 명령을 가져 와서 irc 서버에 게시하고, 누군가에게 이메일로 보내거나, 명령을 실행하고, NNTP 서버에서 읽고 변경 사항이 있는지 웹 페이지를 모니터링하는 Jabber 봇이있을 수 있습니다. 나쁜 소식은 모든 것을 할 수 있고 OP와 같은 간단한 작업을 위해 일을 지나치게 복잡하게 만들 수 있다는 것입니다. 파이썬의 장점은 필요한 것만 포함한다는 것입니다. 따라서 다운로드는 20MB 일 수 있지만 2MB의 라이브러리 만 포함 할 수 있습니다 (여전히 많음). 트위스트에 대한 나의 가장 큰 불만은 예제가 포함되어 있지만 기본 TCP 서버를 넘어서는 것입니다.

파이썬 솔루션은 아니지만 node.js가 최근에 더 많은 견인력을 얻었습니다. 사실 나는 더 작은 프로젝트를 조사하는 것을 고려했지만 자바 스크립트를 들으면 울었습니다. :)


나는 큰 파이썬 팬입니다. – Douglas Crockford의“자바 스크립트 – 좋은 부분”을 확인하십시오 (3, 4 비디오). 그리고 CoffeeScript를 들여다보십시오. JS에는 Syntax, haha를 제외하고 파이썬이 가져야 할 것이 있습니다. CS는 그것을 완화 시키려고 노력했지만 그것에 약간 서투른 것입니다.
Robert Siemer

4

Abe Fettig의 "Twisted Network Programming Essentials"라는 주제에 관한 좋은 책이 있습니다. 예제는 매우 Pythonic 코드를 작성하는 방법을 보여 주며 개인적으로 부풀린 프레임 워크를 기반으로 나를 공격하지 않습니다. 책의 해결책을 살펴보십시오. 깨끗하지 않으면 깨끗하다는 것이 무엇인지 모르겠습니다.

내 유일한 수수께끼는 Ruby와 같은 다른 프레임 워크와 동일합니다. 걱정 되나요? 확장 성 문제가있는 프레임 워크에 클라이언트를 투입하는 것을 싫어합니다.


4

Whizzer 는 pyev를 사용하는 작은 비동기 소켓 프레임 워크입니다. 주로 pyev 때문에 매우 빠릅니다. 약간의 변경으로 꼬인 비슷한 인터페이스를 제공하려고 시도합니다.


2

또한 Syncless 시도 하십시오 . 그것은 코 루틴 기반입니다 (따라서 Concurrence, Eventlet 및 gevent와 유사합니다). socket.socket, socket.gethostbyname (등), ssl.SSLSocket, time.sleep 및 select.select에 대한 드롭 인 비 차단 대체를 구현합니다. 빠릅니다. Stackless Python과 libevent가 필요합니다. C (Pyrex / Cython)로 작성된 필수 Python 확장이 포함되어 있습니다.


2

나는 syncless 의 장점을 확인합니다 . libev (새롭고 깨끗하며 성능이 우수한 libevent 버전)를 사용할 수 있습니다. 몇 번 전에 libevent만큼 많은 지원을 제공하지는 않지만 개발 프로세스가 진행되어 매우 유용합니다.



0

PyWorks를 살펴 보는 것은 매우 다른 방법입니다. 객체 인스턴스가 자체 스레드에서 실행되도록하고 해당 객체에 대한 함수 호출을 비동기로 만듭니다.

클래스가 객체 대신 Task에서 상속하도록하고 비동기입니다. 모든 메서드 호출은 프록시입니다. 반환 값 (필요한 경우)은 미래 프록시입니다.

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
이것은 흥미롭고 일부 작업에 적합 할 수 있지만 네트워킹에 스레드를 사용하면 성능이 떨어집니다 (특히 GIL로 인해 Python에서). 그리고 이것은 정확히 문제가되었습니다 : 이벤트 프레임 워크 또는 멀티 프로세싱. 따라서 당신의 대답은 분명히 범위를 벗어납니다 ...
schlamar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.