mysql+mycat壓力測試一例
有很多人擔心生產系統上新東西的程序怕壓力跟不上和穩定性不行,是的,大家都怕,所以領導要求做一次壓力測試,我個人也覺得是有必要的.
如果按原理來說,mycat如果不做分片,純粹只是代理的話,他所做的事情,其實更多的是數據轉發,而這個轉發能力,當然就是看他能有多強.
既然理論上轉發能力很強,那麽是不是就可以忽略不計呢,當然不是,所以需要用直連mysql的測試數據來做對比.
測試前準備
服務器分配情況:
10.21.128.156:mycat1.6.5,sysbench0.4
10.21.128.157:mysql5.7.20主庫
10.21.128.158:mysql5.7.20從庫1
10.21.128.159:mysql5.7.20從庫2
第一步當然是安裝好mysql,這裏就不詳細介紹怎麽安裝了,但是,my.cnf的參數是有些變化的,主要原因是要適應高並發壓測環境,不然就被參數限制,然後程序退出.當然了,如果你想盡量模擬線上環境,那這些限制你得思考在內,更改就需要謹慎一些,我這裏只是給出一例來參考.
#首先,就是要把系統的連接數和打開文件數搞起來 ulimit -SHn 65535 #想永久生效就要這樣 echo " * soft nofile 65535 * hard nofile 65535 root soft nofile 65535 root hard nofile 65535 " >> /etc/security/limits.conf
然後,更改mysql配置文件參數
#打開配置文件 vim /usr/local/mysql/my.cnf #其他參數我們暫時忽略,只看這些關乎壓測的參數 [mysqld] #每臺機都需要不一樣的ID,主從環境下 server-id = 128157 #全局最大打開文件數,不可以超過系統設定的最大文件數,不然無效 open_files_limit = 65530 #innodb引擎限制一次打開表空間文件.ibd的文件描述符數量 innodb_open_files = 65530 #允許存到緩存裏的表的句柄數量,壓測自然要打開很多表,設大一點就對了,受系統limit和上面兩個參數一起限制 table_open_cache = 65000 #最大連接數,×××,不然壓著不通就麻煩 max_connections=30000 #最大每用戶連接數,和上面一樣 max_user_connections=20000 #最大數據包大小,做壓測改大一點還是有必要 max_allowed_packet = 128M #限制了同一時間在mysqld上所有session中prepared 語句的上限,平時不用理這個參數,但是壓測就需要調大一點 max_prepared_stmt_count=100000
其他參數我就不一一列舉,自己看情況來設置就行,然後,重啟生效待命.
軟件安裝
先說說壓測工具的選擇問題,在MySQL協議上Mycat不兼容tpcc,所以放棄tpcc。然後sysbench1.0對mycat兼容也比較欠佳,壓測不明原因失敗次數多,所以也只能放棄.最後選定sysbench0.4和0.5來使用,可以順利測出結果,而且從壓測的原理來說也比較客觀.
所以,我們需要安裝的軟件有:mysql(默認已裝),mycat,sysbench0.4或0.5
mysql怎麽安裝和授權什麽的,這裏就不細說了,還請各位自己搭建好.
先安裝mycat:
1)搭建jdk環境
由於mycat是java程序,所以需要安裝JDK,版本至少要jdk1.6以上,下載好安裝包後,
tar xf jdk-8u144-linux-x64.tar.gz
mv jdk1.8.0_144/ /usr/local/
ln -sf jdk1.8.0_144/ jdk
創建環境變量
vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/local/jdk
export JRE_HOME=/usr/local/jdk/jre
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin
重載環境變量
source /etc/profile
驗證安裝
java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
安裝完成,可以使用.
2)配置mycat
了解java程序的同學應該知道,java程序只要配置好,直接啟動就能用,所以沒有安裝的概念,直接將mycat配置做好就可以用.
因為沒有涉及分庫分表,mycat只需要設置server.xml和schema.xml即可,具體mycat存放路徑沒規定,我將他放在/usr/local了.
先看基本環境設置server.xml,大部分設置都可以不動,註意添加修改下面配置就可以了,註意標簽:
vim /usr/local/mycat/conf/server.xml
<system> <property name="idleTimeout">2880000</property> <!--設置超時時間為28800秒 --> <property name="maxPacketSize">134217728</property> <!--設置最大網絡包為128M --> <property name="charset">utf8</property> <!--設置默認字符集為utf8 --> <property name="txIsolation">2</property> <!--設置隔離級別為RC --> <property name="sqlExecuteTimeout">600</property> <!--設置sql執行的超時時間為600秒 --> </system> <!--下面是設置mycat的用戶名/密碼和權限控制,和mysql的用戶名密碼無關 --> <user name="root" defaultAccount="true"> <property name="password">mycat123</property> <property name="schemas">sbtest,testppp</property> </user> <user name="sysbench"> <property name="password">sb123</property> <property name="schemas">sbtest</property> </user> <user name="test"> <property name="password">test</property> <property name="schemas">sbtest</property> <property name="readOnly">true</property> <privileges check="false"> <schema name="sbtest" dml="0001" > <table name="sbtest11" dml="1111"></table> </schema> </privileges> </user>
設置了一些必要項目,和創建了三個用戶root,sysbench,test.這三個用戶和數據庫的用戶沒有關聯,是獨立的,即使這個用戶密碼被破解,數據庫的密碼依然安全.其中root有完全控制權限,sysbench只能控制sbtest庫,test也只能控制sbtest庫,而且限制了讀寫權限.
然後設置邏輯庫配置文件schema.xml,這裏改動比較多,所以直接貼上整個文件:
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="sbtest" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> </schema> <schema name="testppp" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn2"> </schema> <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743" /> --> <dataNode name="dn1" dataHost="10.21.128.157" database="sbtest" /> <dataNode name="dn2" dataHost="10.21.128.157" database="testppp" /> <!--<dataNode name="dn4" dataHost="sequoiadb1" database="SAMPLE" /> <dataNode name="jdbc_dn1" dataHost="jdbchost" database="db1" /> <dataNode name="jdbc_dn2" dataHost="jdbchost" database="db2" /> <dataNode name="jdbc_dn3" dataHost="jdbchost" database="db3" /> --> <dataHost name="10.21.128.157" maxCon="3000" minCon="20" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts --> <writeHost host="hostM1" url="10.21.128.157:3306" user="root" password="128157"> <!-- can have multi read hosts --> <readHost host="hostS2" url="10.21.128.158:3306" user="root" password="128157" /> <readHost host="hostS3" url="10.21.128.159:3306" user="root" password="128157" /> </writeHost> <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> --> </dataHost> </mycat:schema>
設置了兩個邏輯庫sbtest和testppp(和真實庫同名,其實可以不同),指向的真實數據庫的主從環境dn1和dn2,裏面有一主兩從三臺真實服務器地址,並開啟讀寫分離(事務只走主庫).
3) 啟動mycat,
#啟動mycat Mycat start #重啟mycat Mycat restart #關閉mycat Mycat stop #而Mycat默認的連接端口是8066,管理端口是9066,可以在server.xml修改. ss -ntplu |grep java tcp LISTEN 0 100 :::9066 :::* users:(("java",pid=115779,fd=168)) tcp LISTEN 0 100 :::8066 :::* users:(("java",pid=115779,fd=172)) #看到端口起來了,就可以使用了,因為mycat支持mysql原生協議,所以連上8066端口是不會和一般mysql有什麽區別,直接就能使用了. #如果更改了任何配置文件,可以登錄進管理端口執行下列命令實時熱刷新配置,相當方便. mysql -uroot -pmycat123 -h10.21.128.156 -P9066 #更改server的配置可以 Mysql>reload @@config 如果改了邏輯庫的配置,需要這個命令 Mysql>reload @@config_all
加載完成就可以使用新配置了,哪怕是改了登錄用戶名也能熱加載.
搭建sysbench
下載下來後,只要有c運行庫就能編譯安裝,但是要創建mysql庫文件的軟連接,不然會報錯找不到庫文件,
#先創建mysql庫文件的軟連接 ln -sf /usr/local/mysql/lib/* /usr/lib64/ #然後執行: cd /tmp/sysbench-0.4.12-1.1 ./autogen.sh ./configure --with-mysql-includes=/usr/local/mysql/include --with-mysql-libs=/usr/local/mysql/lib Make #如果 make 沒有報錯,就會在 sysbench 目錄下生成二進制命令行工具 sysbench cd /tmp/sysbench-0.4.12-1.1/sysbench ls -l sysbench -rwxr-xr-x 1 root root 3293186 Sep 21 16:24 sysbench
在此,環境就搭建完畢了.
開始測試
環境準備好了,就開始測試了,測試前要先準備測試數據,需要使用命令來制造出來,需要比較長的時間,重點是要關註硬盤空間是否足夠:
#避免不必要的錯誤,直連數據庫操作 mysql -uroot -p128157 -h10.21.128.157 -P3306 #創建測試數據庫,sysbench默認庫名是sbtest,也可以指定庫名 mysql> create database sbtest #進入sysbench程序目錄 cd /tmp/sysbench-0.4.12-1.1/sysbench #開始造數據, ./sysbench --mysql-host=10.21.128.157 --mysql-port=3306 --mysql-user=root --mysql-password=128157 --test=tests/db/oltp.lua --oltp_tables_count=15 --oltp-table-size=40000000 --mysql-table-engine=innodb --rand-init=on prepare
參數解析:
--test=tests/db/oltp.lua 表示調用 tests/db/oltp.lua 腳本進行 oltp 模式測試
--oltp_tables_count=15 表示會生成 15 個測試表
--oltp-table-size=40000000 表示每個測試表填充數據量為 40000000行
--rand-init=on 表示每個測試表都是用隨機數據來填充的
--mysql-table-engine=innodb 表示表的引擎是innodb
prepare 用於準備測試需要的數據,準備完後執行run來測試,測試完成後如果需要清理數據就用cleanup來清除測試數據
所以這裏創造了15個表,裏面每個表有4000萬行的數據,數據為隨機輸入,這個數據量大概需要150G硬盤空間,估計可以涵蓋大部分情況了吧,當然,你也可以創建更多數據.
然後就可以進行正式測試了,我們先進行測試普通主從架構:
#進入sysbench程序目錄 cd /tmp/sysbench-0.4.12-1.1/sysbench #執行測試命令 ./sysbench --mysql-host=10.21.128.157 --mysql-port=3306 --mysql-user=root --mysql-password=128157 --test=tests/db/oltp.lua --oltp_tables_count=15 --oltp-table-size=40000000 --mysql-table-engine=innodb --num-threads=1024 --oltp-read-only=off --report-interval=10 --rand-type=uniform --max-time=3600 --max-requests=0 --percentile=99 run >> /tmp/sysbench_oltpX_32_20171113-1.log
參數解析:
--num-threads=1024 表示發起1024個並發連接
--oltp-read-only=off 表示不要進行只讀測試,也就是會采用讀寫混合模式測試
--report-interval=10 表示每10秒輸出一次測試進度報告
--rand-type=uniform 表示隨機類型為固定模式,其他幾個可選隨機模式:uniform(固定),gaussian(高斯),special(特定的),pareto(帕累托)
--max-time=3600 表示最大執行時長為3600秒,測試將在這個時間後結束
--max-requests=0 表示總請求數為 0,因為上面已經定義了總執行時長,所以總請求數可以設定為 0;也可以只設定總請求數,不設定最大執行時長
--percentile=99 表示設定采樣比例,默認是 95%,即丟棄1%的長請求,在剩余的99%裏取最大值
根據上面的解析,最後輸出到一個文件.
然後到mycat代理環境:
./sysbench --mysql-host=10.21.128.156 --mysql-port=8066 --mysql-user=sysbench --mysql-password=sb123 \ --test=tests/db/oltp.lua --oltp_tables_count=15 --oltp-table-size=40000000 --mysql-table-engine=innodb --num-threads=1024 --oltp-read-only=off --report-interval=10 --rand-type=uniform --max-time=3600 --max-requests=40000000 --percentile=99 run >> /home/logs/sysbench_oltpX_32_20171113-2.log
和上面一樣,設定了並發為1024個線程,測試時間為3600秒即1小時,同時也是用到剛才制造出來的15個4000萬行的表,設定取值采樣平均值為99%的數據,輸出到另一個log文件.
閱讀測試報告
測試完了,就來看結果了,我們拿其中一個結果來解析說一下:
#忽略掉一些每10秒統計值,只看最後的統計值 vim /tmp/sysbench_oltpX_32_20171113-1.log sysbench 0.5: multi-threaded system evaluation benchmark Running the test with following options: Number of threads: 1024 Report intermediate results every 10 second(s) Random number generator seed is 0 and will be ignored Threads started! -- 每10秒鐘報告一次測試結果,tps、每秒讀、每秒寫、99%以上的響應時長統計 [ 10s] threads: 1024, tps: 364.69, reads/s: 6324.66, writes/s: 1765.66, response time: 4292.46ms (99%) [ 20s] threads: 1024, tps: 475.80, reads/s: 6037.91, writes/s: 1640.10, response time: 4088.05ms (99%) [ 30s] threads: 1024, tps: 439.40, reads/s: 6349.45, writes/s: 1808.89, response time: 3248.44ms (99%) [ 40s] threads: 1024, tps: 487.70, reads/s: 6438.46, writes/s: 1879.72, response time: 4385.98ms (99%) [ 50s] threads: 1024, tps: 395.70, reads/s: 6498.99, writes/s: 1849.00, response time: 3845.88ms (99%) . . . [3560s] threads: 1024, tps: 385.80, reads/s: 4949.60, writes/s: 1503.80, response time: 19827.73ms (99%) [3570s] threads: 1024, tps: 249.70, reads/s: 3679.90, writes/s: 1009.40, response time: 12016.58ms (99%) [3580s] threads: 1024, tps: 328.90, reads/s: 4511.40, writes/s: 1301.40, response time: 7419.06ms (99%) [3590s] threads: 1024, tps: 196.40, reads/s: 3058.90, writes/s: 815.30, response time: 12092.35ms (99%) [3600s] threads: 1024, tps: 386.60, reads/s: 5282.74, writes/s: 1537.78, response time: 13614.18ms (99%) OLTP test statistics: queries performed: read: 16913554 -- 讀總數 write: 4832444 -- 寫總數 other: 2416222 -- 其他操作總數(SELECT、INSERT、UPDATE、DELETE之外的操作,例如COMMIT等) total: 24162220 -- 全部總數 transactions: 1208111 (335.29 per sec.) -- 總事務數(每秒事務數) deadlocks: 0 (0.00 per sec.) -- 發生死鎖總數 read/write requests: 21745998 (6035.29 per sec.) -- 讀寫總數(每秒讀寫次數) other operations: 2416222 (670.59 per sec.) -- 其他操作總數(每秒其他操作次數) General statistics: total time: 3603.1388s -- 總耗時 total number of events: 1208111 -- 共發生多少事務數 total time taken by event execution: 3688348.3797s -- 所有事務耗時相加(不考慮並行因素) response time: min: 28.41ms -- 最小耗時 avg: 3052.99ms -- 平均耗時 max: 48667.93ms -- 最長耗時 approx. 99 percentile: 12708.40ms -- 超過99%平均耗時 Threads fairness: events (avg/stddev): 1179.7959/29.07 execution time (avg/stddev): 3601.9027/1.01
所以,每秒事務數Tps達335.29,每秒查詢數Qps達6035.29.
看完解析,來看結果,下面是直接測主從環境的結果:
OLTP test statistics: queries performed: read: 21161868 write: 6046248 other: 3023124 total: 30231240 transactions: 1511562 (419.65 per sec.) deadlocks: 0 (0.00 per sec.) read/write requests: 27208116 (7553.71 per sec.) other operations: 3023124 (839.30 per sec.) General statistics: total time: 3601.9548s total number of events: 1511562 total time taken by event execution: 3687391.4160s response time: min: 17.05ms avg: 2439.46ms max: 34582.27ms approx. 99 percentile: 11020.73ms Threads fairness: events (avg/stddev): 1476.1348/27.71 execution time (avg/stddev): 3600.9682/0.33
每秒事務數Tps達419.65,每秒查詢數Qps達7553.71
下面是通過mycat代理的結果
OLTP test statistics: queries performed: read: 23383990 write: 6681140 other: 3340570 total: 33405700 transactions: 1670285 (463.76 per sec.) deadlocks: 0 (0.00 per sec.) read/write requests: 30065130 (8347.72 per sec.) other operations: 3340570 (927.52 per sec.) General statistics: total time: 3601.5979s total number of events: 1670285 total time taken by event execution: 3687347.4150s response time: min: 21.40ms avg: 2207.62ms max: 23365.26ms approx. 99 percentile: 8844.22ms Threads fairness: events (avg/stddev): 1631.1377/26.35 execution time (avg/stddev): 3600.9252/0.36
每秒事務數Tps達463.76,每秒查詢數Qps達8347.72
從總體說個結果,果然和我預料差不多,損耗在5%之內.
mysql+mycat壓力測試一例