수평 확장 가능한 MMORPG와 같은 역동적 인 세상을 만드는 방법이 있습니까?


11

초당 20 번의 업데이트 속도로 데이터가 변경되는 500여 명의 오픈 월드 플레이어를 상상해보십시오. 마지막으로 비슷한 MMORPG에서 일할 때 SQL을 사용했기 때문에 DB를 항상 쿼리 할 수 ​​없었습니다. 대신, DB에서 모든 플레이어를 C ++ 객체로 메모리에로드하여 사용했습니다. 즉, 세로로 확장됩니다. 대신 서버를 수평 확장 가능하게 만들 수 있습니까? 해당 양의 업데이트를 동시에 지원하도록 설계된 데이터베이스가 있습니까?


데이터베이스에서 플레이어를 초당 20 회 업데이트하려는 이유는 무엇입니까?
Balon

내가 혼란스러워하는 곳 @Balon. 데이터베이스에서 메모리로 업데이트하지 않으면 컴퓨터마다 상태가 다릅니다. 그러나 DB 업데이트에는 약간의 오버 헤드가 있으므로 그 정도의 업데이트에는 실제로 작동하지 않습니까?
MaiaVictor

2
실제로 다른 머신 (또는 프로세스)이 수백 개의 객체에 대해 20Hz 업데이트가 필요하다고 생각하면 데이터베이스를 완전히 우회하고 메시징 시스템을 직접 사용하십시오. 그러나 당신이 정말로, 정말로 당신이 원하는 것은 당신이 정말로 원하는 것이 아닙니다. 당신이 원하는 것은 누가 무엇을 알아야하고, 그 사이의 범위 사이에서 객체를 깔끔하게 운송 할 수있는 방법을 가지고있는 것입니다. 큰 대답을 얻으려면 다른 컴퓨터간에 20Hz 업데이트가 필요한 이유에 대한 질문에 대답해야합니다. 누군가가 문제를 보는 새로운 방법을 생각할 수도 있습니다.
Patrick Hughes

@PatrickHughes 필요한 것이 무엇인지 모르겠습니다. 게임이 어떻게 작동하는지 설명하고 있습니다. 캐릭터는 2 ~ 3 타일 / 초씩 움직입니다. 플레이어 사냥은 몇 개의 몬스터로 둘러싸여있을 수 있으므로 최소 10 타일 / 플레이어 / 초입니다. 그런 다음 바닥, 플레이어의 배낭에 부패하는 품목이 있습니다. 플레이어 방향으로 움직이는 공격이 있고 몬스터 방향으로 움직이는 공격이 있습니다. 체력이 떨어지고 마나가 사용되며 플레이어에게 독 피해를주는 타이머가 있습니다. 따라서 상황이 정말 빠르게 변합니다. 이것이 게임 디자인입니다. 그러한 설계를 어떻게 수직으로 확장 할 수 있습니까?
MaiaVictor

1
나는 얼마 전에 HackerNews에서 이것을 보았습니다 : paralleluniverse.co 그들은 당신을 위해 모든 공간 분할 / 배포 작업을 수행하는 데이터베이스에서 작업하고 있습니다. 나는 후드 아래에서 아래 답변의 모든 일을하고 있다고 추측합니다.
잡아 당김

답변:


17

500 명의 플레이어가 모두 의사 소통하는 테스트 사례, 즉 20Hz에서 250K 스트림의 정보가 전송됩니다. 이를위한 내부 대역폭은 각 메시지가 100 바이트 인 것으로 가정하면 약 500MB / 초입니다. 야심 찬 소리. 특히 프로세스 간.

플레이어를 100 개의 그룹으로 분리하면 20MB / 초 등으로 줄어 듭니다. 그렇기 때문에 MMO에 영역이 있고 해당 영역에서 대역폭이 합리해질 때까지 영향을 거의받지 않는 이유가 있습니다.

원래 문제 는 10 명 모두 실시간 정보를 공유하지만 500 명 모두 공유를 원하는 경우 통신 링크가 기하 급수적으로 증가하고이를 해결할 수있는 방법이라고 할 수 있습니다 . 내가 들었던 마법의 총알이 마법의 기하학적 진행을 마술처럼 만들지 못할 까봐 두렵습니다.

데이터베이스를 사용하여 통신하지 마십시오. 이것이 바로 메시징입니다. 데이터베이스를 사용하여 플레이어가 잃고 싶지 않은 거래 및 상점 정보를 시행하십시오. 내가 익숙한 대부분의 MMO는 1-10 분마다 또는 영역 전환이나 디자인의 "안전한"영역으로 들어가는 편리한 지점에서만 동적 플레이어 정보로 데이터베이스를 업데이트합니다.

멀리 떨어져 있더라도 모든 플레이어의 배낭 내용을 실시간으로 업데이트하려면 모든 플레이어에 대한 게임의 요구 를 다시 설계해야 할 수도 있습니다 .

또한 거리를 기준으로 업데이트 패턴을 20Hz에서 속도로 변경하십시오 .1 마일 떨어진 사람은 정확히 230.6 초에 1 발을 움직 인 다음 231.4 초에 다른 발을 움직일 필요가 없습니다. 초.


훌륭하고 유익한 답변, 감사합니다. 하지만 세상이 매우 빠른 속도로 변하는 동안 플레이어는 바로 옆에있는 다른 플레이어 만 볼 수 있다고 덧붙일 수 있습니다. 나는 그것을 기하학적으로 보지 않는다-500 명의 플레이어가 서버에 정보를 보낸다. 서버는 주기적으로 500 명의 플레이어에게 정보를 보냅니다. 내가 본 것처럼 선형입니다. 그러나 주요 요점은 네 번째 단락에 있습니다. 데이터베이스를 스토리지로만 사용하면 데이터를 메모리에로드합니다. 컴퓨터의 메모리에 데이터를로드하는 경우 비동기 버전의 세계를 만들고 있습니다. 그것이 내가 얻지 못한 것입니다.
MaiaVictor

1 클라이언트의 경우 : 1 msg out + 1 msg in = 2입니다. 2 클라이언트의 경우 : 2 msg out, 2 msg in = 4입니다. 3 개의 클라이언트의 경우 : 3 msg out, 3 msg in = 9입니다. 그것은 다음과 같습니다 : 상태 메시지를 보내고 서버는 결과를 저와 다른 2 명의 클라이언트 (1 in, 3 out)와 3 명의 클라이언트 모두에게 보냅니다 (1 in 9 out). 3의 클라이언트 중 하나에 대해서만 선형으로 보이지만 시스템의 총 처리량에 대해 모든 클라이언트에 곱해야합니다. 비 동기화의 경우 동일한 물리적 상자의 프로세스조차도 상태 메시지가 생성되고 전송 될 때까지 동기화되지 않습니다. 파이프가 비워지는 위치, 로컬 RAM 또는 네트워크의 문제 일뿐입니다.
Patrick Hughes

5

관심 영역 필터링을 사용하십시오. 세계가 3 대의 서버로 분리되어 있고 서버 1의 영역이 서버 3의 영역 근처에 없으면 엔티티에 대한 정보를 전혀 공유 할 이유가 없습니다.

마찬가지로 단일 서버에서는 관련 정보 만 클라이언트에게 보냅니다. 플레이어 A가 플레이어 B에서 맵의 반대편에 있다면 B에 대한 업데이트를 A에게 보내거나 그 반대의 이유가 없습니다.

연속 세계에 여러 서버가있는 경우 서버 2의 에지 근처에 서버 1의 엔터티에 가까운 엔터티가 있습니다. 엔터티에 대한 "권한"서버에서 다른 서버로 업데이트를 보낼 수 있습니다 (적절한 경우). 메시지를 권한있는 서버에 적절하게 전달하십시오.

예,이 경우 특정 엔터티에 대해 하나의 서버가 약간 오래된 것입니다. 그것을 해결하려고하지 마십시오. 그냥 처리하십시오. 엔터티가 약간 오래된 것으로 가정합니다. 엔티티를 정식으로 소유하는 서버에서만 최신 정보가 필요한 로직을 수행하십시오. 엔터티가 다른 엔터티에 영향을 주면 메시지를 보내고 엔터티가 처리되고보기가 업데이트되기 전에 여러 게임 로직 틱이 필요할 수 있다고 가정합니다.

이 설계는 단일 서버를 훨씬 쉽게 스레드 할 수있게합니다. 엔터티는 다른 엔터티를 직접 수정하거나 메시지 만 보내지 않아야하며 로컬 서버 / 스레드 별 프록시 캐시는 약간 오래된 것으로 가정해야합니다.

예를 들어, 엔티티 A가 엔티티 B를 공격하는 경우 B의 수명을 확인하지 않고 0에 도달하면 사망 메시지를 보내십시오. "손상된"메시지를 보내고 B의 권한있는 서버가 처리 한 다음 처리하십시오. 엔티티 A가 그것에 대해 신경 쓰면 나중에 서버 B가 보낸 "엔티티 사망"메시지

크고 확장 가능한 게임 이외의 모든 응용 프로그램에도 동일하게 적용됩니다. 중앙 데이터베이스는 마법의 인스턴트 공유 기술이 아닙니다. 높은 처리량을 유지하려면 두 서버가 메시지와 비동기식으로 메시지와 통신해야합니다. 따라서 AMPQ와 같은 기술의 인기가 있습니다. 데이터베이스는 저장 용이며, 동기화 또는 통신용이 아니기 때문에 통신용으로 사용할 수 있도록 동기화가 필요합니다.


고마워, 이것은 내 남은 의심의 대부분을 끝냈다. 또한 당신은 나에게 지역이 아닌 플레이어에 의해 서버를 분리한다는 아이디어를주었습니다. 각 서버는 x 플레이어를 관리합니다. 나는 이것을 정말로 좋아한다! 이것이 사용됩니까? 또한 한 가지 더 있습니다. 위에서 요청했듯이 새로운 NoSQL 데이터베이스 인 Couchbase에 대해 알게되었습니다. 매우 빠른 쓰기 / 읽기 속도 (초당 최대 200k 업데이트)를 제외하고는 CouchDB와 같아야합니다! 어쩌면 이것이 실제로 "실시간 공유 세계 모델"로 작동 할 수 있습니까?
MaiaVictor

나는 서버의 일반적인 "샤딩"외에 그 기술이 야생에서 사용되는지 전혀 모른다. 플레이어와 지리적 영역에서 수행하는 것만으로 각 서버는 다양한 영역에 걸쳐 매우 많은 수의 엔티티를 인식해야하므로 서버로드가 증가하고 서버 간 통신이 크게 증가합니다. 영역별로 수행하면 서버가 붐비는 영역에 과부하가 걸릴 수 있지만 (이 경우 동적으로 영역을 분할하고 결합 할 수는 있지만) 각 서버에는 추적 할 수있는 관련 비 플레이어 엔티티 및 지오메트리 세트가 더 작습니다. .
Sean Middleditch 2012 년

@Dokkat : 각 서버가 주로 게임 세계의 특정 부분에서 플레이어를 처리하는 일종의 "부드러운 영역"이있을 수 있지만 플레이어가 너무 멀리 떨어지면 다른 서버로 투명하게 넘겨 줄 수 있습니다. 원래 서버의 지역 플레이어가 실제로 눈치 채지 못할 정도로 핸드 오버가 매끄 럽도록해야합니다. 심지어 지역 경계에있는 경우에도 멋진 적응 기술을 사용하여 동일한 서버에서 상호 작용하는 플레이어 클러스터를 유지하려고 시도 할 수도 있습니다.
Ilmari Karonen

3

Gamasutra 에 대한 이 기사에 관심이있을 것입니다 . Eve Online 개발자는 하나의 SQL 데이터베이스에서 4 억 명의 활성 플레이어와 게임을 성공적으로 실행하는 방법에 대해 논의합니다.


2

데이터베이스를 모든 종류의 실시간 공유 세계 모델로 생각하지 마십시오. 알다시피 작동하지 않을 수도 있습니다.

대신 데이터베이스를 자동으로 업데이트 된 저장 파일처럼 취급하십시오. 플레이어가 로그인하거나 로그 아웃하거나 한 영역에서 다른 영역으로 이동할 때 또는 원하지 않는 중요한 일이 발생할 때와 같이 가끔씩 데이터베이스를 업데이트합니다. 서버 충돌시 손실됩니다.

실제 실시간 세계 상태는 원래 예제에서와 같이 게임 서버가 메모리에 보관해야합니다. 이제 수평 적 확장의 요령은 모든 서버가 모든 순간에 모든 것을 알 필요 는 없다는 입니다. 플레이어 A는 서버 A에 영역 A를 재생하는 경우 예를 들어, 영역 B를 실행하는 서버 B는 일반적으로 알 필요가 없다 어떤 플레이어 A가 자신의 배낭에 - 그리고,이 경우 않는 말 (어떤 이유로 알 필요를, 영역 B의 플레이어 B는 A)에 일종의 원격 스파이 주문을 캐스팅하기 때문에 다른 서버에 해당 정보를 요청할 수 있습니다 .

서버 B가 플레이어 A의 배낭에 대해 알고 싶을 때 서버에 권한 정보가있는 서버를 알 수 있도록 서버에 명확한 책임을 할당해야합니다. 예를 들어 서버 B가 서버 A에게 " 플레이어 A를 감시하는 사람이 있고 달리 말할 때까지 그들이하는 모든 일에 대해 계속 업데이트하도록 할 수 있도록"일종의 업데이트 구독 메커니즘을 포함하고 싶을 것입니다. 또한 플레이어가 어디에 있든지 플레이어가 알아야 할 중요한 글로벌 이벤트를 위해 일종의 글로벌 방송 시스템을 포함하고 싶습니다. 물론 이러한 이벤트도 데이터베이스에 기록해야하지만 모든 서버에 적극적으로 브로드 캐스트한다는 것은 서버가 업데이트를 위해 데이터베이스를 계속 폴링 할 필요가 없음을 의미합니다.


멋진 답변! 이것이 바로 내가 요구 한 내용이었습니다. 감사합니다. 아마도 핵심은 서버를 영역으로 나누고 로직을 메모리에 유지하는 것입니다. 그래도 추가 할 수 있습니다. 방금 새로운 NoSQL 데이터베이스 인 Couchbase에 대해 배웠습니다. 매우 빠른 쓰기 / 읽기 속도 (초당 최대 200k 업데이트)를 제외하고는 CouchDB와 같아야합니다! 어쩌면 이것이 실제로 "실시간 공유 세계 모델"로 작동 할 수 있습니까?
MaiaVictor

@ 독카 아니, 그렇지 않습니다. 소파베이스는 마술이 아닙니다.
Philipp

2

다른 응답은 데이터베이스를 사용하고 통신에 데이터베이스를 사용하지 않는 방법을 지적하는 훌륭한 작업을 수행했습니다. 살펴볼 수있는 또 다른 측면은 정보를 다른 엔터티와 통신하는 방법에 따라 업데이트를 분류하는 것입니다. 서버와의 통신 범위를 지정하는 대신 메시징을 분배하고 엔티티 간 업데이트 통신을 위해 pubsub 메커니즘을 사용할 수 있습니다. 예를 들어, 가까운 사람에 따라 위치를 다르게 취급 할 수 있습니다.

  • 정확한 실시간 위치는 반경 R 내에서 유용 할 수 있습니다.
  • 덜 정확한 위치 업데이트는 반경 2 * R 내에서 유용 할 수 있습니다.
  • 반경 2 * R 이외의 위치 정보는 필요하지 않습니다.

반경 2 * R (또는 엔티티의 업데이트 속도 및 최대 속도를 기반으로하는 것의 몇 배) 내에있는 엔티티를 주기적으로 스캔하고 엔티티를 다른 엔티티의 정확하거나 부정확 한 위치 피드에 등록하여 엔티티의 위치 정보를 전달할 수 있습니다.

서로 다른 유형의 정보에 대해 서로 다른 전략을 가지거나, 공통 사항을 동일한 메시지 큐로 그룹화하거나, 다른 엔티티로 이동해야하는 메시지에 대해 다른 큐를 가질 수 있습니다. '유용하지 않습니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.