遊戲服務端中的分散式 ,集群?

分散式 ,集群在遊戲服務端 中是如何運用的?或者說遊戲中運用到的技術是屬於集群還是分散式?


這個問題問的很空泛,或者說根本就不是一個完整的問題,每個遊戲的特性,需求是不同的,同樣與之對應的分布設計,也是不同的。

重要的事情強調3遍,問題的目的性!目的性!目的性!

通俗的來講,遊戲伺服器只是伺服器設計中的一種而已。

遊戲伺服器的設計,大致可氛圍強交互(帶狀態的消息),弱交互(無狀態的消息)

首先你要明白你想得到什麼,如果你想得到一個大世界的概念,那麼你要付出的代價主要是數據同步的代價,換言之,就是,我的消息如何進入?我需要從哪裡取得我要的數據?哪條路徑最短?取得後我如何保持這個路徑用於下次相關狀態信息請求還走這裡?我如何維護在鏈路信息被建立下,別的玩家對我的數據要求(讀取或者寫入)?當數據完成修改,我什麼時機將數據同步到永久介質中(資料庫,帶IO的緩存)?

來,一個個問題給你展開講講。

(1)我的數據如何進入?

關於數據入口的問題,都快被說爛了,網上常說的建立N個Gate主機,它不負責邏輯的處理,只負責消息的驗證和消息的過濾。通過Gate驗證的數據會被發送到後面一台或者幾台業務伺服器上去做進一步的處理。看上去是不是很美妙?要知道,任何事情都是雙刃劍。這樣的設計,要求的是你的內部網卡必須給力,無論你後面是一台主機,還是N台主機。你都需要至少配置兩塊網卡(除非你想讓一個網卡負責接收玩家信息和轉發,那你的流量積壓會導致你的入口用戶吞吐變的很微妙,此消彼長互相牽制),一個網卡用戶吞吐用戶玩家的消息,一個網卡用於吞吐內部傳遞數據的信息。這樣,我們把頭抬起來,你看到的就是,你的網卡要是掛了,你的整個系統就崩潰了。網卡相當於內存而言,還是脆弱的。所以,有些遊戲設計者寧可用內存,也不會考慮IO,畢竟IO相對本機實在是不靠譜,你不能說自己沒問題就沒問題了,你還的看別人有沒有問題,同時,為了保證雙方都無問題,你需要開發相關的平衡機制,付出額外的代碼來保證IO的完整性。這就是雙刃劍的兩面性。當然,設計是根據需求而進行取捨的,不能依賴框架是什麼我們就開發什麼,而是我要什麼,怎麼讓框架滿足我。

(2)我需要從哪裡取得我要的數據?

實際這個問題,就是路徑問題,當然,最快的,我們可以在本地的內存中獲得。如果我們的設計都是弱連接,用戶數據可以從任意一台Gate進來,我們怎麼選擇?你看,這裡,你為了數據的一致性,你就不能相信本地內存,你需要去一個"公共"的地方獲得"唯一"的對象。這本身就又是一次IO旅程。就算最短一次來回,那麼先不考慮你的邏輯其他的問題,你至少內部要經過4次IO才能返回給用戶信息(如果你後面的"公共"的地方還是一個集群,比如kv集群,那麼命中IO可能走的更多次)。你的這次設計會進一步加深你對IO的依賴。俗話說的好,節點越多越難維護。如果我為此獲得一個路徑成本不能保持的話,每次都獲取一次,你的成本累計是很客觀的。你的伺服器時間會大量的消耗在IO的傳輸上。所以,這裡數據以及邏輯服務的介面獲取就顯得異常重要。你需要怎樣的設計來保持你的維護成本?用戶可是懶得聽你的"IO迷宮"是如何走出來的。

(3)哪條路徑最短?

別和我說你會用中間件就是最短路徑,路徑的長短和保持,是取決於你的需求的。通常,現在用到的中間件大量採用的是CORBA標準,中間件是簡潔了你的代碼開發,使得你不用關注內部的路徑尋找以及數據收發,但是,很重要的是,效能的體現,往往不在於你的邏輯複雜度。此話怎講?你的邏輯複雜度循環10萬次,可能都比你進行一次IO要塊。中間件隱藏了細節,同時,提出的要求是你對數據流的設計也必須有一定的"數據鈍化"(也就是實時性不敏感的數據)。如果你的中間件調度用到了10ms,剩下多少時間留給你的邏輯呢?再往深了說,你的Gate還在等著用IO呢。所以,這部分如何保持,如何降低成本,是你必須考慮的問題。

(4)數據同步性

分散式不是沒有代價的,任何分散式代價的成本都是來自於糟糕的設計。通常,我們為了保證數據的一致性,不敢把某一個數據放在一個節點上。那麼,我就需要面臨一個巨大的問題,我們怎麼保證我要的數據是最新的?如果我的數據不在一個節點上,那麼我就需要"比較",如果在一個節點上,那麼這個數據是否正在被別的數據做重要修改?你是否可以使用?還是要等待別的修改後,回傳修改此節點信息後你在用?這又是一個坑。設計不好,往往會給自己的後路留下滿地荊棘。

(5)數據的存儲

當然,你可以說,我可以定時存儲數據,用另外的進程自己去做。但是,需要注意的是,你應該怎麼去思考刷入數據的時機?有些數據,是有關聯性的。你修改一個欄位的時候,必須要等另一個欄位同時被修改才可以。比如,你花錢買了一個頭盔,剛好扣錢的時候,你存儲了,如果你運氣足夠好,你會看到,你存入資料庫的時候,頭盔也在,錢還沒扣。這裡,就是存儲時機的問題了。

綜上所述,我個人的意思是,不要一上來就討論架構,那是沒有意義的。

在設計上,關鍵是,你的目的性。

你怎麼做能讓用戶滿足對你的消息等待?(大家的時間都很寶貴)

你的運維怎麼在你紛繁複雜的伺服器架構中去找到某一個用戶的消息到底到達到哪裡了?幾時到達的?

你怎麼設計你的架構保留最優路徑?

你怎麼保證你的存儲時機?

所以,請在問這個問題之前,先問問自己,你需要一個怎麼樣的需求,然後確定自己的目的性,最後,再來問,什麼樣的架構可以滿足我的需求。


現在的遊戲架構主要還是分區分服,單打獨鬥的老套路。當然,所謂的「分服」並不是說只有一個物理節點,也有按照 SOA 的理念拆分成多台伺服器的實現(比如按照 Gateway、User、World、Map 等角色來拆分,方法各有不同)。

但總體來說都有性能瓶頸,甚至單點問題,無法實現線性橫向擴展的高性能集群(HPC),以及強一致(抗腦裂)、多活 IDC 的高可用集群(HAC)。因此嚴格說都不能算是真正的分散式集群計算。

關於大規模網路遊戲的「真·分散式集群架構」,我寫過一篇設計文檔:http://baiy.cn/doc/moog_svr_arch.pdf 可以作為參考。

聲明:其中很多設計均是依託於我們已有的成熟技術才能得以實現:如單點千萬量級並發的高性能網路伺服器組件、獲多個國家和國際發明專利保護的分散式架構和演算法、支持實時壓縮和強加密的分散式虛擬文件系統等等,故此文僅作參考。


推薦閱讀:

遊戲數據存儲方案?
如何評價微軟的orleans框架?
遊戲伺服器使用MongoDB作為資料庫,還有必要使用Redis緩存嗎?
作為遊戲客戶端開發,需要掌握哪些伺服器方面的知識,以及如何學習?
手游開發中網路通信使用長連接還是短連接比較好?

TAG:伺服器 | 遊戲伺服器 | 集群 | 分散式 |