Golang號稱高並發,但高並發時效能不高

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

1.管道chan吞吐極限10,000,000,單次Put,Get耗時大約100ns/op,無論是採用單Go程,還是多Go程並發(並發數:100, 10000, 100000),耗時均沒有變化,Go核心這對chan進行最佳化。

解決之道:在系統設計時,避免使用管道chan傳遞主業務資料,避免將商務程序處理流程分割到對個Go程中執行,這樣做減少chan傳輸耗時,和Go程調度耗時,效能會有很大的提升。

案例分析:nsq和nats都是即時訊息佇列,nsq在用戶端端和服務端大量使用chan轉寄訊息,導致效能不佳,只有100,000/s;而nats服務端在分發訊息流程程中,沒有使用chan,只在用戶端接收時使用chan,效能可達到1,000,000/s。

2.互斥鎖Mutex在單Go程時Lock,Unlock耗時大約20ns/op,但是採用多Go程時,效能急劇下降,並發越大耗時越長,在Go1.5並發數達到1024耗時900ns/op,Go1.6最佳化到300ns/op,究其原因,是構建在CPU的原子操作之上,搶佔過於頻繁將導致,消耗大量CPU時鐘,進而CPU多核無法並行。

解決之道:採用分區,將需要互斥保護的資料,分成多個固定分區(建議是2的整數倍,如256),訪問時先定位分區(不互斥),這樣就可降低多個Go程競爭1個資料分區的機率。

案例分析:Golang的Go程調度模組,在管理大量的Go程,使用的就是資料分區。

3.select非同步作業在單管道時耗時120ns/op,但是隨著管道數增加,效能線性下降,每增加1個管道增加100ns/op,究其原因,slelect時當chan數超過1後,Go內部是建立一個Go程,有它每1ms輪訓的方式檢查每個chan是否可用,而不是採用事件觸發。

解決之道:在select中避免使用過多的管道chan分支,或者把無法用到的chan置為nil;解決select逾時,避免使用單獨的逾時管道,應與資料返回管道共用。

案例分析:nsq和nats都是即時訊息佇列,由於nsq大量使用chan,這就必然導致大量使用select對多chan操作,結果是效能不高。

4.Go調度效能低下,當出現1,000,000Go程時,Go的調度器的效能急劇下降。

解決之道:避免動態建立Go程,服務端收到資料並處理的流程中,避免使用chan傳遞業務資料,這樣會引起Go程調度。

案例分析:nsq和nats都是即時訊息佇列,由於nsq大量使用chan,這就必然導致在服務過程中,引起Go調度,結果是效能不高。

5.defer效能不高,每次defer耗時100ns,,在一個func內連續出現多次,效能消耗是100ns*n,累計出來浪費的cpu資源很大的。

解決之道:除了需要異常捕獲時,必須使用defer;其它資源回收類defer,可以判斷失敗後,使用goto跳轉到資源回收的代碼區。

6.記憶體管理器效能低下,申請16位元組的記憶體,單次消耗30ns,64位元組單次消耗70ns,隨著申請記憶體尺寸的增長,耗時會迅速增長。加上GC的效能在1.4, 1.5是都不高,直到1.6, 1.7才得到改善。

解決之道:建議使用pool,單次Put,Get的耗時大約在28ns,在並發情況下可達到18ns,比起每次建立,會節省很多的CPU時鐘。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.