分布式之高性能IO組件


因為畢業設計(實時分析大型數據流),開始對分布式並行計算做研究,第一個問題就是通訊。高性能的通訊是整個系統性能的基本保障。

方案

就目前的經驗來講,最好的通信選擇是:異步非阻塞IO + 資源池。

  • 異步非阻塞是為了避免因IO而阻塞進程(或是線程)而造成計算資源的浪費
  • 使用資源池(連接池)是為了應對高並發

方案是這樣,要說理由的話就得說一大堆,牽扯很多東西

程序運行背景

以往常規的代碼都是單線程同步的代碼,指令的執行順序和書寫時一致,當遇到IO(文件操作或是網絡操作),通常都會阻塞線程,那么OS會讓其他線程獲得CPU資源,這使得你的程序停滯了,當有其他請求進來時得不到處理,自然系統性能也就降低了。傳統的方法是用多個線程處理多個請求,就像運行php的apache服務器一樣,然而線程是昂貴的,自然也不是較好的選擇。

IO 操作是基於OS,windows系統提供倆類IO,一種是同步IO(如上面描述的一樣),一種是異步IO(其他OS也提供這樣的操作,但並不是所有的OS都支持的很好)。異步IO與同步IO的區別在於誰去真正執行IO操作。在同步IO中是由用戶進程執行IO;在異步IO中,則有OS分派另外的內核線程來執行,待數據准備好之后再將數據交由用戶進程處理,在內核線程執行IO的時候,用戶進程可以處理其他事情,並未被阻塞,這是異步IO高效的原因。

ACE && netty

ACE

ACE是Douglas Schmidt開發的一個C++網絡編程庫,實現了Reactor 和 Proactor倆種模式。其中Reactor模式以類似異步的方式編寫代碼,但IO實際上是同步的;Proactor則是利用OS的異步IO而編寫,是真正意義上的異步IO。可以看這里鏈接,有對倆種方式的簡要介紹,作者還自己寫了一個TProactor,非常有意思!因為真正意義上的IO與OS密切相關,不同OS提供的API都不一樣,跨平台是一個非常繁瑣的問題,需要你了解不同OS的差異,使用別人經過嚴格測試的框架是一個非常明智的選擇。

netty

netty是java世界的非阻塞IO庫,netty是按Reactor模式設計,使用一個單獨的線程作為event demultiplexor ,java鄙人不熟,也不清楚其線程創建的開銷是否大。不過可以確定的是在java的世界netty是最好的選擇。

Golang blocking IO && node.js non-blocking IO

關於這個,非常感謝國外一個同行做的測試鏈接,從測試結果看來node.js 的異步非阻塞IO的性能低於Golang的阻塞IO。為什么呢,主要原因有倆個:一 是語言的runtime,解釋型語言肯定比不過編譯型語言,但這不是主要因素;最主要的因素是在Golang里面雖然是以阻塞的方式編寫代碼,可實際運行的時候不同goroutine之間可以進行非常高效的切換,代價遠低於傳統的線程切換(Golang的調度器做了異步IO的操作,對使用者屏蔽了底層問題),工作原理類似協程。所以IO阻塞對於Golang編寫的程序來講不是一個問題,一個goroutine阻塞了,其他的goroutine可以繼續運行,整個系統並沒有放棄對CPU的占用。

在stackoverflow 還有一個討論鏈接,感性趣的可以看看

另外還有Erlang的解決方案(之前公司小組的leader推薦了Elixir,准備看看),per connection per process, OTP ,所以有好多選擇啊!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM