Чи є спосіб зробити такий динамічний світ, як MMORPG, горизонтально масштабований?


11

Уявіть, що у відкритому світі є 500+ гравців, дані змінюються так само швидко, як 20 оновлень / програвач / секунду. Минулого разу я працював у подібному MMORPG, він використовував SQL, тому обвіоульсія не могла весь час запитувати БД. Натомість він завантажував усіх гравців з БД у пам'ять як об’єкти C ++ та використовував їх. Тобто вона масштабується вертикально. Чи можна було б зробити цей сервер горизонтально масштабованим? Чи існує база даних, призначена для підтримки такої кількості оновлень одночасно?


Чому ви хочете оновити програвач у базі даних 20 разів на секунду?
Балон

@Balon саме тут я плутаюся. Якщо я не оновлюю його в базі даних, просто в пам'яті, то у мене будуть різні стани між різними машинами. Але я здогадуюсь, що оновлення БД мають величезні накладні витрати, тому це дійсно не буде працювати для такої кількості оновлень?
MaiaVictor

2
Якщо ви дійсно по-справжньому думаєте, що для різних машин (або навіть процесів) потрібні оновлення 20 ГГц для сотень об’єктів, то повністю обходять базу даних та безпосередньо використовують систему обміну повідомленнями. Але те, що ти насправді, справді думаєш, що хочеш, - це не те, що ти насправді хочеш. Те, що ви хочете, - це мати розумну сферу того, хто повинен знати що, а потім мати спосіб акуратно транспортувати об’єкти між областями поверх цього. Ви повинні відповісти на питання, чому вам потрібні оновлення на 20 Гц між різними машинами для чудових відповідей, хтось може подумати про новий спосіб розглянути проблему.
Патрік Х'юз

@PatrickHughes Я не знаю, що мені потрібно, я просто пояснюю, як працює гра. Персонажі рухаються 2 ~ 3 плитки / секунду. Гравець на полюванні може бути оточений кількома монстрами, тож принаймні 10 плиток / гравець / секунда. Потім на підлозі, на рюкзаку гравця - гнилі предмети. Є атаки, що рухаються в напрямку гравця, є атаки, що рухаються в напрямку монстра. Там погіршується здоров’я, застосовується мана, таймери наносять шкоди отруєнню гравцеві. Отже, справи змінюються дуже швидко. Це ігровий дизайн. Яким чином можна вертикально масштабувати таку конструкцію?
MaiaVictor

1
Я це бачив на HackerNews трохи раніше: paralleluniverse.co Вони працюють над базою даних, яка виконує всі просторові сегментації / дистрибуції для вас. Я б здогадався, що під кришкою вони роблять усі речі у відповідях нижче.
буксири

Відповіді:


17

Тестовий випадок з 500 гравців, які спілкуються між собою, це 250 000 потоків інформації, що летять на частоті 20 ГГц. Внутрішня пропускна здатність для цього складе, припускаючи 100 байт кожного повідомлення, приблизно 500 МБ / сек. Звучить амбітно. Особливо між процесами.

Якщо ви розділите гравців на групи по 100, це знижується до 20 МБ / сек тощо. Ось чому ММО мають зони, а в цих зонах невеликі бульбашки впливу і так далі вниз, поки пропускна здатність не стане розумною.

Оригінальною проблемою можна констатувати, що якщо у вас є 10 людей, які всі діляться інформацією в режимі реального часу, але ви хочете, щоб 500 спільного доступу до них, це експоненціальне зростання комунікаційних зв’язків і як ми можемо це подолати . Я боюся, що немає жодної магічної кулі, про яку я коли-небудь чув, що може магічним чином змусити геометричну прогресію.

Не використовуйте базу даних для спілкування, саме для цього і обмін повідомленнями. Використовуйте базу даних для примусового виконання транзакцій та зберігання інформації, яку ви не хочете, щоб програвачі програвали. Більшість MMO, з якими я знайомий, лише оновлюють базу даних з інформацією про динамічний програвач кожні 1-10 хвилин, або в зручних точках, таких як переходи в зоні або введення "безпечних" зон в дизайн.

Ви , можливо , доведеться перепроектувати в грі необхідно для кожного гравця, незалежно від того , як далеко, щоб в реальному часі поновлення вмісту рюкзака кожного іншого гравця.

Також змініть схему оновлення з 20 Гц на швидкість, що базується на відстані, комусь на відстань 1 милі не потрібно знати, що ви перемістили 1 ногу рівно на 230,6 секунди, потім ще одну ногу за 231,4 секунди, вони можуть мати справу з вами, рухаючи 15 футів кожні 10 секунд.


Дивовижна та інформативна відповідь, дякую. Але можу додати, що хоча світ змінюється дуже швидкими темпами, гравець може бачити лише інших гравців безпосередньо поруч. Я не вважаю це геометричним - 500 гравців надсилають інформацію на сервер; сервер періодично надсилає інформацію цим 500 гравцям. Як я бачу, це лінійно. Але головний пункт - у 4-му пункті: якщо я використовую базу даних лише для зберігання, то я завантажую дані в пам'ять. Якщо я завантажую дані в пам'ять в машині, я створюю десинхронізовану версію світу. Ось чого я не розумію.
MaiaVictor

Для 1 клієнта: 1 msg out + 1 msg in = 2. Для 2 клієнтів: 2 msg out, 2 msg у = 4. Для 3 клієнтів: 3 msg out, 3 msg у = 9. І так це відбувається. Це так: надішліть статус msg, сервер надсилає результат мені та іншим 2 клієнтам (1 in, 3 out) та 3 клієнтам, які роблять це (1 у 9 out). Хоча це виглядає лінійним лише для одного клієнта з 3-х, ви можете помножити це на всі клієнти на загальну пропускну здатність системи. Що стосується десинхронізації, навіть процеси в одній фізичній коробці не синхронізовані, поки не буде створено та відправлено повідомлення про стан, це лише питання про те, де спорожняється труба, локальна ОЗУ чи мережа.
Патрік Хьюз

5

Використовуйте область фільтра за інтересами. Якщо світ розбитий на 3 сервери, а область на сервері 1 ніде не знаходиться поблизу області сервера 3, то для них взагалі немає приводу ділитися інформацією про сутності.

Так само на одному сервері надсилайте клієнтам лише відповідну інформацію. Якщо гравець A знаходиться на абсолютно протилежному кінці карти від гравця B, немає жодної причини надсилати оновлення про B до A, або навпаки.

Якщо у вас є декілька серверів у безперервному світі, у вас будуть об'єкти біля краю на сервері 2, близьких до сутностей на сервері 1. Ви можете надсилати оновлення з "авторитетного" сервера для сутності на інший сервер (коли це доречно) , а також пересилайте будь-які повідомлення на авторитетний сервер у відповідних випадках.

Так, у цьому випадку один сервер буде трохи застарілим для певних організацій. Не намагайтеся вирішити це. Просто розібратися з цим. Припустимо, що юридичні особи можуть трохи застаріти. Виконайте будь-яку логіку, яка потребує оновленої інформації лише на сервері, який авторитетно володіє сутностями. Коли суб'єкт впливає на іншого, надішліть повідомлення та припустіть, що воно може взяти кілька логічних ігрових кліків перед його обробкою та оновленням вашого перегляду.

Така конструкція також значно полегшує передачу потоку на один сервер. Жодна сутність не повинна безпосередньо змінювати іншу, лише надсилати повідомлення, а локальні кеші проксі-серверів / потоків повинні вважатись трохи застарілими.

Наприклад, якщо суб'єкт А атакує сутність B, не перевіряйте термін служби B і не надсилайте повідомлення про смерть, якщо воно потрапляє 0. Просто надішліть повідомлення "пошкоджене", нехай авторитетний сервер для B обробляє його, а потім обробляйте будь-яке Повідомлення "померла сутність", надіслане сервером B пізніше, якщо про це піклується сутність A

Це ж стосується будь-якого великого масштабованого неігрового додатка. Центральна база даних не є магічною технологією обміну миттєвими можливостями. Два сервери повинні спілкуватися з повідомленнями, асинхронно, партіями, щоб підтримувати високу пропускну здатність. Звідси популярність таких технологій, як AMPQ тощо. Бази даних призначені для зберігання та підтримки синхронізації з необхідності, що дозволяє використовувати їх для зв'язку, а не тому, що вони самі призначені для синхронізації чи зв'язку.


Дякую, цим закінчилася більшість моїх залишилися сумнівів. Також ви дали мені ідею розділити сервери від гравців, а не з областями - це виглядало б гладше. Кожен сервер піклується про x гравців. Мені це дуже подобається! Це використовується? А також, є лише ще одна річ. Як я вже запитував вище, я щойно дізнався про нову базу даних NoSQL, Couchbase. Він повинен бути як CouchDB, за винятком дуже швидкої швидкості запису / читання: до 200k оновлень в секунду! Можливо, це насправді може спрацювати як така "світова модель у режимі реального часу", чи ні?
MaiaVictor

Я не маю уявлення, чи застосовується ця техніка в дикій природі, крім звичайного грубого "заточування" серверів. Завдяки цьому гравці та географічна зона означає, що кожному серверу може бути відома дуже велика кількість сутностей у різноманітних наборах областей, збільшуючи навантаження сервера та значно збільшуючи міжсерверну комунікацію. Якщо це робити за площею, ваш сервер може перевантажуватися на переповнених областях (хоча в цьому випадку ви можете динамічно розділяти та приєднуватися до областей), але це означає, що кожен сервер має менший набір відповідних об'єктів, що не належать до гравців, та геометрію для відстеження .
Шон Міддлічч

@Dokkat: Можливо, є якісь "м'які зони", де кожен сервер в основному обробляє гравців у певній частині ігрового світу, але їх потрібно прозоро передати гравцеві на інший сервер, якщо вони занадто далеко відхиляться від регіон їх оригінального сервера. Вам просто потрібно переконатися, що передача проходить досить гладко, щоб гравці насправді цього не помічали. Ви навіть можете спробувати використати деякі пристосовані пристосувальні методи, щоб утримувати кластери взаємодіючих гравців на одному сервері, навіть якщо вони трапляються лише на кордоні регіону.
Ільмарі Каронен


2

Не думайте про базу даних як про якусь модель світового доступу в режимі реального часу, яка зберігає все про все в усі часи - як ви помітили, це не може працювати.

Натомість трактуйте базу даних більше як автоматично оновлений файл збереження: ви оновлюєте базу даних лише періодично, наприклад, коли гравці входять або виходять або переміщуються з однієї зони в іншу, або коли відбувається щось важливе, чого ви не хочете бути втрачено у разі аварії сервера.

Фактичний стан світу в реальному часі повинен зберігатися в ігрових серверах, пам'яті так само, як у оригінальному прикладі. Тепер хитрість горизонтального масштабування полягає в тому, що не кожному серверу потрібно знати все в кожен момент . Наприклад, якщо гравець A грає в зоні A на сервері A, сервер B, який працює в зоні B, зазвичай не повинен знати, який гравець А має в своєму рюкзаку - і, якщо це так потрібно знати , що з якоїсь - то причини (наприклад, оскільки гравець B в зоні B кидає якусь заклинання віддаленого шпигунства на A), він може просто попросити іншого сервера про цю інформацію .

Це вимагає, щоб ви поклали чіткі обов'язки на сервери, так що коли сервер B хоче знати про рюкзак гравця A, він буде знати, який сервер має авторитетну інформацію про це. Ви також , ймовірно , захочете включити який - то механізм передплати поновлення, так що , наприклад , сервер B може просто сказати сервера А « у мене є хто - то шпигує гравця А, тримати мене в курсі про все , що вони роблять , поки я не скажу інакше. » Ви, ймовірно , також хочуть включити якусь глобальну систему мовлення для важливих глобальних подій, про які гравці, можливо, повинні знати, незалежно від того, де вони перебувають; Звичайно, такі події також слід фіксувати в базі даних, але їх активна трансляція на весь сервер означає, що серверам не доведеться продовжувати опитувати базу даних для оновлень.


Дивовижна відповідь! Саме це я і просив, дякую. Тому, можливо, ключовим є розділення сервера на області, зберігаючи логіку в пам'яті. Можна все ж додати: я щойно дізнався про нову базу даних NoSQL, Couchbase. Він повинен бути як CouchDB, за винятком дуже швидкої швидкості запису / читання: до 200k оновлень в секунду! Можливо, це насправді може спрацювати як така "світова модель у режимі реального часу", чи ні?
MaiaVictor

@Dokkat ні, не буде. Couchbase не є магією.
Філіп

2

Інші відповіді виконали гарну роботу, вказавши, як використовувати базу даних, а не використовувати базу даних для спілкування. Ще один аспект, на який ви можете звернути увагу, - це класифікувати оновлення залежно від того, як інформація повинна передаватися іншим організаціям. Замість того, щоб спілкуватись із серверами, ви можете поширювати повідомлення та використовувати механізми pubsub для передачі оновлень між сутностями. Наприклад, ви можете по-різному ставитися до місця розташування залежно від того, хто вам близький:

  • Точне місцезнаходження в реальному часі може бути корисним в радіусі R
  • Менш точні, рідше оновлення місцеположення можуть бути корисні в радіусі 2 * R
  • Інформація про місцезнаходження може бути не потрібна за радіусом 2 * R

Ви можете передавати інформацію про місцезнаходження для об'єкта, періодично скануючи сутність у радіусі 2 * R (або деякий кратний з цього на основі швидкості оновлення та максимальної швидкості сутності) та підписуючи сутність на точний або неточний канал розташування іншого суб'єкта господарювання.

Ви можете мати різні стратегії для різних типів інформації, групувати загальні речі в одні і ті ж черги повідомлень або мати різні черги для повідомлень, яким потрібно переходити до різних об'єктів (або просто надсилати їх до найширшого набору сутностей і відхиляти повідомлення, якщо вони не корисний).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.