公司主要產品是策略經營SLG遊戲.屬於玩家間的交互非常頻繁的類型.有非常多的公共數據(比如世界地圖數據)很多地方經常會大規模的調用其他玩家的用戶數據或大量通知(比如上百人的大規模國戰,還有聊天,羣發郵件)

原先服務端C++一直採用的是本地緩存.即在伺服器啟動時把數據大部分從資料庫都讀取到內存中來(至少公共數據和可能和其它玩家有關聯的數據以及可能會被定時器任務改變的數據).

這樣的做法很大的弊端就是伺服器啟動時需要比較長時間.每次維護一次都至少需要十分鐘以上。而且伺服器有BUG也無法熱更.必須停服維護.而且都要10分鐘以上...

然而優點就是開發邏輯清晰簡單.基本模式都是取相關的對象指針=&>使用或修改數據=&>存庫.而且性能較好.不知道各位對於這種交互較多的服務端有沒有什麼更好的解決方案?(能夠滿足性能好,開發簡單,啟動快或者可以熱更)大家在自己的服務端中用的都是什麼樣的緩存機制和服務端架構?================

補充點

現在初步的方案計劃使用redis來替代本地緩存.藉此來達到維護不用重新從DB載入數據到內存的目的,這樣就可以快速重啟維護了,也算實現了目標吧.但是這樣感覺整個業務邏輯複雜程度大大提高了.因為所有的數據在用的時候都要經過(獲取緩存=&>如果緩存不存在取庫=&>操作數據=&>寫資料庫=&>寫緩存)這樣一個過程,在一個操作需要大量零散數據的情況下整個處理需要多次的和redis和資料庫交互.不知道會不會發生雪崩.


設計的時候是應該把強交互的情景和弱交互的情景隔離開的。

最簡單的方法是實現成開房間機制,國戰開打了,找場景進程開場景實例,玩家全傳進去打。打國戰的過程中玩家交互都是進程內數據訪問。打完了再傳出來,存檔。

如果遊戲有網關進程,那這樣實現起來就非常容易,成本很低。

如果沒有,那可以評估下客戶端打國戰的時候多維持一條到場景服的連接的改動風險。

瀉藥。

用redis代替本地緩存是可行的,不過我沒用過redis,我們現在的項目用的是memcached+mysql,支撐1000k左右是沒問題的,memcached主要用來減少select資料庫的操作從而減少IO負載。我覺得主要是代碼層上操作很繁瑣,每次操作數據之前,把所有的數據取出來到本地(先從緩存取,沒有就從資料庫取,當然這都是封裝到一個介面裡面的),然後修改本地數據,寫資料庫,寫緩存。很多這樣的操作,就導致了很多代碼的copy,看起來很不爽,不過可以大量減少資料庫操作的壓力,cache一般用的好的話,並沒有什麼壓力。

而且重啟伺服器,對cache沒有任何影響。


為什麼不使用共享內存緩存數據呢?這樣重啟得時候數據都在本地,並不需要重新初始化。
本地緩存和 redis都用過,都沒啥問題。而且在設計本地緩存的時候,我還設計了buffer功能,定期寫入資料庫,減少資料庫壓力。看到問題描述,我覺得問題出在

伺服器啟動時需要比較長時間.每次維護一次都至少需要十分鐘以上。而且伺服器有BUG也無法熱更.必須停服維護.而且都要10分鐘以上...

你這是有多大的數據呀?試著重新設計一下,不那麼緊急的數據就等玩家真正需要的時候再讀到緩存中。

至少在手遊項目中,我的實踐經驗都是秒起的。

不建議redis替代本地緩存.

存在2個問題:1. 性能變動: redis基於網路, 本地緩存是直接讀寫內存, 速度差距多少? 2. 介面的完全變動, 如果使用redis同步介面, 代碼修改量可以接受, 但是在交互非常頻繁的情況下, 在增加一個同步等待完成時間, 這塊需要優先做個預估. 估計性能會下降多少? (個人猜測同步介面不可行, 數據讀寫這塊應該是幾千上萬倍的下降, 再加上cpu光等待同步了, 乘方一下, 性能嘩嘩的掉). 如果同步介面不可行, 只能使用非同步介面, 帶來的代碼變動就很大. 有多少把握能夠不出重大bug發新版本?

在運營階段(?)冒這麼大風險, 只為了10分鐘的啟動時間, 個人覺得, 基本不考慮

建議現階段了就不要嘗試去減少10分鐘, 去減少10分鐘的次數, 比如每天找個人少的時間維護一次. 不要每天高峯期重啟十次.
這個架構沒必要引入redis,增加架構的複雜性。重啟載入時間達10分鐘的問題應該可以大幅優化,可能不是你數據量大的問題。引入redis並不能解決停服更新的問題。

獲取緩存=&>如果緩存不存在取庫。 這個封裝成函數,業務應該感知不到。

操作數據=&>寫資料庫=&>寫緩存。這個改成只寫緩存,然後單獨一個進程定時寫臟數據到資料庫。

在這種需要使用大量數據寫和實時性要求較高的使用場景裏,redis顯然滿足不了你們的需求。

另外,在伺服器內存中除了地圖、部分玩家等數據需要首次裝入外,其他數據都可以後臺智能傳輸不用重啟時裝入內存,這樣重新設計後你們伺服器就根本不需要10分鐘重啟時間,最多1-2分鐘之內完全足夠重啟。
按照普通 sata硬碟算,讀取速度 每秒算100M/s 1分鐘就是6G 10分鐘大概是600G 你們緩存了這麼多數據?

性能好:這一個要求就把無狀態伺服器剔除了。可以在現有基礎上做個熱更方案,動態鏈接庫或 Lua 都可以,數據放在宿主中,業務邏輯放在動態鏈接庫或 Lua 裏,但無論採用哪種方式,開發一定會複雜些


推薦閱讀:
相關文章