顯示廣告
隱藏 ✕
※ 本文為 adst513 轉寄自 ptt.cc 更新時間: 2012-05-17 02:37:46
看板 C_Chat
作者 art1 (人,原來不是人)
標題 Fw: [EVE] CarbonIO與BlueNet:下一代的網路技術
時間 Tue May 15 15:02:06 2012


※ [本文轉錄自 ONLINE 看板 #1FiVxyb- ]

看板 ONLINE
作者 art1 (人,原來不是人)
標題 [EVE] CarbonIO與BlueNet:下一代的網路技術
時間 Tue May 15 15:00:09 2012


原始英文連結:http://community.eveonline.com/devblog.asp?a=blog&nbid=2332
簡體文章連結:http://eve.tiancity.com/homepage/article/2012/05/15/35308.html
游戏新闻 — EVE Online官方网站 新纪元已开启
EVE Online 新纪元---官方网站,2012全球最大星战网游,全球同步,神作启航!! ...
 
這是中國CCP翻譯歐服Devblog的成果,底下已轉成繁體

我有在twitter上建議Horace先翻一些跟TiDi有關的Devblog文章,這雖然不是我建議的那
幾篇,但依舊很好看,這種充滿技術名詞的文件光看頭就大了,幸好中國CCP會持續翻譯
到全部翻完,即使仍舊看不太懂,但有中文可看真是太棒了!!



==============================================================================

【開發日誌】CarbonIO與BlueNet:下一代的網絡技術
作者:CCP Curt 譯者:CCP Lion

大多數熟悉EVE的人都知道,它是用Python語言編寫的,如果要說得更具體點,那就是

Stackless Python。Stackless是在Python基礎上編寫的一套微線程框架,它能在不產生

大量Python自身額外開銷的情況下同時容納數百萬條的線程。但話還是要說回來,它畢竟

還是Python,因此擺脫不了“解釋器全局鎖”(Global Interpreter Lock,下文將其簡

稱為GIL)。



  GIL是一個序列鎖,用來保證在任何時候都只能有一個線程利用Python解釋器(包括其

所有數據)來運行自己。因此,儘管Stackless Python感覺上好像具備多線程處理能力,

但實際上它還是單線程的,只不過運用了任務分離、頻道、定時器及共享內存等一系列招

數而已。 其實過去有些協作式的多任務操作系統也是這樣幹的,其好處是保證了所有線

程都能被執行,不會出現被操作系統提前結束這一情況(除非被操作系統懷疑非法宕機)

。  GIL的存在使得程序員在編寫遊戲邏輯時能自信推斷出程序的全局狀態,省去了一大

堆採用異步回調函數的麻煩。


但這樣有一大缺點:由於EVE中有部分框架的代碼是用Python編寫的,因此它們都免不了

GIL造成的負面影響。 比如,一段用來讀取Python數據的C++語言代碼必須在獲得GIL後才

能讀取一個字符串。


      圖片短網址:http://tinyurl.com/77s5fcc
[圖]
 
      http://image.tiancity.com/article/UserFiles/Image/EVE/2012/05/15/eve0515
      _a01.jpg

      使用Python的任務都要獲得GIL才能合法地被處理,這樣等同於Python任務都是
      單線程執行。  (這圖畫得不太好看,人家只是個程序員,不是美術師哦)


一言以蔽之,Stackless Python 代碼的運行速度不會高於你最快的那個CPU核心的速度。

在一台4核或8核CPU的服務器上,其中只有一核在超負荷運作,其他都沒派上用場。當然

,為了讓這些CPU核心物盡其用,我們可以在它們身上加載更多的節點。對於EVE中許多無

狀態或對共享狀態依賴度極低的代碼而言,這沒什麼問題。但對於像太空模擬或空間站行

走這樣高度依賴共享狀態的代碼而言,就成了一個大問題。


假設一個CPU核心就能處理所有的邏輯並且寫出來的Python代碼較為清晰,那我之前說的

都不是什麼問題。不過,想必我不用說大家也知道,儘管Gridlock等小組已經在優化工作

方面做到了其極致,但我們現在面臨的情況依舊是單個CPU已經無法處理一場大型會戰了

。最近上市的CPU速度是更快、緩存容量也更大、總線也更寬裕並且具備更好的執行流水

線,但在EVE需要其給力的地方,卻沒有任何進步。近期(也可能包括中長期)的趨勢是

“橫向增長”,即同時運行多個CPU核心。



總體而言,多核CPU的流行對EVE的長遠發展是一大利好。 未來那些30乃至60核CPU的機器

能夠很好地體現EVE集群部署方式的優勢,這是因為CPU核心之間切換的效率將遠遠大於線

程之間切換的效率。但就目前而言,為了提升遊戲運行速度,我們需要把網絡及通用讀寫

這樣的EVE模塊從GIL中解放出來。



多核心、超標量的硬件對當今的網絡遊戲來說,都是個好消息。這些遊戲很適合這種架構

,並且能很容易地進行並行處理。可惜對於依賴Python的EVE來說,這就算不得好消息了

。那些對運行速度要求極高、不需要Python便利開發優勢的EVE系統需要儘早擺脫GIL的束

縛。CarbonIO在這個方向上可以說是向前邁進了一大步。



  CarbonIO 是在StacklessIO 基礎上的一個自然提升。它實際上是個從頭寫起的全新引

擎,目標非常明確:讓網絡流量擺脫GIL的束縛,並且讓任何C++代碼也能這樣做。後半個

目的是重頭戲,我們花了大半年才把它完成。


這裡不得不先稍微提一下StacklessIO。對Stackless Python的網絡通信而言,它可以說

是個質的飛躍。通過讓網絡操作變得具有“無堆棧的意識”,StacklessIO可以將一個被

鎖住的操作轉移到一個未被GIL鎖住的線程上,這樣該操作就可以繼續等候,而Stackless

則繼續處理其他事務。然後,該操作重新獲得GIL,告訴Stackless其操作已完成。這樣,

接收端就可以同步進行,使得通訊速度可以達到操作系統級別,並且能基本上在第一時間

內回報給Python。


      圖片短網址:http://tinyurl.com/8xy2lj3
[圖]
 
      http://image.tiancity.com/article/UserFiles/Image/EVE/2012/05/15/eve0515
      _a02.jpg
      StacklessIO在沒有GIL的情況下完成Python請求


  CarbonIO在此基礎上更上一層樓。由於它是在完全脫離於GIL的情況下運行多線程通信

引擎,因此Python與該系統之間的交互便是完全獨立了。沒有Python的要求,它也能收發

數據。


請允許我再強調一下:CarbonIO能在Python不作任何要求的情況下收發數據。這是並發性

的,不需要GIL。



當一個連接通過CarbonIO被建立後,系統會調用WSARecv()開始接收數據。與Python進程

並行的線程池將這些數據解密、解壓縮然後轉義到數據包裡。這些數據包會排隊,等著

Python來處理。


當Python覺得它需要一個數據包時,它會往下調用“可能已將此包準備就緒”的CarbonIO

。這意味著數據在離開隊列被返回整個過程中根本沒有用到GIL。這是一個瞬時過程,至

少也有納秒那麼快。這個並行讀取能力是CarbonIO的第一大好處。



第二大好處便是發送了。數據以其原始形式排在工作線程隊列裡,然後便等著Python來調

用了。 其間的壓縮、加密、打包及WSASend()調用都沒有觸及GIL而發生在另一個線程裡

,這樣操作系統便可以安排它運行在另一顆CPU上了。C++代碼也可以調用一個方法來這樣

做,並不需要特別的架構變更。StacklessIO也可以那樣做,但在脫離上述背景的情況下

,這會變得很沒意義。



讓我們再來回顧一下之前提到的“已將此包準備就緒”。但如果我們要安置一個C++回調

鉤子函數,使得非Python模塊能在不觸及Machonet的情況下獲得那個數據,這可行嗎?

行啊,這時我們要用的就是BlueNet了。



  CarbonIO不停地進行數據接收,並且能在無Python介入的情況下告訴C++模塊數據已收

到。



  Machonet是一個大型功能集合,它負責對會話進行分流、導向及管理,負責對數據包的

時間計劃/發送以及其他一系列將EVE撮合成一個有機整體的功能。由於它是個Python模塊

,因此所有的數據遲早都必須觸及那倒霉的GIL,無論數據在哪個節點。無論一個C++模塊

的速度有多快,GIL仍然是個繞不過的瓶頸。這使得我們曾經都不太願意做大量的C++優化

,因為任何優化後取得的優勢都會被Machonet 中的GIL吞噬。




但現在情況不一樣了。



現在C++的系統能通過BlueNet收發數據包,無需再理會GIL。這原來是專門為了空間站行

走設計的。空間站行走功能需要發送大量的表示移動的數據。EVE中太空飛行的那部分功

能所需要收發的數據,我們以前可以用旁門左道的方法來解決,但對於如此近距離的人物

動作,就不行了。 之前我們做的預測顯示,即使把空間站行走發送數據的頻率控制在一

般程度,該功能也會把整個服務器集群拖垮。通過在沒有GIL干擾的情況下對流入/流出


C++原生系統(比如物理系統)的數據進行分流,BlueNet成功地解決了該問題。由於在這


種情況下,數據還是保持著其原生態,因此整個系統運行的速度就比之前提高了。


這個具體是怎麼運作的呢? BlueNet保存著一份所有必要Machonet結構的只讀拷貝,另外

,所有的數據包前都會附上很小的一段((8到10個字節)數據頭。這個數據頭里含有路徑

信息。當BlueNet接到一個數據包時,它會對其進行檢測,然後合理地再分發:要么轉發到

另一個節點上,要么交給被本地的已註冊的C++應用程序。如果它轉發,那這個過程中將用

不到GIL,根本不會調用Machonet/Python。這意味著我們的代理服務器完全能以並行方式

對BlueNet的數據包進行分流,而不必去經過Python導致額外開銷的產生。那這效率究竟提

高了多少呢? 我們還無法確定,但在降低機器負載及延遲方面,它還是非常非常明顯的。

實際上我們還不能將數據公開,因為它們好得難以置信。




除此之外,CarbonIO也包含了大量底層優化,絕大多數都是小規模的速度提升,但把這些

統統疊加起來,整個系統的運行速度也就有了顯著提高。以下幾點值得一提:



  工作分組


雖然我很難在本文中把這事兒說得太細,但CarbonIO非常出色地將工作分組來處理。簡而

言之,就是某些操作有了一個固定的開銷。網絡引擎有許多這樣的開銷,但其他所有具有

重要意義的代碼也有大量開銷。通過一些別出心裁的技巧,我們是可以將許多這樣的工作

合併在一起,這樣就只產生一次開銷。就像把邏輯數據包都組合在一起發送在一個


TCP/IP MTU裡一樣(EVE一直就是這樣幹的),CarbonIO將這一做法進一步深化。一個比

較簡單的例子就是GIL獲取集合。



第一個要嘗試取得GIL的線程會先建立起一個隊列,這樣其他要獲取GIL的線程只需將自己

的喚醒調用排在隊列末尾然後返迴線程池就行。那GIL最後被取得時,第一個線程會吸乾

整個隊列,不必在每次IO喚醒時釋放/重拾GIL。在一個繁忙的服務器上這種情況很多,因

此這種改進對我們來說是一大利好。



  openSSL整合


  CarbonIO用openSSL來實現SSL,並且能在不鎖定GIL的情況下與該協議數據通信。該庫

只是用作一個BIO對而已,所有的數據導航還是由CarbonIO通過完成端口進行的。這有助

於我們循序漸進地讓EVE變得更安全,甚至將來可以把官方網站上的某些帳號管理功能挪

到EVE客戶端上去,這樣可以更方便大家。



  壓縮整合


  CarbonIO能利用zlib或snappy對每一個數據包都進行壓縮/解壓縮,這一過程同樣是無
需GIL的。


  實戰檢驗


通過對一個繁忙的代理服務器(人數峰值大約1600人,一個平常工作日)的24小時數據的

收集,我們發現CPU的總體使用率與單個用戶的CPU使用率都出現了大幅下降。這都歸功於

CarbonIO的總體架構,其作用就是降低事務的開銷。當服務器變得繁忙之後,這些優化的

效果會被逐漸增多且必須處理的事務所抵消,但在最高負載時,CarbonIO還是讓我們的遊

戲增速了不少。


      圖片短網址:http://tinyurl.com/775fsg8
[圖]
 
      http://image.tiancity.com/article/UserFiles/Image/EVE/2012/05/15/eve0515
      _a04.jpg


      圖片短網址:http://tinyurl.com/8x7q7eo
[圖]
 
      http://image.tiancity.com/article/UserFiles/Image/EVE/2012/05/15/eve0515
      _a05.jpg
      以上為24小時內單個用戶的CPU使用率

      圖片短網址:http://tinyurl.com/7cd22zw
[圖]
 
      http://image.tiancity.com/article/UserFiles/Image/EVE/2012/05/15/eve0515
      _a06.jpg
      以上為同樣的24小時內總體CPU使用率


至於SOL(星系)節點,由於它們的主要職責是遊戲機製而非網絡管理,因此它們從該優

化中獲得的優勢並不那麼明顯,但我們還是看到它們的CPU使用率下降了8%-10%。



需要指出的是,在上述的檢驗中我們沒有運用BlueNet,沒有用CarbonIO的數據導航,也

沒有用離GIL的數據壓縮/解壓縮。



  總結


總的來說,比起以前,EVE能更好地利用現代服務器硬件帶來的優勢,能讓它在同樣的時

間內完成更多的工作,這樣就間接提升了一個系統所能進行的操作上限。通過將我們的代

碼盡量與GIL脫離,我們反而為那些真正需要用它的代碼騰出了空間。另外,由於不再有

那麼多代碼需要競相獲取GIL,系統的總體運行效率也會提升。有了BlueNet再加上很好的

代碼優化,提速空間已被打開。雖然最後的結果仍有待實踐檢驗,但至少,我們已經消除

了一大瓶頸。



原文 http://community.eveonline.com/devblog.asp?a=blog&nbid=2332

--
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.130.245.45

※ 發信站: 批踢踢實業坊(ptt.cc)
※ 轉錄者: art1 (220.130.245.45), 時間: 05/15/2012 15:02:06
kane1031:有沒有高手可以解釋下 太專業看不懂1F 05/15 15:09
tsunamimk2:不是高手 快速掃一遍的topic 1.把worker拆開來多執行緒2F 05/15 15:11
Gravity113:對不起我END了,可以簡單說明前後差異嗎?3F 05/15 15:11
tsunamimk2:2是不要讓global lock鎖住不管interpreter的鳥事4F 05/15 15:13
tsunamimk2:因為看起來似乎C/C++對python的介面是有個lock的
tsunamimk2:結果就是很多根本不用lock的事情還得去排隊等
tsunamimk2:新的引擎把io的排程從這lock解放了
tsunamimk2:所以可以有效的把io攤平並善用proxy
tsunamimk2:以及可以善用多cpu的環境可以開多thread的好處
Gravity113:更高效率的使用多核心處理器的意思?10F 05/15 15:15
tsunamimk2:還有package的改良 看起來像是參考SIMD的搞法11F 05/15 15:16
tsunamimk2:同時地傳送多筆資料並且能正確的route到指定的node
tsunamimk2:喔 果然是個pool,他弄了一個queue去管理有限的lock
Gravity113:海嘯你要回這麼細的話可以麻煩回文嗎?14F 05/15 15:17
tsunamimk2:重點是讓scale變得更容易更大15F 05/15 15:17
Gravity113:我相信回一篇文會造福很多版眾16F 05/15 15:17
tsunamimk2:可是..回了完全沒有acg點啊17F 05/15 15:18
art1:EVE Online使用的技術...不知道這沒有ACG點...orz18F 05/15 15:18
Gravity113:我不認為這篇技術文章的ACG點會多到哪去XD19F 05/15 15:18
tsunamimk2:我覺得很多是有做過大規模service的人都會遇到的啦...20F 05/15 15:19
tsunamimk2:就好像最近流行的 有人把node.js做了個web server
tsunamimk2:號稱超有效率,(但是v8 一堆安全性的洞)
kira925:Micro-Threading...23F 05/15 15:25
tsunamimk2:yap24F 05/15 15:26
tsunamimk2:但實務上不會搞到那麼誇張 就是讓資料能不被lock最好
kira925:這招好像Ruby也有人在玩 好像就是Actor model?26F 05/15 15:26
tsunamimk2:例如這個就是說 不用過python的就別過了27F 05/15 15:27
tsunamimk2:Design pattern比較像worker?
kira925:其實就是很像Erlang不是嗎XD29F 05/15 15:28
tsunamimk2:沒玩過erlang耶.有甚麼特色嗎?30F 05/15 15:29
kira925:我再看一次文章好了...Erlang就是一種Actor model的實作31F 05/15 15:47
tsunamimk2:沒研究過 應該去稍微survey一下32F 05/15 15:48
kira925:Stackless python的Wiki頁面 See also有Erlang連結33F 05/15 15:58
kira925:確實跟Actor Model有點關係
tsunamimk2:稍微看了一下 大概知道是在說甚麼東西了...35F 05/15 17:22

--
※ 看板: ACG 文章推薦值: 0 目前人氣: 0 累積人氣: 314 
分享網址: 複製 已複製
e)編輯 d)刪除 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇