技術分享 | MySQL: 壓測結果很差怎麼辦

作者:胡呈清

愛可生 DBA 團隊成員,擅長故障分析、性能優化,個人博客:https://www.jianshu.com/u/a95ec11f67a8,歡迎討論。

本文來源:原創投稿

*愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。


老闆讓你做一個 MySQL 的性能基準測試,測來測去發現明明機器配置很高,但 tps 就是上不去,爲什麼?
首先我們很容易想到的就是 InnoDB 緩衝池設置的不夠大、 redo log 太小、數據沒有充分預熱、 sysbench 線程數開的太少... 這些是很常見的原因,今天我們來看一些不那麼顯而易見的情況。
以下案例的硬件配置爲:64core、256Gmemory、raid 10 15K 機械盤。

網絡瓶頸

一次壓測結果是這樣的:

sysbench oltp_read_write --mysql-host=10.18x.xx.104 --mysql-port=3308  \
--mysql-user=sysbench --mysql-password=sysbench --mysql-db=sbtest --tables=10 \
--table-size=10000000 --report-interval=5 --threads=200 --time=600 run

##結果:
SQL statistics:
queries performed:
read: 4682958
write: 1337988
other: 668994
total: 6689940
transactions: 334497 (2783.82 per sec.)
queries: 6689940 (55676.32 per sec.)
ignored errors: 0 (0.00 per sec.)
reconnects: 0 (0.00 per sec.)
結果 tps 只有 2800,顯然對不起這麼高的硬件,這時候就得觀察負載了,一般最明顯的一點就是 CPU 使用率低,比如這個案例在我的環境上 CPU 使用率只有36%,而網卡流量很高達到 124MB/s ,差不多就是千兆網卡的極限了(1000Mb/s / 8):
這時候就得意識到“我是不是用錯網卡了”?爲啥這麼說呢,因爲一般都會配兩塊網卡分別訪問內外網,快速查看網絡接口: ifconfig -a|grep -B 1 inet 。立馬就看到確實是雙網卡,我們壓測用的是em3,還有另外一個網絡接口 vlan2 :

然後再確認下帶寬:ethtool {dev_name} |grep Speed。em3 是千兆帶寬,壓測時 124MB/s 的流量已經打滿了:

所以在sysbench壓測時換成 vlan2 萬兆網絡接口後(即修改 --mysql-host=10.0.xx.104),輕鬆到1萬。如果實在沒有萬兆網卡怎麼辦?那就在本地使用迴環接口進行測試吧。下圖是使用3個網口測試的網絡流量圖,明顯可以看出千兆網口的網絡瓶頸:

SSL

MySQL8.0 或者 MySQL5.7 企業版壓測時會遇到一個坑:默認開啓 SSL,壓測結果 tps 只有3700:

sysbench oltp_read_write --mysql-host=10.18x.xx.104 --mysql-port=3308  \
--mysql-user=sysbench --mysql-password=sysbench --mysql-db=sbtest --tables=10 \
--table-size=10000000 --report-interval=5 --threads=200 --time=600 run

##結果:
SQL statistics:
    queries performed:
        read:                            6303388
        write:                           1800968
        other:                           900484
        total:                           9004840
    transactions:                        450242 (3747.71 per sec.)
    queries:                             9004840 (74954.25 per sec.)
Latency (ms):
         min:                                    6.35
         avg:                                   53.31
         max:                                  542.71
         95th percentile:                      104.84
         sum:                             24004566.42
         

和前面說的一樣,觀察系統負載,發現 CPU 使用率已經用到了 80% ,但是 CPU system 時間反常的高,再去看壓測結果 95% 的響應時間也很高需要 100 多毫秒,正是因爲需要消耗大量的系統資源進行加密連接:

解決辦法就是配置文件寫入 skip-ssl 重啓 MySQL。其實 sysbench 有個參數 --mysql-ssl[=on|off],看說明只要設置爲 off 就可以關閉 ssl 連接,但實測並沒有用,通過 select * from status_by_thread where VARIABLE_NAME like '%ssl%';查看連接還是開啓 ssl 的,對 ssl 機制比較懵逼,歡迎有了解的大佬留言。

sort_buffer_size

sort_buffer_size 會影響 sysbench 性能嗎?官方文檔有這樣的描述:

On Linux, there are thresholds of 256KB and 2MB where larger values may significantly slow down memory allocation, so you should consider staying below one of those values.

也許你會覺得問題不大,但實際看下面這組測試結果:11000 tps VS 930 tps

## sort_buffer_size=31M
SQL statistics:

queries performed:
read: 16358846
write: 4673956
other: 2336978
total: 23369780
transactions: 1168489 (11678.75 per sec.)
queries: 23369780 (233574.94 per sec.)

## sort_buffer_size=32M
SQL statistics:
queries performed:
read: 392182
write: 112052
other: 56026
total: 560260
transactions: 28013 (930.07 per sec.)
queries: 560260 (18601.38 per sec.)

事實就是這麼不可思議,當 sort_buffer_size 達到閾值32M後(我測試的閾值和文檔給出的閾值256K、2M不一樣),內存分配方式發生改變,內存分配效率變低, CPU system 時間劇增:

細說一下內存分配方式變化爲什麼會引起這個結果,參考:【技術分享 | MySQL 內存管理初探】

malloc() 是 C 標準庫提供的內存分配函數,對應到系統調用上,有兩種實現方式,即 brk() 和 mmap()。

  1. brk 方式 對於小塊內存(<128K),C 標準庫使用 brk() 來分配。也就是通過移動堆頂的位置來分配內存。這些內存釋放後並不會立刻歸還系統,而是被緩存起來,重複使用。

    優缺點:brk() 方式可以減少缺頁異常的發生,提高內存訪問效率。不過,由於這些內存沒有歸還系統,所以在內存工作繁忙時,頻繁的內存分配和釋放會造成內存碎片。

  2. mmap 匿名映射方式 對於大塊內存(>128K),C 標準庫使用 mmap() 來分配,也就是在文件映射段找一塊空閒內存分配出去。mmap() 方式分配的內存,會在釋放時直接歸還系統,所以每次 mmap 都會發生缺頁異常。

    優缺點:mmap() 方式可以將內存及時返回給系統,避免 OOM。但是工作繁忙時,頻繁的內存分配會導致大量的缺頁異常,使內核的管理負擔增大。這也是 malloc 只對大塊內存使用 mmap 的原因。

    謂的缺頁異常是指進程申請內存後,只分配了虛擬內存。 這些所申請的虛擬內存,只有在首次訪問時纔會分配真正的物理內存,也就是通過缺頁異常進入內核中,再由內核來分配物理內存(本質就是建立虛擬內存與物理內存的地址映射)。
brk() 方式申請的堆內存由於釋放內存後並不會歸還給系統,所以下次申請內存時,並不需要發生缺頁異常。
mmap() 方式申請的動態內存會在釋放內存後直接歸還系統,所以下次申請內存時,會發生缺頁異常(增加內核態 CPU 開銷)。

總結

當壓 測結果不樂觀,第一時間去看 CPU 使用率,只要總使用率低,或者 iowait、system 高,都是異常情況,需要去排查原因。my.cnf 規範模板可以解決大部分的壓測結果異常的問題,另一方面則需要我們掌握基本的分析方法,再配合一些過往經驗,就能測出理想的數據了。


文章推薦:

技術分享 | Zabbix 監控 TiDB (二)

技術分享 | Zabbix 監控 TiDB (一)

技術分享 | show engine innodb status 中 Pages flushed up to 的含義



社區近期動態




本文關鍵字:#壓測# ##
  點一下“閱讀原文”瞭解更多資訊

本文分享自微信公衆號 - 愛可生開源社區(ActiontechOSS)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章