※ 本文為 adst513 轉寄自 ptt.cc 更新時間: 2012-05-17 02:37:46
看板 C_Chat
作者 標題 Fw: [EVE] CarbonIO與BlueNet:下一代的網路技術
時間 Tue May 15 15:02:06 2012
※ [本文轉錄自 ONLINE 看板 #1FiVxyb- ]
看板 ONLINE
作者 標題 [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全球最大星战网游,全球同步,神作启航!! ...
EVE Online 新纪元---官方网站,2012全球最大星战网游,全球同步,神作启航!! ...
我有在twitter上建議Horace先翻一些跟TiDi有關的Devblog文章,這雖然不是我建議的那
幾篇,但依舊很好看,這種充滿技術名詞的文件光看頭就大了,幸好中國CCP會持續翻譯
到全部翻完,即使仍舊看不太懂,但有中文可看真是太棒了!!
幾篇,但依舊很好看,這種充滿技術名詞的文件光看頭就大了,幸好中國CCP會持續翻譯
到全部翻完,即使仍舊看不太懂,但有中文可看真是太棒了!!
==============================================================================
【開發日誌】CarbonIO與BlueNet:下一代的網絡技術
作者:CCP Curt 譯者:CCP Lion
大多數熟悉EVE的人都知道,它是用Python語言編寫的,如果要說得更具體點,那就是
Stackless Python。Stackless是在Python基礎上編寫的一套微線程框架,它能在不產生
大量Python自身額外開銷的情況下同時容納數百萬條的線程。但話還是要說回來,它畢竟
還是Python,因此擺脫不了“解釋器全局鎖”(Global Interpreter Lock,下文將其簡
稱為GIL)。
大量Python自身額外開銷的情況下同時容納數百萬條的線程。但話還是要說回來,它畢竟
還是Python,因此擺脫不了“解釋器全局鎖”(Global Interpreter Lock,下文將其簡
稱為GIL)。
GIL是一個序列鎖,用來保證在任何時候都只能有一個線程利用Python解釋器(包括其
所有數據)來運行自己。因此,儘管Stackless Python感覺上好像具備多線程處理能力,
但實際上它還是單線程的,只不過運用了任務分離、頻道、定時器及共享內存等一系列招
數而已。 其實過去有些協作式的多任務操作系統也是這樣幹的,其好處是保證了所有線
程都能被執行,不會出現被操作系統提前結束這一情況(除非被操作系統懷疑非法宕機)
。 GIL的存在使得程序員在編寫遊戲邏輯時能自信推斷出程序的全局狀態,省去了一大
堆採用異步回調函數的麻煩。
所有數據)來運行自己。因此,儘管Stackless Python感覺上好像具備多線程處理能力,
但實際上它還是單線程的,只不過運用了任務分離、頻道、定時器及共享內存等一系列招
數而已。 其實過去有些協作式的多任務操作系統也是這樣幹的,其好處是保證了所有線
程都能被執行,不會出現被操作系統提前結束這一情況(除非被操作系統懷疑非法宕機)
。 GIL的存在使得程序員在編寫遊戲邏輯時能自信推斷出程序的全局狀態,省去了一大
堆採用異步回調函數的麻煩。
但這樣有一大缺點:由於EVE中有部分框架的代碼是用Python編寫的,因此它們都免不了
GIL造成的負面影響。 比如,一段用來讀取Python數據的C++語言代碼必須在獲得GIL後才
能讀取一個字符串。
GIL造成的負面影響。 比如,一段用來讀取Python數據的C++語言代碼必須在獲得GIL後才
能讀取一個字符串。
圖片短網址:http://tinyurl.com/77s5fcc
_a01.jpg
使用Python的任務都要獲得GIL才能合法地被處理,這樣等同於Python任務都是
單線程執行。 (這圖畫得不太好看,人家只是個程序員,不是美術師哦)
一言以蔽之,Stackless Python 代碼的運行速度不會高於你最快的那個CPU核心的速度。
在一台4核或8核CPU的服務器上,其中只有一核在超負荷運作,其他都沒派上用場。當然
,為了讓這些CPU核心物盡其用,我們可以在它們身上加載更多的節點。對於EVE中許多無
狀態或對共享狀態依賴度極低的代碼而言,這沒什麼問題。但對於像太空模擬或空間站行
走這樣高度依賴共享狀態的代碼而言,就成了一個大問題。
在一台4核或8核CPU的服務器上,其中只有一核在超負荷運作,其他都沒派上用場。當然
,為了讓這些CPU核心物盡其用,我們可以在它們身上加載更多的節點。對於EVE中許多無
狀態或對共享狀態依賴度極低的代碼而言,這沒什麼問題。但對於像太空模擬或空間站行
走這樣高度依賴共享狀態的代碼而言,就成了一個大問題。
假設一個CPU核心就能處理所有的邏輯並且寫出來的Python代碼較為清晰,那我之前說的
都不是什麼問題。不過,想必我不用說大家也知道,儘管Gridlock等小組已經在優化工作
方面做到了其極致,但我們現在面臨的情況依舊是單個CPU已經無法處理一場大型會戰了
。最近上市的CPU速度是更快、緩存容量也更大、總線也更寬裕並且具備更好的執行流水
線,但在EVE需要其給力的地方,卻沒有任何進步。近期(也可能包括中長期)的趨勢是
“橫向增長”,即同時運行多個CPU核心。
都不是什麼問題。不過,想必我不用說大家也知道,儘管Gridlock等小組已經在優化工作
方面做到了其極致,但我們現在面臨的情況依舊是單個CPU已經無法處理一場大型會戰了
。最近上市的CPU速度是更快、緩存容量也更大、總線也更寬裕並且具備更好的執行流水
線,但在EVE需要其給力的地方,卻沒有任何進步。近期(也可能包括中長期)的趨勢是
“橫向增長”,即同時運行多個CPU核心。
總體而言,多核CPU的流行對EVE的長遠發展是一大利好。 未來那些30乃至60核CPU的機器
能夠很好地體現EVE集群部署方式的優勢,這是因為CPU核心之間切換的效率將遠遠大於線
程之間切換的效率。但就目前而言,為了提升遊戲運行速度,我們需要把網絡及通用讀寫
這樣的EVE模塊從GIL中解放出來。
能夠很好地體現EVE集群部署方式的優勢,這是因為CPU核心之間切換的效率將遠遠大於線
程之間切換的效率。但就目前而言,為了提升遊戲運行速度,我們需要把網絡及通用讀寫
這樣的EVE模塊從GIL中解放出來。
多核心、超標量的硬件對當今的網絡遊戲來說,都是個好消息。這些遊戲很適合這種架構
,並且能很容易地進行並行處理。可惜對於依賴Python的EVE來說,這就算不得好消息了
。那些對運行速度要求極高、不需要Python便利開發優勢的EVE系統需要儘早擺脫GIL的束
縛。CarbonIO在這個方向上可以說是向前邁進了一大步。
,並且能很容易地進行並行處理。可惜對於依賴Python的EVE來說,這就算不得好消息了
。那些對運行速度要求極高、不需要Python便利開發優勢的EVE系統需要儘早擺脫GIL的束
縛。CarbonIO在這個方向上可以說是向前邁進了一大步。
CarbonIO 是在StacklessIO 基礎上的一個自然提升。它實際上是個從頭寫起的全新引
擎,目標非常明確:讓網絡流量擺脫GIL的束縛,並且讓任何C++代碼也能這樣做。後半個
目的是重頭戲,我們花了大半年才把它完成。
擎,目標非常明確:讓網絡流量擺脫GIL的束縛,並且讓任何C++代碼也能這樣做。後半個
目的是重頭戲,我們花了大半年才把它完成。
這裡不得不先稍微提一下StacklessIO。對Stackless Python的網絡通信而言,它可以說
是個質的飛躍。通過讓網絡操作變得具有“無堆棧的意識”,StacklessIO可以將一個被
鎖住的操作轉移到一個未被GIL鎖住的線程上,這樣該操作就可以繼續等候,而Stackless
則繼續處理其他事務。然後,該操作重新獲得GIL,告訴Stackless其操作已完成。這樣,
接收端就可以同步進行,使得通訊速度可以達到操作系統級別,並且能基本上在第一時間
內回報給Python。
是個質的飛躍。通過讓網絡操作變得具有“無堆棧的意識”,StacklessIO可以將一個被
鎖住的操作轉移到一個未被GIL鎖住的線程上,這樣該操作就可以繼續等候,而Stackless
則繼續處理其他事務。然後,該操作重新獲得GIL,告訴Stackless其操作已完成。這樣,
接收端就可以同步進行,使得通訊速度可以達到操作系統級別,並且能基本上在第一時間
內回報給Python。
圖片短網址:http://tinyurl.com/8xy2lj3
_a02.jpg
StacklessIO在沒有GIL的情況下完成Python請求
CarbonIO在此基礎上更上一層樓。由於它是在完全脫離於GIL的情況下運行多線程通信
引擎,因此Python與該系統之間的交互便是完全獨立了。沒有Python的要求,它也能收發
數據。
引擎,因此Python與該系統之間的交互便是完全獨立了。沒有Python的要求,它也能收發
數據。
請允許我再強調一下:CarbonIO能在Python不作任何要求的情況下收發數據。這是並發性
的,不需要GIL。
的,不需要GIL。
當一個連接通過CarbonIO被建立後,系統會調用WSARecv()開始接收數據。與Python進程
並行的線程池將這些數據解密、解壓縮然後轉義到數據包裡。這些數據包會排隊,等著
Python來處理。
並行的線程池將這些數據解密、解壓縮然後轉義到數據包裡。這些數據包會排隊,等著
Python來處理。
當Python覺得它需要一個數據包時,它會往下調用“可能已將此包準備就緒”的CarbonIO
。這意味著數據在離開隊列被返回整個過程中根本沒有用到GIL。這是一個瞬時過程,至
少也有納秒那麼快。這個並行讀取能力是CarbonIO的第一大好處。
。這意味著數據在離開隊列被返回整個過程中根本沒有用到GIL。這是一個瞬時過程,至
少也有納秒那麼快。這個並行讀取能力是CarbonIO的第一大好處。
第二大好處便是發送了。數據以其原始形式排在工作線程隊列裡,然後便等著Python來調
用了。 其間的壓縮、加密、打包及WSASend()調用都沒有觸及GIL而發生在另一個線程裡
,這樣操作系統便可以安排它運行在另一顆CPU上了。C++代碼也可以調用一個方法來這樣
做,並不需要特別的架構變更。StacklessIO也可以那樣做,但在脫離上述背景的情況下
,這會變得很沒意義。
用了。 其間的壓縮、加密、打包及WSASend()調用都沒有觸及GIL而發生在另一個線程裡
,這樣操作系統便可以安排它運行在另一顆CPU上了。C++代碼也可以調用一個方法來這樣
做,並不需要特別的架構變更。StacklessIO也可以那樣做,但在脫離上述背景的情況下
,這會變得很沒意義。
讓我們再來回顧一下之前提到的“已將此包準備就緒”。但如果我們要安置一個C++回調
鉤子函數,使得非Python模塊能在不觸及Machonet的情況下獲得那個數據,這可行嗎?
行啊,這時我們要用的就是BlueNet了。
鉤子函數,使得非Python模塊能在不觸及Machonet的情況下獲得那個數據,這可行嗎?
行啊,這時我們要用的就是BlueNet了。
CarbonIO不停地進行數據接收,並且能在無Python介入的情況下告訴C++模塊數據已收
到。
到。
Machonet是一個大型功能集合,它負責對會話進行分流、導向及管理,負責對數據包的
時間計劃/發送以及其他一系列將EVE撮合成一個有機整體的功能。由於它是個Python模塊
,因此所有的數據遲早都必須觸及那倒霉的GIL,無論數據在哪個節點。無論一個C++模塊
的速度有多快,GIL仍然是個繞不過的瓶頸。這使得我們曾經都不太願意做大量的C++優化
,因為任何優化後取得的優勢都會被Machonet 中的GIL吞噬。
時間計劃/發送以及其他一系列將EVE撮合成一個有機整體的功能。由於它是個Python模塊
,因此所有的數據遲早都必須觸及那倒霉的GIL,無論數據在哪個節點。無論一個C++模塊
的速度有多快,GIL仍然是個繞不過的瓶頸。這使得我們曾經都不太願意做大量的C++優化
,因為任何優化後取得的優勢都會被Machonet 中的GIL吞噬。
但現在情況不一樣了。
現在C++的系統能通過BlueNet收發數據包,無需再理會GIL。這原來是專門為了空間站行
走設計的。空間站行走功能需要發送大量的表示移動的數據。EVE中太空飛行的那部分功
能所需要收發的數據,我們以前可以用旁門左道的方法來解決,但對於如此近距離的人物
動作,就不行了。 之前我們做的預測顯示,即使把空間站行走發送數據的頻率控制在一
般程度,該功能也會把整個服務器集群拖垮。通過在沒有GIL干擾的情況下對流入/流出
走設計的。空間站行走功能需要發送大量的表示移動的數據。EVE中太空飛行的那部分功
能所需要收發的數據,我們以前可以用旁門左道的方法來解決,但對於如此近距離的人物
動作,就不行了。 之前我們做的預測顯示,即使把空間站行走發送數據的頻率控制在一
般程度,該功能也會把整個服務器集群拖垮。通過在沒有GIL干擾的情況下對流入/流出
C++原生系統(比如物理系統)的數據進行分流,BlueNet成功地解決了該問題。由於在這
種情況下,數據還是保持著其原生態,因此整個系統運行的速度就比之前提高了。
這個具體是怎麼運作的呢? BlueNet保存著一份所有必要Machonet結構的只讀拷貝,另外
,所有的數據包前都會附上很小的一段((8到10個字節)數據頭。這個數據頭里含有路徑
信息。當BlueNet接到一個數據包時,它會對其進行檢測,然後合理地再分發:要么轉發到
另一個節點上,要么交給被本地的已註冊的C++應用程序。如果它轉發,那這個過程中將用
不到GIL,根本不會調用Machonet/Python。這意味著我們的代理服務器完全能以並行方式
對BlueNet的數據包進行分流,而不必去經過Python導致額外開銷的產生。那這效率究竟提
高了多少呢? 我們還無法確定,但在降低機器負載及延遲方面,它還是非常非常明顯的。
實際上我們還不能將數據公開,因為它們好得難以置信。
,所有的數據包前都會附上很小的一段((8到10個字節)數據頭。這個數據頭里含有路徑
信息。當BlueNet接到一個數據包時,它會對其進行檢測,然後合理地再分發:要么轉發到
另一個節點上,要么交給被本地的已註冊的C++應用程序。如果它轉發,那這個過程中將用
不到GIL,根本不會調用Machonet/Python。這意味著我們的代理服務器完全能以並行方式
對BlueNet的數據包進行分流,而不必去經過Python導致額外開銷的產生。那這效率究竟提
高了多少呢? 我們還無法確定,但在降低機器負載及延遲方面,它還是非常非常明顯的。
實際上我們還不能將數據公開,因為它們好得難以置信。
除此之外,CarbonIO也包含了大量底層優化,絕大多數都是小規模的速度提升,但把這些
統統疊加起來,整個系統的運行速度也就有了顯著提高。以下幾點值得一提:
統統疊加起來,整個系統的運行速度也就有了顯著提高。以下幾點值得一提:
工作分組
雖然我很難在本文中把這事兒說得太細,但CarbonIO非常出色地將工作分組來處理。簡而
言之,就是某些操作有了一個固定的開銷。網絡引擎有許多這樣的開銷,但其他所有具有
重要意義的代碼也有大量開銷。通過一些別出心裁的技巧,我們是可以將許多這樣的工作
合併在一起,這樣就只產生一次開銷。就像把邏輯數據包都組合在一起發送在一個
言之,就是某些操作有了一個固定的開銷。網絡引擎有許多這樣的開銷,但其他所有具有
重要意義的代碼也有大量開銷。通過一些別出心裁的技巧,我們是可以將許多這樣的工作
合併在一起,這樣就只產生一次開銷。就像把邏輯數據包都組合在一起發送在一個
TCP/IP MTU裡一樣(EVE一直就是這樣幹的),CarbonIO將這一做法進一步深化。一個比
較簡單的例子就是GIL獲取集合。
較簡單的例子就是GIL獲取集合。
第一個要嘗試取得GIL的線程會先建立起一個隊列,這樣其他要獲取GIL的線程只需將自己
的喚醒調用排在隊列末尾然後返迴線程池就行。那GIL最後被取得時,第一個線程會吸乾
整個隊列,不必在每次IO喚醒時釋放/重拾GIL。在一個繁忙的服務器上這種情況很多,因
此這種改進對我們來說是一大利好。
的喚醒調用排在隊列末尾然後返迴線程池就行。那GIL最後被取得時,第一個線程會吸乾
整個隊列,不必在每次IO喚醒時釋放/重拾GIL。在一個繁忙的服務器上這種情況很多,因
此這種改進對我們來說是一大利好。
openSSL整合
CarbonIO用openSSL來實現SSL,並且能在不鎖定GIL的情況下與該協議數據通信。該庫
只是用作一個BIO對而已,所有的數據導航還是由CarbonIO通過完成端口進行的。這有助
於我們循序漸進地讓EVE變得更安全,甚至將來可以把官方網站上的某些帳號管理功能挪
到EVE客戶端上去,這樣可以更方便大家。
只是用作一個BIO對而已,所有的數據導航還是由CarbonIO通過完成端口進行的。這有助
於我們循序漸進地讓EVE變得更安全,甚至將來可以把官方網站上的某些帳號管理功能挪
到EVE客戶端上去,這樣可以更方便大家。
壓縮整合
CarbonIO能利用zlib或snappy對每一個數據包都進行壓縮/解壓縮,這一過程同樣是無
需GIL的。
實戰檢驗
通過對一個繁忙的代理服務器(人數峰值大約1600人,一個平常工作日)的24小時數據的
收集,我們發現CPU的總體使用率與單個用戶的CPU使用率都出現了大幅下降。這都歸功於
CarbonIO的總體架構,其作用就是降低事務的開銷。當服務器變得繁忙之後,這些優化的
效果會被逐漸增多且必須處理的事務所抵消,但在最高負載時,CarbonIO還是讓我們的遊
戲增速了不少。
收集,我們發現CPU的總體使用率與單個用戶的CPU使用率都出現了大幅下降。這都歸功於
CarbonIO的總體架構,其作用就是降低事務的開銷。當服務器變得繁忙之後,這些優化的
效果會被逐漸增多且必須處理的事務所抵消,但在最高負載時,CarbonIO還是讓我們的遊
戲增速了不少。
圖片短網址:http://tinyurl.com/775fsg8
_a04.jpg
圖片短網址:http://tinyurl.com/8x7q7eo
_a05.jpg
以上為24小時內單個用戶的CPU使用率
圖片短網址:http://tinyurl.com/7cd22zw
_a06.jpg
以上為同樣的24小時內總體CPU使用率
至於SOL(星系)節點,由於它們的主要職責是遊戲機製而非網絡管理,因此它們從該優
化中獲得的優勢並不那麼明顯,但我們還是看到它們的CPU使用率下降了8%-10%。
化中獲得的優勢並不那麼明顯,但我們還是看到它們的CPU使用率下降了8%-10%。
需要指出的是,在上述的檢驗中我們沒有運用BlueNet,沒有用CarbonIO的數據導航,也
沒有用離GIL的數據壓縮/解壓縮。
沒有用離GIL的數據壓縮/解壓縮。
總結
總的來說,比起以前,EVE能更好地利用現代服務器硬件帶來的優勢,能讓它在同樣的時
間內完成更多的工作,這樣就間接提升了一個系統所能進行的操作上限。通過將我們的代
碼盡量與GIL脫離,我們反而為那些真正需要用它的代碼騰出了空間。另外,由於不再有
那麼多代碼需要競相獲取GIL,系統的總體運行效率也會提升。有了BlueNet再加上很好的
代碼優化,提速空間已被打開。雖然最後的結果仍有待實踐檢驗,但至少,我們已經消除
了一大瓶頸。
間內完成更多的工作,這樣就間接提升了一個系統所能進行的操作上限。通過將我們的代
碼盡量與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
→ :有沒有高手可以解釋下 太專業看不懂1F 05/15 15:09
推 :不是高手 快速掃一遍的topic 1.把worker拆開來多執行緒2F 05/15 15:11
→ :對不起我END了,可以簡單說明前後差異嗎?3F 05/15 15:11
→ :2是不要讓global lock鎖住不管interpreter的鳥事4F 05/15 15:13
→ :因為看起來似乎C/C++對python的介面是有個lock的
→ :結果就是很多根本不用lock的事情還得去排隊等
→ :新的引擎把io的排程從這lock解放了
→ :所以可以有效的把io攤平並善用proxy
→ :以及可以善用多cpu的環境可以開多thread的好處
→ :因為看起來似乎C/C++對python的介面是有個lock的
→ :結果就是很多根本不用lock的事情還得去排隊等
→ :新的引擎把io的排程從這lock解放了
→ :所以可以有效的把io攤平並善用proxy
→ :以及可以善用多cpu的環境可以開多thread的好處
→ :更高效率的使用多核心處理器的意思?10F 05/15 15:15
→ :還有package的改良 看起來像是參考SIMD的搞法11F 05/15 15:16
→ :同時地傳送多筆資料並且能正確的route到指定的node
→ :喔 果然是個pool,他弄了一個queue去管理有限的lock
→ :同時地傳送多筆資料並且能正確的route到指定的node
→ :喔 果然是個pool,他弄了一個queue去管理有限的lock
→ :海嘯你要回這麼細的話可以麻煩回文嗎?14F 05/15 15:17
→ :重點是讓scale變得更容易更大15F 05/15 15:17
→ :我相信回一篇文會造福很多版眾16F 05/15 15:17
→ :可是..回了完全沒有acg點啊17F 05/15 15:18
→ :EVE Online使用的技術...不知道這沒有ACG點...orz18F 05/15 15:18
→ :我不認為這篇技術文章的ACG點會多到哪去XD19F 05/15 15:18
→ :我覺得很多是有做過大規模service的人都會遇到的啦...20F 05/15 15:19
→ :就好像最近流行的 有人把node.js做了個web server
→ :號稱超有效率,(但是v8 一堆安全性的洞)
→ :就好像最近流行的 有人把node.js做了個web server
→ :號稱超有效率,(但是v8 一堆安全性的洞)
推 :Micro-Threading...23F 05/15 15:25
推 :yap24F 05/15 15:26
→ :但實務上不會搞到那麼誇張 就是讓資料能不被lock最好
→ :但實務上不會搞到那麼誇張 就是讓資料能不被lock最好
→ :這招好像Ruby也有人在玩 好像就是Actor model?26F 05/15 15:26
→ :例如這個就是說 不用過python的就別過了27F 05/15 15:27
→ :Design pattern比較像worker?
→ :Design pattern比較像worker?
→ :其實就是很像Erlang不是嗎XD29F 05/15 15:28
→ :沒玩過erlang耶.有甚麼特色嗎?30F 05/15 15:29
推 :我再看一次文章好了...Erlang就是一種Actor model的實作31F 05/15 15:47
→ :沒研究過 應該去稍微survey一下32F 05/15 15:48
→ :Stackless python的Wiki頁面 See also有Erlang連結33F 05/15 15:58
→ :確實跟Actor Model有點關係
→ :確實跟Actor Model有點關係
推 :稍微看了一下 大概知道是在說甚麼東西了...35F 05/15 17:22
--
※ 看板: ACG 文章推薦值: 0 目前人氣: 0 累積人氣: 314
回列表(←)
分享