문제

결과적으로 두 라이브러리는 유사한 철학과 유사한 디자인 결정을 공유합니다.하지만 이 인기 있는 WSGI 벤치마크 라고 eventlet 것보다 훨씬 느립니다 gevent.무엇이 그들의 성과를 그토록 다르게 만드는가?

내가 알고 있듯이 이들 사이의 주요 차이점은 다음과 같습니다.

  • gevent 의도적으로 의존하고 결합됩니다. libev (libevent, 이전) 동안 eventlet 독립적인 반응기 인터페이스를 정의하고 다음을 사용하여 특정 어댑터를 구현합니다. select, epoll, 그리고 그 뒤에는 뒤틀린 반응기가 있습니다. 추가 반응기 인터페이스로 인해 심각한 성능 저하가 발생합니까?

  • gevent 대부분 Cython으로 작성되었지만 eventlet 순수 Python으로 작성되었습니다. 계산량이 많지 않지만 IO 바인딩된 프로그램의 경우 기본적으로 컴파일된 Cython이 순수 Python보다 훨씬 더 빠른가요?

  • 의 기본 gevent 표준 라이브러리의 인터페이스를 에뮬레이트하는 동시에 eventlet의 프리미티브는 표준과 다르며 이를 에뮬레이션하기 위한 추가 레이어를 제공합니다. 추가 에뮬레이션 계층이 eventlet 더 천천히?

  • 구현인가? eventlet.wsgi 그냥 더 나쁜 것보다 gevent.pywsgi?

정말 궁금합니다. 왜냐하면 그것들이 나에게는 전반적으로 너무 비슷해 보이기 때문입니다.

도움이 되었습니까?

해결책

글쎄, gevent는 Cython으로 "대부분" 작성되지 않았지만 일부 중요한 섹션은 작성되었습니다.

Cython은 큰 차이를 만듭니다.프로세서 최적화는 컴파일된 코드에서 훨씬 더 잘 작동합니다.예를 들어 분기 예측은 VM 실행 수준에서 분기의 간접적인 방향이 불투명하기 때문에 VM 기반 시스템에서는 무너집니다.캐시 공간이 더 촘촘해졌습니다.컴파일된 코드는 여기서 큰 차이를 만들어내며 IO는 대기 시간에 매우 민감할 수 있습니다.

비슷한 맥락에서 libev는 매우 빠릅니다.같은 이유.

Eventlet이 선택 허브를 사용해야 했던 것 같지는 않습니다(Python 2.6은 일반적으로 epoll을 기본값으로 설정합니다).그래도 선택에 멈췄다면 그렇게 될 것입니다. 정말 느립니다(Python은 select fd_set를 Python 목록으로 앞뒤로 변환해야 하기 때문에 루프 중간에 있으면 보기 흉해집니다).

나는 어떤 프로파일링도 ​​하지 않았지만 libev/libevent와 Cython이 큰 차이를 만든다고 확신합니다.특히 일부 스레딩 기본 요소는 Cython의 gevent에 있습니다.많은 코드가 IO와 일부 지점의 표준 라이브러리를 통해 간접적으로 접촉하기 때문에 이는 큰 문제입니다.

Eventlet의 추가 에뮬레이션 레이어에 관해서는 훨씬 더 탄력적인 것으로 보입니다.gevent에서 코드 경로는 콜백을 구성하고 허브가 이를 호출하도록 하는 것으로 보입니다.eventlet은 허브가 gevent에서 수행하는 장부 관리 작업을 더 많이 수행하는 것으로 보입니다.하지만 다시 한 번 말씀드리지만 프로필을 작성하지 않았습니다.몽키패칭 자체는 상당히 비슷해 보입니다.

WSGI 서버는 또 다른 어려운 서버입니다.특히, gevent의 헤더 구문 분석은 표준 라이브러리로 연기되는 반면, gevent에서는 이를 자체적으로 구현합니다.이것이 큰 영향인지 아닌지는 확실하지 않지만 거기에 뭔가가 숨어 있다면 놀랄 일이 아닙니다.가장 눈에 띄는 점은 eventlet의 서버가 표준 라이브러리 BaseHTTPServer의 원숭이 패치 버전을 기반으로 한다는 것입니다.나는 이것이 매우 최적이라고 상상할 수 없습니다.Gevent는 에뮬레이션을 인식하는 서버를 구현합니다.

다른 팁

늦은 답변 죄송합니다.

성능 차이가 큰 두 가지 주요 이유가 있습니다. 해당 벤치마크에서:

  • 앞서 언급했듯이 gevent의 주요 경로는 크게 최적화되어 있습니다.
  • 해당 벤치마크는 스트레스 테스트를 수행합니다.머신이 가능한 한 많은 요청을 실행하도록 시도하기 때문에 더 이상 IO 바인딩이 아닙니다.이것이 Cythonized 코드가 빛나는 곳입니다.

"실제 세계에서"는 "슬래시닷" 트래픽 폭주 중에만 발생합니다.어느 것이 중요하고 준비가 되어 있어야 하지만, 그런 일이 발생하면 더 많은 서버를 추가하거나 리소스를 많이 사용하는 기능을 비활성화하여 대응합니다.부하가 증가하면 실제로 더 많은 서버를 추가하는 벤치마크를 본 적이 없습니다.

반면에 벤치마크가 "평상시" 로드(웹 사이트마다 다름)를 시뮬레이션하지만 일반적으로 요청, 임의 일시 중지, 반복으로 근사할 수 있는 경우입니다.일시 중지가 적을수록 시뮬레이션하는 트래픽이 많아집니다.또한 벤치마크의 클라이언트 측에서는 대기 시간을 시뮬레이션해야 합니다.Linux에서는 멋진 netem[1]을 사용하여 이 작업을 수행할 수 있습니다. 그렇지 않으면 수신/전송 호출 전에 약간의 지연을 두어 수행할 수 있습니다(벤치마크는 일반적으로 더 높은 수준의 라이브러리를 사용하기 때문에 매우 어려울 수 있습니다).

이제 이러한 조건이 충족되면 실제로 IO 바운드 문제를 벤치마킹합니다.그러나 결과는 그다지 좋지 않을 것입니다.모든 후보자는 10, 50, 심지어 200qps 로드를 성공적으로 처리했습니다.지루하지 않나요?따라서 지연 시간 분포, 99% 요청을 처리하는 데 걸리는 시간 등을 측정할 수 있습니다.Gevent는 여전히 더 나은 결과를 보여줄 것입니다.그러나 그 차이는 거의 인상적이지 않을 것입니다.

[1] Linux에서 지연 및 손실된 패킷 시뮬레이션

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top