愛可生 DBA 團隊成員,擅長故障分析、性能優化,個人博客:https://www.jianshu.com/u/a95ec11f67a8,歡迎討論。
*愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。
網絡瓶頸
一次壓測結果是這樣的:
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.)
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()。
brk 方式 對於小塊內存(<128K),C 標準庫使用 brk() 來分配。也就是通過移動堆頂的位置來分配內存。這些內存釋放後並不會立刻歸還系統,而是被緩存起來,重複使用。
優缺點:brk() 方式可以減少缺頁異常的發生,提高內存訪問效率。不過,由於這些內存沒有歸還系統,所以在內存工作繁忙時,頻繁的內存分配和釋放會造成內存碎片。
mmap 匿名映射方式 對於大塊內存(>128K),C 標準庫使用 mmap() 來分配,也就是在文件映射段找一塊空閒內存分配出去。mmap() 方式分配的內存,會在釋放時直接歸還系統,所以每次 mmap 都會發生缺頁異常。
優缺點:mmap() 方式可以將內存及時返回給系統,避免 OOM。但是工作繁忙時,頻繁的內存分配會導致大量的缺頁異常,使內核的管理負擔增大。這也是 malloc 只對大塊內存使用 mmap 的原因。
所 謂的缺頁異常是指進程申請內存後,只分配了虛擬內存。 這些所申請的虛擬內存,只有在首次訪問時纔會分配真正的物理內存,也就是通過缺頁異常進入內核中,再由內核來分配物理內存(本質就是建立虛擬內存與物理內存的地址映射)。
總結
當壓 測結果不樂觀,第一時間去看 CPU 使用率,只要總使用率低,或者 iowait、system 高,都是異常情況,需要去排查原因。my.cnf 規範模板可以解決大部分的壓測結果異常的問題,另一方面則需要我們掌握基本的分析方法,再配合一些過往經驗,就能測出理想的數據了。
文章推薦:
技術分享 | show engine innodb status 中 Pages flushed up to 的含義
社區近期動態
本文分享自微信公衆號 - 愛可生開源社區(ActiontechOSS)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。