มีวิธีที่จะทำให้โลกมีชีวิตชีวาเช่น MMORPG ที่ปรับขนาดได้ในแนวนอนหรือไม่?


11

ลองจินตนาการถึงโลกที่เปิดกว้างของผู้เล่นกว่า 500+ คนที่มีการเปลี่ยนแปลงข้อมูลอย่างรวดเร็วเพียง 20 อัพเดต / ผู้เล่น / วินาที ครั้งล่าสุดที่ฉันทำงานใน MMORPG ที่คล้ายกันมันใช้ SQL ดังนั้น obvioulsy จึงไม่สามารถสืบค้น DB ได้ตลอดเวลา แต่จะโหลดผู้เล่นทุกคนจากฐานข้อมูลไปยังหน่วยความจำในฐานะวัตถุ C ++ และใช้พวกเขา นั่นคือมันปรับขนาดในแนวตั้ง เป็นไปได้ไหมที่จะทำให้เซิร์ฟเวอร์นั้นปรับขนาดได้ในแนวนอนแทน มีฐานข้อมูลที่ออกแบบมาเพื่อรองรับจำนวนการอัปเดตนั้นพร้อมกันหรือไม่?


ทำไมคุณถึงต้องการอัพเดทผู้เล่นในฐานข้อมูล 20 ครั้ง / วินาที?
Balon

@Balon นั่นคือสิ่งที่ฉันสับสน ถ้าฉันไม่อัพเดทในฐานข้อมูลเพียงแค่ในหน่วยความจำแล้วฉันจะมีสถานะที่แตกต่างกันระหว่างเครื่องที่แตกต่างกัน แต่ฉันเดาว่าการอัปเดตฐานข้อมูลมีค่าใช้จ่ายจำนวนมากดังนั้นจึงไม่สามารถใช้งานได้จริงสำหรับการอัปเดตจำนวนนั้น
MaiaVictor

2
หากคุณคิดว่าเครื่องที่แตกต่างกัน (หรือแม้แต่กระบวนการ) จำเป็นต้องมีการอัปเดต 20Hz ในวัตถุหลายร้อยรายการแล้วข้ามฐานข้อมูลอย่างสมบูรณ์และใช้ระบบส่งข้อความโดยตรง แต่สิ่งที่คุณคิดว่าคุณต้องการจริงๆไม่ใช่สิ่งที่คุณต้องการจริงๆ สิ่งที่คุณต้องการคือมีขอบเขตของผู้ที่ต้องการรู้ว่ามีอะไรบ้างจากนั้นจึงมีวิธีในการเคลื่อนย้ายวัตถุระหว่างขอบเขตที่อยู่ด้านบน คุณควรตอบคำถามว่าเพราะเหตุใดคุณจึงต้องการการอัปเดต 20Hz ระหว่างเครื่องที่แตกต่างกันเพื่อคำตอบที่ยอดเยี่ยมบางคนอาจคิดถึงวิธีใหม่ในการดูปัญหา
Patrick Hughes

@ แพททริคฮิวจ์ฉันไม่รู้ว่าฉันต้องการอะไรฉันแค่อธิบายว่าเกมทำงานอย่างไร ตัวละครย้าย 2 ~ 3 แผ่น / วินาที ผู้เล่นอาจถูกล่าโดยสัตว์ประหลาดสองสามตัวดังนั้นอย่างน้อย 10 แผ่นต่อผู้เล่น / วินาที จากนั้นมีไอเท็มที่เน่าเปื่อยอยู่บนพื้นบนกระเป๋าเป้สะพายหลังของผู้เล่น มีการโจมตีที่เคลื่อนที่ไปในทิศทางของผู้เล่นมีการโจมตีที่เคลื่อนที่ไปในทิศทางของสัตว์ประหลาด มีการสลายตัวของสุขภาพ, มานาที่ใช้, ตัวนับที่สร้างความเสียหายพิษต่อผู้เล่น ดังนั้นสิ่งต่าง ๆ เปลี่ยนแปลงอย่างรวดเร็วจริงๆ นี่คือการออกแบบเกม การออกแบบดังกล่าวจะถูกปรับขนาดในแนวตั้งได้อย่างไร?
MaiaVictor

1
ฉันเห็นสิ่งนี้ใน HackerNews เมื่อไม่นานมานี้: paralleluniverse.coพวกเขากำลังทำงานบนฐานข้อมูลที่ทำหน้าที่แบ่งส่วน / กระจายข้อมูลเชิงพื้นที่ทั้งหมดสำหรับคุณ ฉันเดาว่าภายใต้ประทุนพวกเขากำลังทำทุกสิ่งในคำตอบด้านล่าง
ชักเย่อ

คำตอบ:


17

กรณีทดสอบของผู้เล่น 500 คนที่กำลังสื่อสารกันทั้งหมดนั่นคือกระแสข้อมูล 250K ที่บินได้ที่ความเร็ว 20Hz แบนด์วิดท์ภายในสำหรับนั้นคือประมาณ 100 ไบต์ต่อข้อความประมาณ 500MB / วินาที ฟังดูทะเยอทะยาน โดยเฉพาะระหว่างกระบวนการ

หากคุณแยกผู้เล่นออกเป็นกลุ่มละ 100 คนนั้นจะลดลงเหลือ 20MB / วินาทีและต่อไปเรื่อย ๆ นี่คือเหตุผลที่ MMOs มีโซนและในโซนเหล่านั้นมีอิทธิพลต่อฟองอากาศน้อยและอื่น ๆ ลงไปเรื่อย ๆ จนกว่าแบนด์วิดท์จะสมเหตุสมผล

ปัญหาดั้งเดิมอาจกล่าวได้ว่าหากคุณมี 10 คนที่แบ่งปันข้อมูลเรียลไทม์ทั้งหมด แต่คุณต้องการการแบ่งปันทั้งหมด 500ครั้งนั่นคือการเชื่อมโยงการสื่อสารที่เพิ่มขึ้นแบบทวีคูณและวิธีที่เราจะแก้ไขปัญหานั้นได้ ฉันกลัวว่าไม่มีกระสุนวิเศษที่ฉันเคยได้ยินว่าสามารถทำให้ความก้าวหน้าทางเรขาคณิตหายไปได้อย่างน่าอัศจรรย์

อย่าใช้ฐานข้อมูลเพื่อสื่อสารนั่นคือสิ่งที่ใช้สำหรับส่งข้อความ ใช้ฐานข้อมูลเพื่อบังคับใช้ธุรกรรมและจัดเก็บข้อมูลที่คุณไม่ต้องการให้ผู้เล่นเสีย MMO ส่วนใหญ่ที่ฉันคุ้นเคยกับอัปเดตฐานข้อมูลด้วยข้อมูลผู้เล่นแบบไดนามิกทุก ๆ 1-10 นาทีหรือที่จุดที่มีประโยชน์เช่นการเปลี่ยนโซนหรือเข้าสู่โซน "ปลอดภัย" ในการออกแบบ

คุณอาจต้องออกแบบเกมที่ต้องการสำหรับผู้เล่นทุกคนไม่ว่าจะอยู่ไกลแค่ไหนเพื่ออัพเดตเนื้อหากระเป๋าเป้สะพายหลังของผู้เล่นคนอื่น ๆ แบบเรียลไทม์

นอกจากนี้เปลี่ยนรูปแบบการอัปเดตจาก 20Hz เป็นความเร็วตามระยะทางใครบางคนที่อยู่ห่างออกไป 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 in = 9 และมันจะไป มันเป็นเช่นนี้: ส่งสถานะ msg เซิร์ฟเวอร์ส่งผลลัพธ์ให้ฉันและลูกค้าอีก 2 ราย (1 ใน, 3 ออก) และลูกค้าอีก 3 คนทำเช่นนั้น (1 ใน 9 จาก) ในขณะที่มันดูเป็นเส้นตรงสำหรับลูกค้าเพียงรายเดียวของ 3 คุณจะได้รับการคูณด้วยจำนวนลูกค้าทั้งหมดสำหรับปริมาณงานทั้งหมดของระบบ สำหรับ desync แม้กระบวนการบนกล่องฟิสิคัลเดียวกันจะไม่ซิงค์จนกว่าจะมีการสร้างและส่งข้อความสถานะมันเป็นเพียงเรื่องของการที่ไพพ์หมด, RAM ในพื้นที่หรือเน็ต
Patrick Hughes

5

ใช้การกรองพื้นที่ที่น่าสนใจ หากโลกถูกแบ่งออกเป็น 3 เซิร์ฟเวอร์และพื้นที่บนเซิร์ฟเวอร์ 1 นั้นอยู่ใกล้กับพื้นที่ของเซิร์ฟเวอร์ 3 ก็ไม่มีเหตุผลที่พวกเขาจะแบ่งปันข้อมูลเกี่ยวกับเอนทิตีเลย

ในทำนองเดียวกันบนเซิร์ฟเวอร์เดียวจะส่งข้อมูลที่เกี่ยวข้องให้กับลูกค้าเท่านั้น หากผู้เล่น A อยู่ฝั่งตรงข้ามทั้งหมดของแผนที่จากผู้เล่น B ไม่มีเหตุผลที่จะส่งการอัปเดตเกี่ยวกับ B ไปยัง A หรือในทางกลับกัน

เมื่อคุณมีเซิร์ฟเวอร์หลายเครื่องในโลกที่ต่อเนื่องคุณจะมีเอนทิตีใกล้กับเซิร์ฟเวอร์ 2 ที่อยู่ใกล้กับเอนทิตีบนเซิร์ฟเวอร์ 1 คุณสามารถส่งอัปเดตจากเซิร์ฟเวอร์ "สิทธิ์" สำหรับเอนทิตีไปยังเซิร์ฟเวอร์อื่น (ตามความเหมาะสม) และเช่นเดียวกันกับการส่งต่อข้อความใด ๆ ไปยังเซิร์ฟเวอร์ที่เชื่อถือได้ตามความเหมาะสม

ใช่ในกรณีนี้เซิร์ฟเวอร์หนึ่งตัวจะล้าสมัยเล็กน้อยสำหรับเอนทิตีที่เฉพาะเจาะจง อย่าพยายามแก้ปัญหานั้น เพียงจัดการกับมัน สมมติว่าเอนทิตีอาจล้าสมัยเล็กน้อย ทำตรรกะใด ๆ ที่ต้องการข้อมูลที่ทันสมัยบนเซิร์ฟเวอร์ที่ได้รับอนุญาตให้เป็นเจ้าของเอนทิตี เมื่อนิติบุคคลส่งผลกระทบต่อผู้อื่นให้ส่งข้อความและคิดว่าอาจใช้เห็บตรรกะของเกมหลายรายการก่อนที่จะถูกประมวลผลและมุมมองของคุณอัปเดต

การออกแบบนี้ทำให้ง่ายขึ้นในการเธรดเซิร์ฟเวอร์เดียว ไม่มีเอนทิตีควรแก้ไขอื่นโดยตรงส่งข้อความเท่านั้นและแคชพร็อกซีเซิร์ฟเวอร์ต่อเซิร์ฟเวอร์ / ต่อเธรดควรถือว่าล้าสมัยเล็กน้อย

ตัวอย่างเช่นถ้าเอนทิตี A โจมตีเอนทิตี B อย่าตรวจสอบอายุการใช้งานของ B จากนั้นส่งข้อความแจ้งความตายหากพบ 0 เพียงแค่ส่งข้อความ "เสียหาย" ให้เซิร์ฟเวอร์ที่เชื่อถือได้สำหรับ B จัดการแล้วจัดการใด ๆ ข้อความ "เอนทิตีที่เสียชีวิต" ถูกส่งโดยเซิร์ฟเวอร์ B ในภายหลังหากเอนทิตี A ใส่ใจกับสิ่งนั้น

เช่นเดียวกับแอปพลิเคชั่นที่ไม่ใช่เกมขนาดใหญ่ที่ปรับขนาดได้ ฐานข้อมูลกลางไม่ใช่เทคโนโลยีการแบ่งปันทันใจที่น่าอัศจรรย์ เซิร์ฟเวอร์สองเครื่องต้องสื่อสารกับข้อความแบบอะซิงโครนัสในชุดงานเพื่อรักษาปริมาณงานสูง ดังนั้นความนิยมของเทคโนโลยีเช่น AMPQ และไม่ชอบ ฐานข้อมูลสำหรับการจัดเก็บและสนับสนุนการซิงโครไนซ์จากความจำเป็นทำให้พวกเขาสามารถใช้สำหรับการสื่อสารไม่ใช่เพราะพวกเขามีไว้สำหรับการซิงโครไนซ์หรือการสื่อสาร


ขอขอบคุณมันจบลงด้วยความสงสัยที่เหลืออยู่ของฉัน นอกจากนี้คุณให้ความคิดของฉันในการแยกเซิร์ฟเวอร์โดยผู้เล่นไม่ใช่ด้าน - นี่จะดูราบรื่นขึ้น แต่ละเซิร์ฟเวอร์ดูแลผู้เล่น x ฉันชอบสิ่งนี้มาก! มันถูกใช้หรือไม่ และยังมีอีกสิ่งหนึ่ง ตามที่ฉันถามไปแล้วฉันเพิ่งเรียนรู้เกี่ยวกับฐานข้อมูล NoSQL ใหม่คือ Couchbase มันควรจะเหมือนกับ CouchDB ยกเว้นความเร็วในการเขียน / อ่านที่รวดเร็วมาก: อัปเดตสูงสุด 200k ต่อวินาที! บางทีนี่อาจใช้งานได้จริงเช่น "แบบจำลองโลกที่ใช้ร่วมกันแบบเรียลไทม์" หรือยัง
MaiaVictor

ฉันไม่มีความคิดเลยว่าเทคนิคนั้นถูกใช้ใน wild นอกเหนือจาก "sharding" ปกติของเซิร์ฟเวอร์ เพียงแค่เล่นโดยผู้เล่นและพื้นที่ทางภูมิศาสตร์หมายความว่าเซิร์ฟเวอร์แต่ละเครื่องอาจจำเป็นต้องทราบถึงเอนทิตีจำนวนมากในพื้นที่ที่หลากหลายเพิ่มการโหลดเซิร์ฟเวอร์และการสื่อสารระหว่างเซิร์ฟเวอร์ที่เพิ่มขึ้นอย่างมาก การทำตามพื้นที่หมายถึงเซิร์ฟเวอร์ของคุณอาจมีพื้นที่มากเกินไปในพื้นที่แออัด (แม้ว่าคุณสามารถแยกและเข้าร่วมพื้นที่ในกรณีดังกล่าวได้แบบไดนามิก) แต่หมายความว่าเซิร์ฟเวอร์แต่ละเครื่องมีชุดเอนทิตีที่ไม่เกี่ยวข้องกับผู้เล่น .
Sean Middleditch

@Dokkat: มันอาจเป็นไปได้ที่จะมี "พื้นที่อ่อนนุ่ม" ซึ่งคุณมีเซิร์ฟเวอร์แต่ละเครื่องที่จัดการกับผู้เล่นในส่วนหนึ่งของโลกของเกม แต่ให้พวกเขาส่งผู้เล่นไปยังเซิร์ฟเวอร์อื่นอย่างโปร่งใสหากพวกมันอยู่ห่างจาก ภูมิภาคของเซิร์ฟเวอร์ดั้งเดิม คุณเพียงแค่ต้องทำให้แน่ใจว่าการส่งมอบราบรื่นพอที่ผู้เล่นจะไม่สังเกตเห็น คุณสามารถลองใช้เทคนิคการปรับตัวแบบแฟนซีเพื่อให้กลุ่มผู้เล่นโต้ตอบบนเซิร์ฟเวอร์เดียวกันแม้ว่าพวกเขาจะอยู่ในขอบเขตของภูมิภาคก็ตาม
Ilmari Karonen


2

อย่าคิดว่าฐานข้อมูลเป็นแบบจำลองโลกที่แชร์กันแบบเรียลไทม์ซึ่งเก็บทุกอย่างเกี่ยวกับทุกอย่างตลอดเวลาดังที่คุณสังเกตเห็นว่ามันไม่สามารถทำงานได้

ให้รักษาฐานข้อมูลแทนไฟล์บันทึกที่อัปเดตโดยอัตโนมัติแทน: คุณอัปเดตฐานข้อมูลเป็นครั้งคราวเช่นเมื่อผู้เล่นลงชื่อเข้าใช้หรือออกหรือย้ายจากโซนหนึ่งไปอีกโซนหนึ่งหรือทุกครั้งที่มีสิ่งสำคัญเกิดขึ้นที่คุณไม่ต้องการ สูญหายในกรณีที่เซิร์ฟเวอร์ขัดข้อง

สถานะโลกจริงตามเวลาจริงควรจัดขึ้นโดยเซิร์ฟเวอร์เกมในหน่วยความจำเช่นเดียวกับในตัวอย่างดั้งเดิมของคุณ ตอนนี้เคล็ดลับสำหรับการปรับแนวนอนคือว่าไม่ทุกความต้องการเซิร์ฟเวอร์ที่จะรู้ทุกอย่างในทุกช่วงเวลา ตัวอย่างเช่นถ้าผู้เล่นที่กำลังเล่นอยู่ในโซนบนเซิร์ฟเวอร์เซิร์ฟเวอร์ B วิ่งโซน B มักจะไม่จำเป็นที่จะต้องรู้ว่าสิ่งที่ผู้เล่นที่มีอยู่ในกระเป๋าเป้สะพายหลังของพวกเขา - และถ้ามันไม่จำเป็นที่จะต้องทราบว่าด้วยเหตุผลบางอย่าง (พูด, เนื่องจากผู้เล่น B ในโซน B ใช้คาถาการสอดแนมระยะไกลใน A) ผู้เล่นสามารถขอข้อมูลจากเซิร์ฟเวอร์อื่นได้

สิ่งนี้ต้องการให้คุณกำหนดความรับผิดชอบที่ชัดเจนให้กับเซิร์ฟเวอร์ดังนั้นเมื่อเซิร์ฟเวอร์ B ต้องการทราบเกี่ยวกับกระเป๋าเป้สะพายหลังของผู้เล่น A จะรู้ว่าเซิร์ฟเวอร์ใดมีข้อมูลที่เชื่อถือได้ นอกจากนี้คุณยังอาจต้องการรวมกลไกการสมัครรับข้อมูลอัปเดตบางอย่างเช่นเซิร์ฟเวอร์ B สามารถบอกเซิร์ฟเวอร์ A " ฉันมีคนแอบดูผู้เล่น A ให้ฉันอัปเดตเกี่ยวกับทุกสิ่งที่พวกเขาทำจนกว่าฉันจะบอกคุณเป็นอย่างอื่น " ยังต้องการรวมระบบการออกอากาศทั่วโลกบางประเภทสำหรับเหตุการณ์สำคัญระดับโลกที่ผู้เล่นอาจจำเป็นต้องรู้ไม่ว่าพวกเขาจะอยู่ที่ไหน แน่นอนเหตุการณ์ดังกล่าวควรถูกบันทึกไว้ในฐานข้อมูลด้วย แต่การที่พวกเขาออกอากาศอย่างแข็งขันไปยังเซิร์ฟเวอร์ทั้งหมดหมายความว่าเซิร์ฟเวอร์ไม่จำเป็นต้องทำการสำรวจฐานข้อมูลเพื่อทำการอัพเดท


คำตอบที่ยอดเยี่ยม! นี่คือสิ่งที่ฉันขอขอขอบคุณ ดังนั้นกุญแจสำคัญคือการแบ่งเซิร์ฟเวอร์ในพื้นที่รักษาตรรกะในหน่วยความจำ ฉันอาจจะเพิ่ม: ฉันเพิ่งเรียนรู้เกี่ยวกับฐานข้อมูล NoSQL ใหม่คือ Couchbase มันควรจะเหมือนกับ CouchDB ยกเว้นความเร็วในการเขียน / อ่านที่รวดเร็วมาก: อัปเดตสูงสุด 200k ต่อวินาที! บางทีนี่อาจใช้งานได้จริงเช่น "แบบจำลองโลกที่ใช้ร่วมกันแบบเรียลไทม์" หรือยัง
MaiaVictor

@ Dokkat ไม่มันจะไม่ Couchbase ไม่ใช่เวทมนต์
Philipp

2

การตอบกลับอื่น ๆ ทำได้ดีมากในการชี้ให้เห็นถึงวิธีการใช้ฐานข้อมูลและไม่ใช้ฐานข้อมูลเพื่อการสื่อสาร อีกแง่มุมหนึ่งที่คุณอาจพิจารณาคือจัดหมวดหมู่การอัปเดตของคุณตามวิธีที่ข้อมูลต้องการสื่อสารกับเอนทิตีอื่น ๆ แทนที่จะเป็นการสื่อสารขอบเขตไปยังเซิร์ฟเวอร์คุณสามารถกระจายการส่งข้อความของคุณและใช้กลไก pubsub สำหรับการสื่อสารการอัพเดตระหว่างเอนทิตี ตัวอย่างเช่นคุณอาจปฏิบัติต่อสถานที่แตกต่างกันโดยขึ้นอยู่กับว่าใครอยู่ใกล้คุณ:

  • ตำแหน่งที่แม่นยำและเรียลไทม์อาจมีประโยชน์ภายในรัศมี R
  • การอัพเดทตำแหน่งที่แม่นยำน้อยกว่าและน้อยกว่าอาจมีประโยชน์ภายในรัศมี 2 * R
  • ไม่จำเป็นต้องใช้ข้อมูลตำแหน่งเกินกว่ารัศมี 2 * R

คุณอาจสื่อสารข้อมูลตำแหน่งสำหรับเอนทิตีโดยการสแกนเอนทิตีเป็นระยะภายในรัศมี 2 * R (หรือหลาย ๆ อันขึ้นอยู่กับอัตราการอัปเดตและความเร็วสูงสุดของเอนทิตี) และการสมัครสมาชิกเอนทิตี้ของฟีดตำแหน่งที่แม่นยำ

คุณสามารถมีกลยุทธ์ที่แตกต่างกันสำหรับข้อมูลประเภทต่าง ๆ จัดกลุ่มสิ่งทั่วไปลงในคิวข้อความเดียวกันหรือมีคิวที่แตกต่างกันสำหรับข้อความที่ต้องไปเอนทิตีที่แตกต่างกัน (หรือเพียงแค่ส่งพวกเขาไปยังเอนทิตีที่กว้างที่สุด ไม่มีประโยชน์)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.