Go語言項目(kingshard)效能最佳化執行個體剖析

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

kingshard效能最佳化網路篇

最近kingshard的功能開發節奏慢了許多。一方面是工作確實比較忙,另一方面是我覺得kingshard的功能已經比較完善了,下一步的開發重點應該是效能最佳化。畢竟作為一個MySQL proxy,如果轉寄SQL的效能很差,再多的功能都無濟於事。所以這個周末一直宅在家裡最佳化kingshard的轉寄效能。經過兩天的探索發現,將kingshard的轉寄SQL效能提升了18%左右,在這個過程中學到了一下知識。藉此機會分享一下,同時也是督促一下自己寫部落格的積極性。:)

1. 發現kingshard的效能瓶頸

首選,對kingshard進行效能最佳化,我們必須要找到kingshard的效能瓶頸在哪裡。Go語言在效能最佳化支援方面做的非常好,藉助於go語言的pprof工具,我們可以通過簡單的幾個步驟,就能得到kingshard在轉寄SQL請求時的各個函數耗時情況。

1.1 環境搭建

根據kingshard使用指南搭建一個kingshard代理環境。我是用macbook搭建的環境,硬體參數如下所示:

CPU: 2.2GHZ * 4記憶體:16GB硬碟: 256GB

1.2 效能測試步驟

具體步驟如下所述:

1.擷取一個效能分析的封裝庫

go get github.com/davecheney/profile

2.在工程內import這個組件

3.在kingshard/cmd/kingshard/main.go的main函數開始部分添加CPU監控的啟動和停止入口

func main() {    defer profile.Start(profile.CPUProfile).Stop()    fmt.Print(banner)    runtime.GOMAXPROCS(runtime.NumCPU())    flag.Parse()    ....}

4.重新編譯工程, 運行kingshard

./bin/kingshard -config=etc/ks.yaml

5.kingshard啟動後會在終端輸出下面一段提示:

2015/10/31 10:28:06 profile: cpu profiling enabled, /var/folders/4q/zzb55sfj377b6vdyz2brt6sc0000gn/T/profile205276958/cpu.pprof

後面的路徑就是pprof效能分析檔案的位置,Ctrl+C中斷伺服器

6.這時候用sysbench對kingshard進行壓力測試,得到QPS(有關sysbench的安裝和使用,請自行Google解決)。具體的代碼如下所示:

sysbench --test=oltp --num-threads=16 --max-requests=160000 --oltp-test-mode=nontrx --db-driver=mysql --mysql-db=kingshard --mysql-host=127.0.0.1 --mysql-port=9696 --mysql-table-engine=innodb --oltp-table-size=10000 --mysql-user=kingshard --mysql-password=kingshard --oltp-nontrx-mode=select --db-ps-mode=disable run

得到如下結果:

OLTP test statistics:    queries performed:        read:                            160071        write:                           0        other:                           0        total:                           160071    transactions:                        160071 (16552.58 per sec.)    deadlocks:                           0      (0.00 per sec.)    read/write requests:                 160071 (16552.58 per sec.)    other operations:                    0      (0.00 per sec.)Test execution summary:    total time:                          9.6705s    total number of events:              160071    total time taken by event execution: 154.4474    per-request statistics:         min:                                  0.29ms         avg:                                  0.96ms         max:                                 14.17ms         approx.  95 percentile:               1.37msThreads fairness:    events (avg/stddev):           10004.4375/24.95    execution time (avg/stddev):   9.6530/0.00
  • 按照上述步驟測試三次(16552.58,16769.72,16550.16)取平均值,得到最佳化前kingshard的QPS是:16624.15

  • 按照上述步驟,直連MySQL。測試直連MySQL的QPS,同樣測試三次QPS(27730.90,28499.05,27119.20),得到直連MySQL的QPS是:27783.05。

  • 從上述資料可以計算出kingshard轉寄SQL的效能是直連MySQL的59%左右。

7.將cpu.prof拷貝到bin/kingshard所在位置

8.調用go tool工具製作CPU耗時的PDF文檔

go tool pprof -pdf ./kingshard cpu.pprof > report.pdf

2. 效能測試報告分析

通過上述命令,可以產生壓測期間主要函數耗時情況。從report來看,主要的耗時在TCP層資料包的收發上面。那我們應該主要考慮如何最佳化TCP層資料的收發方面。最佳化TCP傳輸效率,我首先想到了減少系統調用,每個資料包傳輸盡量多的資料。

在通過 TCP socket 進行通訊時,資料都拆分成了資料區塊,這樣它們就可以封裝到給定串連的 TCP payload(指 TCP 資料包中的有效負荷)中了。TCP payload 的大小取決於幾個因素(例如最大報文長度和路徑),但是這些因素在串連發起時都是已知的。為了達到最好的效能,我們的目標是使用儘可能多的可用資料來填充每個報文。當沒有足夠的資料來填充 payload 時(也稱為最大報文段長度(maximum segment size) 或 MSS),TCP 就會採用 Nagle 演算法自動將一些小的緩衝區串連到一個報文段中。這樣可以通過最小化所發送的報文的數量來提高應用程式的效率,並減輕整體的網路擁塞問題。

由於這種演算法對資料進行合并,試圖構成一個完整的 TCP 報文段,因此它會引入一些延時。但是這種演算法可以最小化線上路上發送的報文的數量,因此可以最小化網路擁塞的問題。但是在需要最小化傳輸延時的情況中,GO語言中Sockets API 可以提供一種解決方案。就是通過:

func (c *TCPConn) SetNoDelay(noDelay bool) error

這個函數在Go中預設情況下,是設定為true,也就是未開啟延遲選項。我們需要將其設定為false選項,來達到每個資料包傳輸盡量多的資料,減少系統調用的目的。

2.1 代碼修改和效能測試

發現了效能瓶頸以後,修改proxy/server/server.go檔案中的newClientConn函數和backend/backend_conn.go中的ReConnect函數,分別設定client與kingshard之間的串連和kingshard到MySQL之間的串連為最小化傳輸延時。具體的代碼修改可以查看這個commit。

修改後我們利用sysbench重新測試,測試命令和上述測試一致。得到的結果如下所示:

OLTP test statistics:    queries performed:        read:                            160174        write:                           0        other:                           0        total:                           160174    transactions:                        160174 (21291.68 per sec.)    deadlocks:                           0      (0.00 per sec.)    read/write requests:                 160174 (21291.68 per sec.)    other operations:                    0      (0.00 per sec.)Test execution summary:    total time:                          7.5228s    total number of events:              160174    total time taken by event execution: 119.9655    per-request statistics:         min:                                  0.26ms         avg:                                  0.75ms         max:                                 10.78ms         approx.  95 percentile:               1.13msThreads fairness:    events (avg/stddev):           10010.8750/38.65    execution time (avg/stddev):   7.4978/0.00

測試三次得到的QPS為:21291.68,21670.85,21463.44。 相當於直連MySQL效能的77%左右,通過這個最佳化效能提升了18%左右

總結

通過這篇文章,介紹了通過Go語言提供的pprof對kingshard進行效能分析的詳細步驟。對於其他Go語言項目也可以通過類似步驟產生效能報告文檔。效能最佳化的關鍵是發現效能瓶頸,再去找最佳化方案。有時候簡單的最佳化,就可以達到預想不到的效果,希望本文能給Go開發人員在效能最佳化方面提供一個思路。最後打個廣告:kingshard作為一個支援sharding的開源MySQL中介軟體項目,目前已經比較穩定了,且經過效能最佳化後,轉寄SQL的效能提升了不少。後續我還會在鎖和記憶體方面對kingshard進行最佳化,敬請期待。

github: https://github.com/flike/kingshard

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.