Bayangkan dunia terbuka dengan 500+ pemain dengan data berubah secepat 20 pembaruan / pemain / detik. Terakhir kali saya bekerja di MMORPG yang serupa, menggunakan SQL, jadi obvioulsy tidak bisa meminta DB sepanjang waktu. Sebagai gantinya, itu memuat semua pemain dari DB ke memori sebagai objek C ++ dan menggunakannya. Artinya, diskalakan secara vertikal. Apakah mungkin untuk membuat server yang skalabel secara horizontal? Apakah ada database yang dirancang untuk mendukung jumlah pembaruan itu secara bersamaan?
mmo
data-structure
databases
scalability
Viktor Maia
sumber
sumber
Jawaban:
Test case dari 500 pemain yang berkomunikasi, itu adalah 250K aliran informasi terbang sekitar pada 20Hz. Bandwidth internal untuk itu adalah, dengan asumsi 100 byte setiap pesan, sekitar 500MB / detik. Kedengarannya ambisius. Terutama antar proses.
Jika Anda memisahkan pemain menjadi 100, itu menurunkan menjadi 20 MB / detik, dan seterusnya. Itulah sebabnya MMO memiliki zona, dan di zona itu gelembung kecil pengaruhnya, dan seterusnya ke bawah hingga bandwidth menjadi masuk akal.
Masalah aslinya dapat dinyatakan bahwa jika Anda memiliki 10 orang yang semuanya berbagi informasi waktu nyata, tetapi Anda ingin 500 orang berbagi , itu merupakan pertumbuhan yang eksponensial dari tautan komunikasi dan bagaimana kita dapat mengatasinya . Saya khawatir tidak ada peluru ajaib yang pernah saya dengar yang secara ajaib dapat membuat kemajuan geometris hilang.
Jangan gunakan basis data untuk berkomunikasi, itu gunanya pesan. Gunakan database untuk memberlakukan transaksi dan menyimpan info yang Anda tidak ingin kehilangan pemain. Kebanyakan MMO yang saya kenal hanya memperbarui basis data dengan info pemain dinamis setiap 1-10 menit, atau pada titik berguna seperti transisi zona atau memasuki zona "aman" dalam desain.
Anda mungkin harus mendesain ulang permainan kebutuhan untuk setiap pemain, tidak peduli seberapa jauh, untuk memiliki update realtime isi ransel setiap pemain lain.
Juga mengubah pola pembaruan dari 20Hz ke kecepatan berdasarkan jarak, seseorang 1 mil jauhnya tidak perlu tahu bahwa Anda bergerak 1 kaki tepat 230,6 detik, kemudian kaki lain pada 231,4 detik, mereka dapat menangani Anda bergerak 15 kaki setiap 10 detik.
sumber
Gunakan pemfilteran area yang menarik. Jika dunia dipecah menjadi 3 server, dan area pada server 1 tidak berada di dekat area server 3, tidak ada alasan bagi mereka untuk berbagi informasi tentang entitas sama sekali.
Demikian juga, pada satu server, hanya mengirim informasi yang relevan kepada klien. Jika pemain A berada di ujung peta yang sepenuhnya berlawanan dari pemain B, tidak ada alasan untuk mengirim pembaruan tentang B ke A, atau sebaliknya.
Ketika Anda memiliki beberapa server di dunia berkelanjutan, Anda akan memiliki entitas di dekat tepi pada server 2 yang dekat dengan entitas di server 1. Anda dapat mengirim pembaruan dari server "otoritatif" untuk entitas ke server lain (bila perlu) , dan juga meneruskan pesan apa pun ke server yang berwenang sebagaimana mestinya.
Ya, dalam hal ini, satu server akan sedikit kedaluwarsa untuk entitas tertentu. Jangan mencoba menyelesaikannya. Atasi saja. Asumsikan bahwa entitas mungkin sedikit ketinggalan zaman. Lakukan logika apa pun yang memerlukan informasi terkini hanya di server yang memiliki entitas secara otoritatif. Ketika suatu entitas memengaruhi entitas lain, kirim pesan dan anggaplah dibutuhkan beberapa kutu logika game sebelum diproses dan tampilan Anda diperbarui.
Desain ini juga memudahkan untuk memasang satu server. Tidak ada entitas yang harus langsung memodifikasi entitas lain, hanya mengirim pesan, dan cache proxy per-server / per-thread lokal harus dianggap sedikit kedaluwarsa.
Misalnya, jika entitas A menyerang entitas B, jangan periksa umur B dan kemudian mengirim pesan kematian jika menyentuh 0. Cukup kirim pesan "rusak", biarkan server otoritatif untuk B menanganinya, dan kemudian menangani Pesan "entitas-died" dikirim oleh server B nanti jika entitas A peduli tentang itu.
Hal yang sama berlaku untuk aplikasi non-game yang besar dan dapat diskalakan. Basis data pusat bukanlah teknologi berbagi instan yang ajaib. Dua server harus berkomunikasi dengan pesan, secara asinkron, dalam batch, untuk mempertahankan throughput yang tinggi. Karenanya popularitas teknologi seperti AMPQ dan sejenisnya. Basis data untuk penyimpanan dan mendukung sinkronisasi karena diperlukan sehingga dapat digunakan untuk komunikasi, bukan karena itu sendiri dimaksudkan untuk sinkronisasi atau komunikasi.
sumber
Anda mungkin akan tertarik dengan artikel ini di Gamasutra , di mana pengembang Eve Online membahas bagaimana mungkin untuk berhasil menjalankan permainan dengan 400.000 pemain aktif ... dalam satu basis data SQL.
sumber
Jangan menganggap database sebagai semacam model dunia bersama waktu nyata yang menyimpan segala sesuatu tentang segala hal setiap saat - seperti yang Anda perhatikan, itu tidak mungkin berhasil.
Alih-alih, perlakukan database lebih seperti file penyimpanan yang diperbarui secara otomatis: Anda memperbarui database hanya sesekali, seperti ketika pemain masuk atau keluar atau berpindah dari satu zona ke zona lain, atau setiap kali terjadi sesuatu yang penting yang tidak Anda inginkan. hilang jika terjadi crash server.
Status dunia waktu nyata yang sebenarnya harus dipegang oleh server permainan, dalam memori, seperti dalam contoh asli Anda. Sekarang, trik untuk penskalaan horizontal adalah tidak semua server perlu mengetahui segalanya setiap saat . Misalnya, jika pemain A bermain di zona A di server A, server B berjalan zona B biasanya tidak perlu tahu apa yang pemain A memiliki dalam ransel mereka - dan, jika tidak perlu tahu bahwa untuk beberapa alasan (misalnya, karena pemain B di zona B melemparkan semacam mantra mata-mata jarak jauh pada A) ia hanya dapat meminta informasi dari server lain .
Ini mengharuskan Anda untuk menetapkan tanggung jawab yang jelas ke server, sehingga ketika server B ingin tahu tentang ransel pemain A, ia akan tahu server mana yang memiliki informasi resmi tentang itu. Anda juga mungkin ingin menyertakan semacam mekanisme pembaruan berlangganan, sehingga misalnya server B dapat memberi tahu server A " Saya memiliki seseorang yang memata-matai pemain A, terus perbarui semua yang mereka lakukan sampai saya katakan sebaliknya. " Anda mungkin akan juga ingin memasukkan semacam sistem siaran global untuk acara global penting yang mungkin perlu diketahui pemain di mana pun mereka berada; tentu saja, kejadian seperti itu juga harus direkam dalam database, tetapi jika mereka disiarkan secara aktif ke semua server berarti bahwa server tidak harus terus polling database untuk pembaruan.
sumber
Respons lain telah melakukan pekerjaan yang baik untuk menunjukkan bagaimana menggunakan database, dan tidak menggunakan database untuk komunikasi. Satu aspek lain yang mungkin Anda perhatikan adalah mengategorikan pembaruan Anda berdasarkan bagaimana informasi tersebut perlu dikomunikasikan ke entitas lain. Daripada lingkup komunikasi ke server, Anda bisa mendistribusikan pesan Anda dan menggunakan mekanisme pubsub untuk mengkomunikasikan pembaruan antar entitas. Misalnya, Anda mungkin memperlakukan lokasi secara berbeda berdasarkan siapa yang dekat dengan Anda:
Anda dapat mengkomunikasikan informasi lokasi untuk suatu entitas dengan memindai secara berkala entitas dalam radius 2 * R (atau beberapa kelipatan yang didasarkan pada tingkat pembaruan dan kecepatan maksimum suatu entitas), dan berlangganan entitas ke feed lokasi yang tepat atau tidak tepat dari entitas lain.
Anda dapat memiliki strategi berbeda untuk berbagai jenis informasi, kelompokkan hal-hal umum ke dalam antrian pesan yang sama, atau memiliki antrian yang berbeda untuk pesan yang perlu pergi ke entitas yang berbeda (atau hanya mengirim mereka ke entitas yang paling luas dan memiliki pesan yang dibuang jika mereka tidak berguna).
sumber