2009-12-17 6 views
40

Facebook 응용 프로그램 및 클라우드 컴퓨팅 시대에 대규모 멀티 플레이어 게임에 대해 다시 생각해 보겠습니다.대기 시간이 짧은 대규모 메시지 대기열

기존의 개방형 프로토콜을 기반으로 무언가를 구축하고 있다고 가정 해 봅시다. 문제의 범위를 정하기 위해 1,000,000 명의 동시 플레이어를 지원하고 싶습니다.

각 플레이어가 들어오는 메시지 대기열 (채팅 및 기타), 그리고 평균적으로 수신 대기열 (길드, 존, 인스턴스, 경매 ...)이 하나 더있어 2,000,000 개의 대기열이 있다고 가정합니다. 플레이어는 한 번에 1-10 개의 대기열을 듣습니다. 각 큐에는 평균 1 초당 평균 1 개의 메시지가 있지만 특정 큐에는 훨씬 더 높은 속도와 더 많은 수의 수신기가 있습니다 (예 : 수준 인스턴스의 "엔터티 위치"큐). 시스템 대기 시간이 100 밀리 초를 넘지 않는다고 가정 해 봅시다. 이는 약간의 행동 지향적 인 게임 (Quake 또는 Unreal Tournament와 같은 게임이 아님)에서도 괜찮습니다.

다른 시스템에서는 단일 1U 또는 블레이드 상자에서 10,000 명의 사용자에게 서비스를 제공하는 것이 합리적입니다 (물리 시뮬레이션 또는 기타 등등과 같은 비싼 작업이 없다고 가정).

따라서 클라이언트가 연결 게이트웨이에 연결하고 클라이언트가 메시지 대기열 서버에 연결되는 크로스바 클러스터 시스템을 사용하면 게이트웨이 컴퓨터 100 대를 사용하는 게이트웨이 당 10,000 명의 사용자를 얻을 수 있으며 대기열 서버 당 20,000 개의 메시지 대기열이 100 대기열 머신. 다시 말하지만, 일반적인 범위 지정을 위해서입니다. 각 MQ 시스템의 연결 수는 각 게이트웨이와 통신하기 위해 약 100 개 정도로 작습니다. 게이트웨이의 연결 수는 클라이언트의 + 모든 대기열 서 v에 대한 연결에 대해 10,100 높습니다. (이 외에도 게임 월드 시뮬레이션 서버 또는 기타 등등에 대한 몇 가지 연결을 추가하십시오.하지만 지금은 별도로 유지하려고합니다.)

처음부터이 빌드를 원하지 않는다면 존재하는 일부 메시징 및/또는 큐 인프라를 사용하십시오. 내가 찾을 수있는 두 개의 공개 프로토콜은 AMQP 및 XMPP입니다. XMPP의 의도 된 사용은이 게임 시스템이 필요로하는 것과 조금 비슷하지만 오버 헤드는 상당히 눈에 is니다 (XML과 자세한 현재 상태 데이터 및 위에 빌드해야하는 다양한 다른 채널). AMQP의 실제 데이터 모델은 위에서 설명한 것과 비슷하지만 모든 사용자는 대기업 유형의 기업처럼 보이며 작업 부하는 실시간 게임 업데이트와 관련이 없으며 워크 플로와 관련이있는 것으로 보입니다.

누구나 공유 할 수있는 이러한 기술 또는 구현과 관련하여 주간 경험이 있습니까?

+14

나는 우리가 무엇을했는지 요약하고 싶습니다. Rabbit, Qpid, ZeroMQ 및 다른 사람들은 모두 비즈니스에 익숙하고 대기 시간이 짧은 디자인 선택이 적었고 클라이언트를 신뢰하거나 조인/리프/큐 작성/삭제의 높은 비율을 지원하지 않아야했습니다. 비슷한. XMPP는 첫 번째 물리적 상자에서 잘 연합되지 않습니다. JMS는 토끼와 친구들보다 훨씬 나쁩니다. Redis Pub/Sub는 재미 있지만 다시 연합/클러스터되지 않습니다. 우리는 Erlang/OTP (Rabbit과 ejabberd에 사용 된 동일한 언어) 위에 자신의 글을 쓰고 결국 저수준 IDL로 Google 프로토콜 버퍼를 사용했습니다. –

+0

공유 해 주셔서 감사합니다. "XMPP는 첫 번째 물리적 상자에서 잘 연합되지 않습니다"라는 의미는 무엇입니까? – alex

+3

나는 "좋은/과거/첫 번째 물리적 상자를 연합하지 않는다"는 의미입니다. XMPP는 프로토콜의 잘못된 선택이기 때문에 하드웨어를 추가하는 것은 확장에별로 도움이되지 않습니다. –

답변

10

@MSalters

다시 '메시지 큐'

: 과도 pubsub을 :

RabbitMQ의 기본 동작은 당신이 무엇을 설명 정확히이다. 그러나 UDP 대신 TCP를 사용합니다.

최종 배달 및 기타 지속성 및 복구 기능을 보장 받으려면 옵션도 있습니다. 옵션입니다. 이것이 RabbitMQ와 AMQP의 핵심입니다. 하나의 메시지 전달 시스템으로 많은 행동을 할 수 있습니다.

당신이 묘사하는 모델은 DEFAULT 행동입니다. 일시적인 "불과 잊음"이며 수신자가있는 곳으로 메시지를 라우팅합니다. 사람들은 RabbitMQ를 사용하여 EC2에서 멀티 캐스트 검색을 수행합니다. 유니 캐스트 TCP pubsub를 통해 UDP 유형 동작을 가져올 수 있습니다. 허, 응?

Re UDP :

여기서 UDP가 유용 할 지 모르겠습니다. Nagling을 해제하면 RabbitMQ 단일 메시지 왕복 대기 시간 (클라이언트 - 브로커 - 클라이언트)은 250-300 마이크로 초로 측정됩니다. Windows 대기 시간 (조금 더 높음)과의 비교는 여기를 참조하십시오. http://old.nabble.com/High%28er%29-latency-with-1.5.1--p21663105.html

왕복 지연이 300 마이크로 초 미만인 많은 멀티 플레이어 게임을 생각할 수 없습니다. TCP를 사용하면 300us 이하로 떨어질 수 있습니다. TCP 윈도우 잉 은 원시 UDP보다 더 비싼이지만, UDP를 사용하여 더 빠르게 진행하고 사용자 정의 손실 복구 또는 seqno/ack/resend manager를 추가하면 다시 느려질 수 있습니다. 그것은 모두 귀하의 유스 케이스에 달려 있습니다. 정말로 정말로 UDP와 게으른 acks 등을 사용해야한다면, RabbitMQ의 TCP를 벗겨 내고 아마 그걸 풀 수 있습니다.

Jon의 사용 사례에 RabbitMQ를 권장 한 이유를 명확히 알기를 바랍니다.

+0

제안 해 주셔서 감사합니다. Rabbit의 대안은 Red Hat 대기 시간이 낮은 커널에서 실행될 때 단일 8 코어 서버 박스 (!)에서 초당 6M 메시지를 요구하는 Qpid입니다. 그러나이 상자에는 10,000 명의 사용자가 동시에 연결되어있는 것으로 의심됩니다. 토끼 대 Qpid를 비교할 수있는 좋은 링크가 있다면보고 싶습니다. –

+0

존, 6M 참조에서 나를 가르쳐 주시겠습니까? 나는 RabbitMQ와 Qpid가 둘 다 (금융 시장 데이터) OPRA 피드로 얼마 전에 테스트 한 사례를 언급한다고 생각합니다. 이것은 좋은 사례이지만, 우리가 더 높은 속도를 얻기 위해 일괄 처리와 압축을 사용함을 기억합니다. OPRA의 경우 일괄 처리와 압축을 모두 사용하는 것이 표준 방법입니다. 최근의 같은 브로커를 비교해 보면, 즉흥적으로 떠오르는 사례는 없지만 인터넷 검색을 통해 더 많은 정보를 얻을 수 있습니다. 건배 alexis – alexis

+0

예, 아마도 테스트 케이스입니다. 6M 수치는 Red Hat 사이트에서 "저 지연 Linux"기반 Qpid 구현으로 나타났습니다. 그리고 그 테스트 케이스는 제가 관심을 가지고있는 경우와 관련이 거의 없습니다. 연결되는 사용자가 1,000,000 명에 달하고 각각 몇 초 만에 메시지가 도착하는 문제가 있습니다 ... –

4

Jon, AMQP 및 RabbitMQ의 이상적인 사용 사례로 들립니다.

왜 나는 AMQP 사용자가 모든 대기업 유형의 회사라고 말하는지 잘 모르겠습니다. 고객 중 절반 이상이 거대 기업에서부터 소규모 기업에 이르는 '웹'공간에 있습니다. 많은 게임, 도박 시스템, 채팅 시스템, 트위터 타입 시스템 및 클라우드 컴퓨팅 인프라가 RabbitMQ에서 구축되었습니다. 심지어 휴대 전화 응용 프로그램이 있습니다. 워크 플로우는 많은 유스 케이스 중 하나 일뿐입니다.

우리는 여기에서 무슨 일이 일어나고 있는지를 추적 유지하려고 (! 당신이 너무 del.icio.us에 사용 사례의 목록에 클릭을 통해 확인)

http://www.rabbitmq.com/how.html

을 마십시오 보기. 우리는 돕기 위해 왔습니다. 언제든지 [email protected]으로 이메일을 보내거나 트위터 (@monadic)에 나를 때려주세요.

2

내 경험에 비공개 대안 인 BizTalk가있었습니다. 우리가 배운 가장 고통스런 교훈은 이러한 복잡한 시스템이 빠르지 않다는 것입니다. 그리고 하드웨어 요구 사항에서 알 수 있듯이 상당한 비용으로 직접 변환됩니다.

그런 이유로 핵심 인터페이스에 XML을 가까이 가지 마십시오. 서버 클러스터가 초당 2 백만 개의 메시지를 구문 분석합니다. 2 ~ 20GB/초의 XML이 될 수 있습니다! 그러나 대부분의 메시지는 몇 개의 대기열에 대한 것이지만 대부분의 대기열은 실제로 낮은 트래픽입니다.

따라서 아키텍처를 설계하여 COTS 대기열 서버로 시작한 다음 병목 현상이 확인되면 각 대기열 (유형)을 사용자 정의 대기열 서버로 옮기기가 쉽습니다.

또한 비슷한 이유로 메시지 대기열 아키텍처가 애플리케이션의 모든 커미셔닝 요구에 가장 적합하다고 가정하지 마십시오. "인스턴스에서 엔터티 위치"예제를 가져옵니다. 이것은 이 아닌에 메시지 전달이 보장되는 고전적인 사례입니다. 이 정보를 공유해야하는 이유는 항상 변경되기 때문입니다. 따라서 메시지가 유실 된 경우 메시지를 복구하는 데 시간을 낭비하고 싶지 않습니다. 영향을받는 개체의 오래된 위치 만 보내면됩니다. 대신, 현재 해당 엔티티의 위치를 ​​보내고 자 할 것입니다. 기술면에서는 TCP가 아니고 사용자 지정 손실 복구 메커니즘이 아니라 UDP를 원한다는 의미입니다.

+2

예 : 패킷을 삭제하면 TCP 문제가 발생합니다. 복구 전의 정지는 중요 할 수 있습니다. TCP를 사용하면 커널은 이전 정보가 아직 도착하지 않았기 때문에 새로운 정보를 보류합니다. 게임 (예 : 위치 업데이트)의 경우 바람직하지 않습니다. 메시지 대기열 클라이언트는 전세계에 분산되어있는 모든 사용자로, 클러스터 자체에 있지 않으므로 네트워킹 문제가 실제로 발생합니다. (실제로 잘 연결된 서버 룸 내에서도 스위치와 버퍼의 크기에 관계없이 어느 정도의 패킷 손실이 발생합니다.) –

3

FWIW 중간 결과가 중요하지 않은 경우 (위치 정보와 같이) Qpid에는 가장 최근 값만을 가입자에게 전달할 수있는 "마지막 값 대기열"이 있습니다.

+0

알아두면 좋은 소식입니다! 나는 실제로 체크 아웃하고 Qpid를 구축했으며 지금 시도하고있다. 특히 좋아하지 않는 것은 기본 구성이 300 개의 연결로 제한된다는 점입니다. 1 상자 당 20,000 개의 연결을 수행합니까? –

+0

필자는 [email protected] 목록에서 좀 더 깊이 대답했지만, 충분한 하드웨어 마력이 있다고 가정 할 때 상자 당 20,000 건의 연결을 수행해도 문제가 없어야합니다. –

10

저는 지금 그런 시스템을 만들고 있습니다.

나는 RabbitMQ, Qpid 및 ZeroMQ를 포함하여 여러 MQ에 대한 상당한 평가를 수행했습니다. 이러한 유형의 응용 프로그램에 대해서는 지연 시간과 처리량이 적합합니다.그러나 좋지 않은 것은 50 만 개 이상의 대기열에 대기열 생성 시간이있는 것입니다. Qpid는 특히 수천 개의 큐 이후에 상당히 심각하게 열화됩니다. 이 문제를 피하기 위해 일반적으로 고유 한 라우팅 메커니즘을 생성해야합니다 (전체 대기열 수가 적고 해당 대기열의 사용자는 관심이없는 메시지를받습니다).

현재 시스템은 ZeroMQ를 사용하지만, 상당히 제한적인 방법으로 내에서 클러스터를 사용합니다. 클라이언트의 연결은 사용자 정의 sim으로 처리됩니다. 데비안은 libev를 사용하여 만들었고 완전히 단일 스레드입니다 (그리고 매우 좋은 확장 성을 보이고 있습니다 - 아무런 문제없이 하나의 상자에 50,000 개의 연결을 처리 할 수 ​​있어야합니다 - 우리의 sim. tick rate는 매우 낮습니다. 아니 물리학).

XML (따라서 XMPP)은 I/O에 바인딩되기 오래 전에 CPU 처리 XML을 페깅 할 것이기 때문에 매우 적절하지 않습니다. 이는 원하지 않는 것입니다. 우리는 현재 Google 프로토콜 버퍼를 사용하고 있으며, 이는 우리의 특별한 요구에 잘 맞을 것 같습니다. 또한 클라이언트 연결에 TCP를 사용하고 있습니다. 과거에는 UDP와 TCP를 모두 사용 해본 경험이 있으며, 다른 사람들이 지적한 것처럼 UDP에는 이점이 있지만 작업하기가 약간 더 어렵습니다.

출시하기에 조금 더 가까울수록 더 자세한 정보를 공유 할 수 있기를 바랍니다.

관련 문제