騰訊遊戲DBA團隊的發展自白

zping發表於2018-05-07

BA這個崗位跟倉管員很像,就是每天給別人發點貨,別人在你這兒放點貨,DBA工作就是把貨儘快給送出去或者讓人家儘快放進來。當然,還有一份重要的工作,就是讓倉庫裡擺放的貨物儘可能整齊,這也是倉管員的本職工作,你不能拿到貨往倉庫裡一通亂扔,別人來取貨,又讓別人等上半個小時。

 

圖:騰訊遊戲DBA Team Leader Robin

 

內容提綱:

  1. 前輩的積累

  2. Game Cloud Storage架構

  3. Game Cloud Storage組成

  4. Game Cloud Storage去哪

  5. 驅動力及方向探討

前輩的積累:三類遊戲DB架構解析

圖:前輩的積累

 

圖: 騰訊互娛的三類遊戲

騰訊互娛有三類PC端遊戲:1. 平臺休閒遊戲,比如QQGame鬥地主、QQ寵物;2. 高階休閒遊戲,因為遊戲實時性要求增高,對使用者需要就近接入,這類遊戲會進行分割槽處理;3. 大型多人線上遊戲MMOG,這類遊戲玩法比較複雜,可能包含上萬個任務,道具資訊,邏輯很複雜,實時性要求更高,對應單使用者資料量也會變得更大,新的MMOG遊戲或者運營時間長的MMOG單使用者資料量會達到幾百K。手遊這幾年本身遊戲內容不斷的豐富,演進中的遊戲分類基本也可以參考原先端遊。

圖:PLAT/QQGame DB分佈

對於平臺休閒/QQ遊戲的DB,資料集中一個城市存放。因為遊戲玩法相對最簡單,所以,玩家自身的屬性較少,可能就是積分、榮譽、裝扮,少量道具的變化,對應資料量也比較小,比較適合集中存放,不同地域的gamesvr到專線也不會有太大壓力。

此類DB特點:

  • DB資料集中,基本分佈在同城IDC;

  • 單使用者資料結構簡單,資料量少(<1K);

  • 使用者量巨大,通常註冊使用者過億,後臺通過qq號hash或者uin末尾2-3位數字做分散式資料切片處理;

  • 單DBServer支援訪問人數大於10萬。

圖:ACG/飛車 DB分佈

相對MMOG,ACG/飛車的遊戲內容比較簡單,以玩家對局為主,但單使用者的數量會比PLAT / QQGame要大一點,需要大區方式運營,產品策劃對於使用者聚合有更多訴求,大區增加相對少,反而單個大區承載人數的上限,會因為時間推移,逐步通過技術升級不斷提升。

DB特點:

  • 介於PLAT,MMOG之間,單大區支援人數有10萬。

圖:MMOG/ 三國DB分佈

MMOG/ 三國遊戲邏輯複雜,使用者屬性多,玩家升級、打怪、做任務、多人組隊作戰PK為主。本身一個大區,因為內容過多,複雜的經濟系統平衡等,同時承載人數有幾萬的上限,需要通過不斷增加大區,擴張線上人數。實時性要求更高,適合把整個遊戲的後臺物理設施跟使用者作就近接入,這樣使用者體驗會更好一些。

DB特點:

  • DB資料分佈廣,分佈在多個IDC;

  • 單使用者資料結構簡單,資料量少(50K-幾百K);

  • DBServer物理及邏輯擴充套件頻繁,單個區支援同時遊戲人數在2-3萬。

圖:DB架構簡化

經過總結,發現其實架構是蠻簡單的,我們的MySQL就很簡單,一個Master,一個Slave,一個LogDB,把三種遊戲精練一下,其實就是一個很簡單的架構,如上圖。

我們總結了一個經驗,因為單使用者資料量比較小的話,DB部署的適合集中存在一個城市;如果像一個使用者的玩家資料達到幾百K的時候,還是適合整體單區架構包括資料庫做就近接入、Set化。

圖:DB架構精粹

  • 資料部署策略:集中與Set分佈,資料集中適合邏輯簡單,使用者屬性較少的遊戲;IDC Set分佈,適合邏輯複雜,使用者屬性多遊戲.

  • 資料切割策略:平行(QQ號或其它使用者ID)及垂直(不同模組屬性資料,例如QQGame的道具與裝扮資訊的切分)

  • 成本與質量策略:分級投入,核心狀態與日誌流水硬體分離,讓讀寫最頻繁的狀態類資訊保持一個較小的規模,為核心狀態類資料增加熱備投入。流水日誌現在因為近幾年大資料很時髦,也有傳輸到hadoop做分析,也相當於有備份了。

  • 回寫策略:前端cache定時合併回寫,本身Mysql設定innodb_flush_log_at_trx_commit=0,提升2-3倍效能。

  • 簡化策略:對於MMOG將使用者屬性中資料量較大的任務,道具,倉庫資訊以二進位制方式封裝到Blob中。儘可能將DB問題簡化為或IO或記憶體或CPU資源不足的問題。

  • SNS遊戲沒有列出來,是因為現在所有遊戲幾乎都包含了SNS元素,但當社交變為遊戲的重點時,因為熱點不在集中,首要策略是All In Memory,比如前些年特別流行的QQ農場業務。

Game Cloud Storage 架構

圖:Game Cloud Storage架構

Game Cloud Storage主要解決硬體故障處理時間長,版本停機時間長,以及空閒率高這三個問題。mysql前增加了proxy一層做高可用;推出定製的tmysql,秒級線上加欄位;以及將多例項管理變得更加方便,便於縮擴容。

自動切換

圖:Auto-Switch

Auto-Switch首要的考慮是避免誤切換。不切換影響最多回到從前,但誤切換可能導致更加複雜的問題,比如切換到一個落後了幾天資料的Slave,意味著要整體停機,資料亂了,耗費N個小時來做使用者資料回檔工作,新的使用者資料完全丟失。

MySQL Proxy定製擴充套件

  • refresh_backends,在proxy管理埠擴充套件了一個核心的指令refresh backend,通過外圍控制,外圍檢測到master故障,一個指令將proxy指向slave,引導後續gamesvr來的正常訪問,通過增加proxy整體訪問切割,也避免一致性問題;

  • Refresh_user,做user@ip白名單的控制,Proxy本身當它作為MySQL代理的時候,MySQL看到的ip已經都是proxy,增強這一點來延續對於MySQL對來源IP的控制。

  • Show_processlist,檢視來源連線,在MySQL裡看到的都是來自於proxy的連線,這個時候也不方便去定位一些來源連結的問題,所以proxy需要看到能更直接地來自於gameserver等等前端詳細資訊。

  • Refresh_connlog,開啟記錄連線log,保證整個所有DB的請求,可以追溯來源。

監控邏輯

多點監控

高可用切換主要依賴外圍的集中監控,我們分了幾個大的IDC,比如成都、深圳和上海等,我們會在大的區域本地進行監控,比如成都會有本地的點去對成都所有DB定時監測,深圳也會監測,並會對比這兩者,如果兩者有一者存活的話,那就不做處理,如果兩者都有問題的話,就會考慮開始把它進行切換,這是多點監控。

SQL探測,SSH登陸

先通過replace sql探測DB埠,成功則認為ok,否則通過ssh登陸,及touch檔案探測。為什麼要以SHH作為條件?因為MySQL負載高的時候,SQL探測遇到Hang住異常,希望ssh進一步去探測物理機器存活,如果ssh登陸不了或ssh後touch遇到只讀,我們基本斷定一臺機器故障了,這個時候,會推送到下一步第二輪探測佇列,以便整機切換。

DoubleCheck

前述第一輪探測,檢驗完成後,進行Double Check探測,確認問題後,同時檢查一下Slave這些跟進的狀態是不是對的,最近的資料Check Sum校驗是不是一致的,是否有主備Time delay。

最後,滿足切換的前置條件包括以下幾方面:

  1. show slave status, 獲取binlog獲取及本地relay執行對比;

  2. Checksum(7天內)不一致塊數量,小於5個塊可進行切換;

  3. Slave落後Master時間, 小於10秒為可進行切換;

  4. Master已故障時間,小於10分鐘可進行切換;

壓縮

圖:壓縮

關於Blob我們遇到的一個問題是,當時比較火的《地下城與勇士》,上線剛半年單機資料量達到200多G。當時跑的硬體只是只有8G記憶體,6塊SAS磁碟一臺機器,一個週末因為夜間備份時間過長,到了白天還沒結束,業務連續出了2個突發。後來,我們跟韓國的開發商商定了壓縮這個投入最小的方案,通過一次停機,整體資料做一次壓縮,整個資料庫資料從200多G變成了4G。

同時,後續資料修改,從資料庫拿到資料後進行gameserver進行解壓,在gameserver寫入資料庫前就進行壓縮。根據在Slave上對OSS金錢統計相關資料進行的經營統計分析,發現原來要執行400分鐘的,基本上降低到5分鐘。很簡單的壓縮還是蠻有用的,控制核心資料量,對後續這個遊戲長續運營產生了極大的幫助,這個遊戲早期被外界叫做掉線城與虛弱勇士,我想我們做的很簡單的事情,對於幫助遊戲丟掉這個惡名還是有一點幫助的。

圖:壓縮演進歷程

壓縮演進歷程:

2008年,遇到一款MMOG遊戲,單一使用者量很大,當時想到最簡單的辦法就是壓縮。開發方,在select時候,用mysql自身的uncompress做解壓,update直接sql裡邊用mysql函式compress寫回,用MySQL的技術就搞定了。

2011年,逐步會有一些內部的ORM DB公共元件可以做一些透明開關,通過中介軟體層去壓縮資料。

2013年,前面幾種辦法都不是DBA能完全cover的,總需要開發更新中介軟體,或者改寫sql,或者更新gameserver邏輯,我們想了一招,就是把Mysql內完全解決這個問題,完全對開發透明,只要給欄位通過alter增加Compress的屬性,在MySQL底層直接就把大欄位壓縮給做了。這個效率,我們測試中發現遠好於本身innodb page壓縮。

監控

  • 2007年前,監控是比較零散的。

  • 2007年剛入職,接到的第一個稍大的任務就是給DB寫監控,我們都把監控放在資料庫機器本地,還有一些Hang判斷,ErrorLog檢測,還有status我們收集了232個。

  • 2009年,因為有時候某個指標異常的時候,難以得到問題相關因素現場,所以我們針對slowquery量及io利用率超過一定閥值去做了一些現場保留工作,比如show processlist,ps aux,top等,並儲存在監控日誌裡邊。同時,也做了checksum的辦法,OS層指標增加一些我們急需的但公司網管系統並未涉及的,比如每個分割槽的ioutil等。

  • 2012年,為了配合做GCS高可用,做一些時間同步的檢測;為了能更方便地去對比一些DB的效能,聚合效能指標在一起,做了特別方便的效能對比工具。

Game Cloud Storage去哪

圖:Game Cloud Storage去哪

思考GCS去哪,本身也是在想原始碼定製這條路該往哪裡走?如果大家對開源軟體比較有興趣的話,可以參考我們走過的路,可以先嚐試簡單功能的優化,然後考慮擴充套件至性,再考慮效能,因為效能優化的挑戰,涉及到mysql底層更復雜的鎖調優等機制優化,我一直覺得還是蠻大的。最近一兩年,線上加欄位這個痛點解決折後,我們一直希望能MySQL在保持mysql協議基本不變的前提下,能像nosql類似MongoDB擴充套件性那麼好,在這方面做了一些探索。

我們選用了Spider,一個分散式的MySQL底層儲存引擎來解決這個問題,前一兩年開始研究這個Spider,到現在已有超過10個業務上用了起來。Spider官方,在最近一兩年也不斷完善,合併到MariaDB 10的正式版本里面。大家如果對資料庫分散式有需求,同時不希望開發太多修改,可以考慮MariaDB 10的版本。

圖:運維的驅動力

最近業界有很多運維發展方向的討論,我自身也在思考運維的核心驅動力到底是什麼。如果我去回顧過去的一些歷程,我自己考慮運維核心的驅動力還是最簡單兩個字——問題。可能來自業務發展的快速增大資料量,請求併發增大,或者開發使用整個儲存的容易程度,或者平時運維的一些問題,我們不希望自己那麼多通宵處理故障,那麼多步驟那麼辛苦縮擴容。不管在哪家公司,只要我還能夠不斷解決問題,可能這個公司我還能呆得下去;如果沒有問題需要解決,或者是天天時間都花在其他地方了,可能也就沒什麼意思了。

圖:內部平臺產品方向

我們做這些內部平臺,按目前的人力投入,最重要的還是聚焦支撐內部精品大業務的發展。但站在內外部技術平臺競爭加劇的角度,每天都能看到各種各樣渠道吹牛的資訊(就像我今天這樣),都說自己很厲害,很強,我們的下一步該怎麼走,怎麼證明自己的價值,獲得應有的認可,這是個很關鍵的問題。

聽了很多業界大拿的建議,比如葉金榮同學,平靜的思考之後,我們後續計劃或者是策略大概是:首要的,仍然會站在“巨人的肩膀上”,更好的使用及支援整個社群開放協議儲存方案,通過更為深入研究積累,能提供基本閉環的服務支撐能力;第二步,關於怎麼證明團隊價值,從前幾年的“定製”方向轉變到“回到社群”方向,在那個更加廣袤的空間去追求些許的認可。

更新這個ppt之前,翻出來多年前內部分享的一頁ppt,“關於DB的美好想象”,其中第一點因為牽扯業務過於多樣化邏輯資料設計,還是沒做到,第二點做到一點點。

相關文章