昨天有了第一篇的測試之后,僅僅是一個開始。
創(chuàng)新互聯(lián)公司是一家專業(yè)提供濉溪企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計、成都做網(wǎng)站、H5技術(shù)、小程序制作等業(yè)務(wù)。10年已為濉溪眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。我接下來做sysbench壓測的主要思路是根據(jù)現(xiàn)有的配置作出調(diào)整,能夠持續(xù)性的優(yōu)化和壓力測試達(dá)到目的,而不是簡單的去對比連接數(shù)在不同數(shù)量級會有多大的差別,所以你會在里面看到一些問題的排查,一些問題的解決,可能有些又不是壓測相關(guān)的。
壓測連接數(shù)300跑不上去
我設(shè)置了max_connections為3000,但是壓測的時候到了300個線程就跑不上去了。這個問題很有典型性。
sysbench拋出的錯誤如下:
FATAL: mysql_stmt_prepare() failed
FATAL: MySQL error: 1461 "Can't create more than max_prepared_stmt_count statements (current value: 16382)"
FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:282: SQL API error
MySQL的錯誤日志信息如下:
2017-03-14T15:01:57.839154Z
348 [Note] Aborted connection 348 to db: 'sysbenchtest' user: 'root'
host: 'localhost' (Got an error reading communication packets)
2017-03-14T15:01:57.839185Z
346 [Note] Aborted connection 346 to db: 'sysbenchtest' user: 'root'
host: 'localhost' (Got an error reading communication packets)
看起來兩者關(guān)聯(lián)不大,所以有些信息就會有一些誤導(dǎo)了。
根據(jù)錯誤的信息,當(dāng)前的參數(shù)max_prepared_stmt_count設(shè)置值為16382,是安裝后的默認(rèn)值。
mysql> show variables like 'max_prepared_stmt_count';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| max_prepared_stmt_count | 16382 |
+-------------------------+-------+
而packet的參數(shù)設(shè)置為4M的樣子,也是默認(rèn)值
mysql> show variables like '%pack%';
+--------------------------+------------+
| Variable_name | Value |
+--------------------------+------------+
| max_allowed_packet | 4194304 |
| slave_max_allowed_packet | 1073741824 |
+--------------------------+------------+
到底是不是參數(shù)max_allowed_packet引起的呢,我們可以簡單模擬一下。
set global max_allowed_packet=33554432;
然后繼續(xù)運(yùn)行sysbench腳本:
sysbench /home/sysbench/sysbench-1.0.3/src/lua/oltp_read_write.lua --mysql-user=root --mysql-port=3306 --mysql-socket=/home/mysql/s1/s1.sock --mysql-host=localhost --mysql-db=sysbenchtest --tables=10 --table-size=5000000 --threads=200 --report-interval=5 --time=10 run
結(jié)果還是拋出了同樣的錯誤,這也就間接證明了這個問題和這個參數(shù)無關(guān),所以我恢復(fù)了原來的設(shè)置。
然后我們繼續(xù)調(diào)整這個參數(shù)max_prepared_stmt_count,把值從16382調(diào)整到30000
set global max_prepared_stmt_count=30000;
然后再次運(yùn)行200個線程,就可以看到?jīng)]問題了,運(yùn)行過程中我們可以使用show
global status的方式來查看這個值的變化,這個參數(shù)的主要含義是應(yīng)對瞬間新建的大量prepared
statements,通過max_prepared_stmt_count 變量來控制,這個值是怎么算出來的,還需要細(xì)細(xì)挖挖。
mysql> show global status like 'Prepared_stmt_count';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| Prepared_stmt_count | 18200 |
+----------------------------+----------+
執(zhí)行完200個線程后,繼續(xù)300個,打算以此類推,一直到1000個線程。
執(zhí)行300個線程的時候,抓取了一下這個參數(shù)值,發(fā)現(xiàn)已經(jīng)快溢出了。
mysql> show global status like '%stmt%';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| Prepared_stmt_count | 27300 |
+----------------------------+----------+
10 rows in set (0.00 sec)
所以自己簡單做了個計算,
200個線程參數(shù)值為 18200
300個線程參數(shù)值為 27300
通過簡單的計算可以看出100個線程對應(yīng)參數(shù)值9100,按照這個參數(shù)設(shè)置,我要運(yùn)行500個線程,30000這個參數(shù)值是肯定不夠的。很快就驗證了我的這個想法,拋出錯誤了。所以我調(diào)整了參數(shù)值為100000,在900個線程都沒有任何問題。
這是分別對應(yīng)50個,300個,500個線程時候的TPS測試結(jié)果,QPS基本是TPS的20倍。
壓測連接數(shù)1000跑不上去然后我繼續(xù)測試1000個線程的時候,發(fā)現(xiàn)跑不上去了。
壓到1000的時候,拋出了下面的錯誤。
FATAL: unable to connect to MySQL server on socket '/home/mysql/s1/s1.sock', aborting...
FATAL:
error 1135: Can't create a new thread (errno 11); if you are not out of
available memory, you can consult the manual for a possible
OS-dependent bug
這個時候查看資源的使用情況如下:
# ulimit -a
。。。
open files (-n) 1024
pipe size (512 bytes, -p) 8
max user processes (-u) 1024
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
值得一提的是在RedHat 6中,在/etc/security/limits.conf設(shè)置用戶為*的時候,完全不會生效,需要制定具體的用戶,
比如下面的配置就不會生效,需要指定為root
* soft nproc 65535
* hard nproc 65535
再次可以引申出兩點(diǎn),一個是修改了資源設(shè)置之后,已有的MySQL服務(wù)就需要重啟,因為資源設(shè)置還是舊的值,如何查看呢??梢允褂胮idof來查看/proc下的設(shè)置。
# cat /proc/`pidof mysqld`/limits | egrep "(processes|files)"
Max processes 1024 256589 processes
Max open files 15000 15000 files
第二點(diǎn)就是在RedHat 6中,我們其實(shí)需要設(shè)置另外一個參數(shù)文件,/etc/security/limits.d/90-nproc.conf
在這個文件中做如下的配置,對所有用戶生效。
* soft nproc 65535
修改后重啟MySQL服務(wù)即可生效,再次開啟測試就沒有問題了,說明這個地方的錯誤和參數(shù)nproc還是有密切的關(guān)系,但是open files目前還是1024暫時還沒有問題。
這是當(dāng)時測試的一個初步結(jié)果??梢钥吹骄€程50,500,1000的時候的TPS情況,線程1000的指標(biāo)似乎沒有什么提升。
線程達(dá)到了1000,我們的基準(zhǔn)測試也有了一個階段性的成果,那就是最起碼支持1000的連接是沒有問題了,但是測試結(jié)果還是讓人不大滿意,至少從數(shù)字上來看還是有很大的瓶頸。
問題出在哪里了呢,首先機(jī)器的配置較差,這是個不爭的事實(shí),所以你看到的結(jié)果和很多網(wǎng)上高大上的結(jié)果有較大的出入。
另外一點(diǎn)是默認(rèn)參數(shù)層面的優(yōu)化,我們使用的是Lua模板讀寫兼有。壓力測試的過程中生成了大量的binlog,而對于InnoDB而言,我們需要明確在IO上的幾點(diǎn)可能,一個是刷數(shù)據(jù)的效率,一個是redo的大小,還有一些已有的優(yōu)化方式改進(jìn)。我們來簡單說一下。
MySQL里有類似Oracle中LGWR的一個線程,在5.7中默認(rèn)是16M,早先版本是8M.因為刷新頻率很高,所以這個參數(shù)一般不需要調(diào)整。
mysql> show variables like 'innodb_log_buffer_size';
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| innodb_log_buffer_size | 16777216 |
對于redo的大小,目前是50M,還有個group的參數(shù)innodb_log_files_in_group,默認(rèn)是2,即兩組,可以理解為Oracle中的兩組redo日志。
mysql> show variables like 'innodb_log%';
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| innodb_log_buffer_size | 16777216 |
| innodb_log_checksums | ON |
| innodb_log_compressed_pages | ON |
| innodb_log_file_size | 50331648 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | ./ |
| innodb_log_write_ahead_size | 8192 |
+-----------------------------+----------+
在這個壓力測試中,頻繁的寫入binlog,勢必會對redo的刷新頻率極高。
我們抓取一個測試中的InnoDB的狀態(tài):
mysql -e "show engine innodb status\G"|grep -A12 "Log sequence"
Log sequence number 39640783274
Log flushed up to 39640782426
Pages flushed up to 39564300915
Last checkpoint at 39562272220
0 pending log flushes, 0 pending chkp writes
93807 log i/o's done, 198.50 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 26386366464
Dictionary memory allocated 555380
Buffer pool size 1572768
Free buffers 1048599
簡單來做個計算,可以看到Log sequence number的值減去Last checkpoint at的值,大概是70M左右
mysql> select 39640783274-39562272220;
+-------------------------+
| 39640783274-39562272220 |
+-------------------------+
| 78511054 |
+-------------------------+
redo文件設(shè)置為多大,其實(shí)沒有一個絕對的概念,在Percona的建議中,在壓力測試中可以設(shè)置為1G或者2G,大設(shè)置為4G,因為本身會直接影響到恢復(fù)的效率。
調(diào)整redo的大小還是尤其需要注意,在這一點(diǎn)上MySQL沒準(zhǔn)以后會有所改進(jìn),Oracle中的redo修改還是值得借鑒的。像5.7中的undo已經(jīng)可以截斷,逐步的剝離出來,都是一點(diǎn)點(diǎn)的改進(jìn)。
怎么修改redo的大小呢,要正常停庫,然后刪除默認(rèn)的兩個redo文件,保險起見,你可以先備份出來也行,然后修改參數(shù)文件的redo文件參數(shù),啟動MySQL,當(dāng)然開始的時候會識別不到redo文件會自動創(chuàng)建兩個新的。
下面的結(jié)果很有代表性,是暫時修改redo為100M時的TPS情況。左下角藍(lán)色的部分是原來10分鐘內(nèi)的TPS情況,紅色的部分是2個多小時里的TPS情況,可以看到基本是穩(wěn)定的,而且是原高于原來同樣線程數(shù)的TPS.
后續(xù)改如何優(yōu)化呢,還有更多內(nèi)容值得分享出來。
參考資料http://www.ceus-now.com/mysql-innodb-page-cleaner-settings-might-not-be-optimal/
https://www.percona.com/blog/2013/02/04/cant_create_thread_errno_11/
https://www.percona.com/blog/2006/07/03/choosing-proper-innodb_log_file_size/
https://www.percona.com/blog/2011/07/09/how-to-change-innodb_log_file_size-safely/
分享文章:使用sysbench壓力測試MySQL(二)-創(chuàng)新互聯(lián)
網(wǎng)站URL:http://www.rwnh.cn/article34/ccihse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、網(wǎng)站設(shè)計公司、品牌網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容