mysql+mycat壓力測試一例

前言

Mycat是業內知名mysql數據庫中間件,其功能在各種mysql中間件中是比較豐富的.而mycat相關組件由java語言編寫,部署方便.他的功能有:不透明代理,讀寫分離,負載均衡,數據分片等.而且因爲其底層連接方式是用java的jdbc組件來連接數據庫的,所以理論上是支持sql server,oracle,pgsql的,但是功能上主要集中在mysql上.

優點:部署簡單,功能強大,靈活性高,彌補mysql的一些功能缺失

缺點:功能開發不算十分完善,需要注意踩坑

如果按原理來說,mycat如果不做分片,純粹只是代理的話,他所做的事情,其實更多的是數據轉發,而這個轉發能力,當然就是看他能有多強.

既然理論上轉發能力很強,那麼是不是就可以忽略不計呢,當然不是,所以需要用直連mysql的測試數據來做對比.


測試前準備

服務器配置爲32核cpu(虛擬化後的數值,算上超線程),120G內存,16000iops的存儲設備,具體分配情況:

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

簡單說明拓撲關係:

1.png

第一步當然是安裝好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配置文件參數,其他buffer_pool什麼的就不列出來了,請各自看情況設置,這裏只說明涉及壓測相關的參數.

#打開配置文件
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以上,

下載java語言程序包,

Java的下載地址一直在變,所以最好自己上去看着來下載

http://download.oracle.com/otn-pub/java/jdk/8u151-b12/e758a0de34e24606bca991d704f6dcbf/jdk-8u151-linux-x64.tar.gz?AuthParam=1513326216_bcf60226458d67751e1d8d1bbe6689b4

#下載好安裝包後,解壓創建軟連接
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配置做好就可以用.

我們下載mycat1.6.5的版本,這是最新正式版

http://dl.mycat.io/1.6.5/Mycat-server-1.6.5-release-20180122220033-linux.tar.gz

#解壓安裝包
tar xf Mycat-server-1.6.5-release-20180122220033-linux.tar.gz
#移到目的位置
mv mycat1.6.5 /usr/local/
#創建軟連接
ln -sf mycat1.6.5/ mycat
#把命令也做軟連接
ln -sf /usr/local/mycat/bin/* /usr/bin/

然後就可以開始改配置文件了

這裏sysbench的測試沒有涉及分庫分表,所以mycat只需要設置server.xml和schema.xml即可,具體mycat存放路徑沒規定,我將他放在/usr/local了.

==============================分割線開始==============================

有的人可能會疑惑,mycat支持分庫分表,那麼壓測可不可以針對分庫分表進行呢?其實理論上是可行的,有意向做分庫分表壓測的就要把數據做一些處理,按照sysbench原理來說是可行的,他測試的表的數量是可控的,你把帶數字編號的表通過邏輯庫處理可以集合成一個新的邏輯表.

==================分割線結束==========================================

先看基本環境設置server.xml,大部分設置都可以不動,注意添加修改的是<system>標籤下面配置就可以了,每創建一個用戶<user>是要另外起標籤:

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
#如果改了schema的配置,需要這個命令
Mysql>reload @@config_all

加載完成就可以使用新配置了,哪怕是改了登錄用戶名也能熱加載.


搭建sysbench

下載下來後,只要有c運行庫就能編譯安裝,但是要創建mysql庫文件的軟連接,不然會報錯找不到庫文件,

#先安裝依賴包
yum install -y automake libtool
#先創建mysql庫文件的軟連接,不然編譯會報錯的
ln -sf /usr/local/mysql/lib/libmysql*  /usr/lib64
ln -sf /usr/local/mysql/lib/libmysqlclient.so  /usr/lib64/libmysqlclient_r.so
#然後執行:
tar xf sysbench-0.4.12-1.1.tgz
cd 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是啥就不解析了
--oltp_tables_count=15    表示會生成 15 個測試表,數量越多,自然花費時間越長
--oltp-table-size=40000000    表示每個測試表填充數據量爲 40000000行 ,數量越多也是越時間長
--rand-init=on    表示每個測試表都是用隨機數據來填充的,這樣才客觀

--mysql-table-engine=innodb    表示表的引擎是innodb

prepare    用於準備測試需要的數據,準備完後執行run來測試,測試完成後如果需要清理數據就用cleanup來清除測試數據

=====================分割線開始===================================

所以這裏創造了15個表,裏面每個表有4000萬行的數據,數據爲隨機輸入,這個數據量大概需要150G硬盤空間,估計可以涵蓋大部分情況了吧,當然,你也可以創建更多數據.

數據結構大致是這樣的,僅供參考:

mysql> show tables;
+------------------+
| Tables_in_sbtest |
+------------------+
| sbtest1          |
| sbtest2          |
| sbtest3          |
    .
    .
    .
| sbtest15         |
+------------------+
5 rows in set (0.00 sec)
mysql> select * from sbtest1 limit 1;
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k       | c                                                                                                                       | pad                                                         |
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
|  1 | 2507308 | 68487932199-96439406143-93774651418-41631865787-96406072701-20604855487-25459966574-28203206787-41238978918-19503783441 | 22195207048-70116052123-74140395089-76317954521-98694025897 |
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.01 sec)

=============分割線結束========================================

然後就可以進行正式測試了,我們先進行測試普通主從架構:

#進入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
#我們設定的是3600秒,在此之前終止,也就是測試失敗,需要分析報錯

參數解析:

--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,平均延時3052.99ms.

看完解析,來看結果,下面是直接測主從環境的結果:

OLTP test statistics:
    queries performed:
        read:                            19215238
        write:                           5490068
        other:                           2745034
        total:                           27450340
    transactions:                        1372517 (381.03 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 24705306 (6858.48 per sec.)
    other operations:                    2745034 (762.05 per sec.)

General statistics:
    total time:                          3602.1538s
    total number of events:              1372517
    total time taken by event execution: 3688254.2686s
    response time:
         min:                                 18.33ms
         avg:                               2687.22ms
         max:                              55386.15ms
         approx.  99 percentile:           12444.89ms

Threads fairness:
    events (avg/stddev):           1340.3486/33.85
    execution time (avg/stddev):   3601.8108/0.44

每秒事務數Tps達381.03,每秒查詢數Qps達6858.48,平均耗時2687.22ms,畢竟總數據量是6億,還是應該要接受.

下面是通過mycat代理的結果

OLTP test statistics:
    queries performed:
        read:                            18078326
        write:                           5165236
        other:                           2582618
        total:                           25826180
    transactions:                        1291309 (358.40 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 23243562 (6451.19 per sec.)
    other operations:                    2582618 (716.80 per sec.)

General statistics:
    total time:                          3602.9883s
    total number of events:              1291309
    total time taken by event execution: 3687715.5739s
    response time:
         min:                                 22.45ms
         avg:                               2855.80ms
         max:                              50326.08ms
         approx.  99 percentile:           13264.21ms

Threads fairness:
    events (avg/stddev):           1261.0439/33.56
    execution time (avg/stddev):   3601.2847/0.96

每秒事務數Tps達358.40,每秒查詢數Qps達6451.19,平均耗時2855.80ms,同樣是總數據量6億.

從結果對比計算,使用mycat後,tps,qps,和耗時都損耗了6%-7%,在我個人看來還是可以接受,因爲使用了mycat做代理層,可以很方便的管理後端數據庫,任何切換都可以手動來秒切,使用上觸發腳本後就是一個HA框架了.


題外說明

測試結果示例說明的例子,其實是加上了高可用keepalived的測試結果,每秒事務數Tps達335.29,每秒查詢數Qps達6035.29,平均延時3052.99ms,總的來說算好,也還只是比純mysql主從損耗10%範圍內,可以接受,畢竟可用性高了很多,而且後續壓力增大也可以隨時增加mycat數量來填補.

功能多了,機器也要多了一些,需要特別說明的是,因爲涉及網絡數據包轉發關係,keepalived和後端mycat不能在同一臺服務器,所以就必須獨立開來.

10.21.128.208:keepalived主

10.21.128.209:keepalived備

10.21.128.200:mycat1

10.21.128.201:mycat2

10.21.128.199:vip

簡單說明拓撲關係:

2.png

需要多搭建一個mycat,不過這裏就不細說了,直接複製一份配置到其他機器再啓動就ok了.


然後搭建一套keepalived集羣:

大多數情況下,大夥使用keepalived只做HA功能,而LVS功能則交給其他軟件實現.但是實際上keepalived+ipvsadm既能實現HA功能,也能實現LVS功能,非常方便.

我們在10.21.128.20810.21.128.209上安裝keepalived和修改配置.

個人不想糾結功能和版本問題,而這些也是比較常態功能性的軟件,絕大部分yum源都配備,所以直接用yum安裝就很方便,有額外興趣的可以慢慢編譯

#安裝需要的軟件
yum install -y keepalived ipvsadm nc rsync telnet tcpdump wget

安裝很快,我們直接看配置,yum安裝默認的配置文件在/etc/keepalived/

#修改配置文件,注意註釋位置
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
#全局配置
global_defs {
   notification_email {
        root@localhost    #定義收件人郵件地址
   }
   notification_email_from root@localhost    #定義發件人
   smtp_server 127.0.0.1    #如果要使用第三方smtp服務器,在現實中幾乎沒有意義(需要驗證的原因),設爲本地就可以了
   smtp_connect_timeout 30    #smtp超時時間
   router_id LVS_HA_MYCAT1    #此服務器keepalived的ID,隨便改,注意不同服務器不一樣就行
}
#vrrp配置(HA配置)
vrrp_instance VI_1 {    #定義虛擬路由,VI_1 爲虛擬路由的標示符,自己定義名稱
    state MASTER    #指定當前節點爲主節點 備用節點上設置爲BACKUP即可 
    interface eth0    #綁定虛擬IP的網絡接口,注意內外網
    virtual_router_id 19    #VRRP組名,兩個節點的設置必須一樣,以指明各個節點屬於同一VRRP組,0-255隨便你用,這個ID也是虛擬MAC最後一段的來源
    priority 100    #初始優先級,取值1-254之間,主節點一定要最大,其他從節點則看情況減少
    advert_int 1    #組播信息發送間隔,兩個節點設置必須一樣
    authentication {    #設置驗證信息,兩個節點必須一致
        auth_type PASS
        auth_pass 199200
    }
    virtual_ipaddress {
        10.21.128.199    #指定VIP,兩個節點設置必須一樣,虛擬ip最好和真實ip在同一網段。
    }
}
#負載均衡配置(LVS配置)
virtual_server 10.21.128.199 8066  {    #指定VIP和端口,vip就是上面設置那個
    delay_loop 6    #延遲多少個週期再啓動服務,做服務檢測
    lb_algo rr    #負載均衡調度算法
    lb_kind DR    #負載均衡類型選擇,可選DR|NAT|TUN,DR性能比較高
    nat_mask 255.255.255.0    #vip的掩碼
    persistence_timeout 0    #會話保持時間,一定時間之內用戶無響應則下一次用戶請求時需重新路由,一般設爲0,不需要.
    protocol TCP    #使用的協議,一般就TCP

    real_server 10.21.128.200 8066  {    #定義後端realserver的真實服務器屬性,ip和端口
        weight 1    #負載均衡權重,數值越大,就負擔更多連接
        MISC_CHECK {    #定義心跳檢測的方法,因爲不是web,而且用tcp_check健康檢測後面的mycat會報錯,所以需要misc_check的方式做心跳檢測
        misc_path"/etc/keepalived/shell/check_mycat_status.sh 10.21.128.200 8066"    #自定義心跳檢測shell腳本的路徑、檢測的服務器ip、檢測的端口。(引號必須要)
        misc_timeout 3    #腳本執行超時時間
        }
    }
    real_server 10.21.128.201 8066 {    #同上
        weight 2
        MISC_CHECK {
        misc_path"/etc/keepalived/shell/check_mycat_status.sh 10.21.128.201 8066"
        misc_timeout 3
        }
    }
    real_server 10.21.128.156 8066 {    #同上
        weight 2
        MISC_CHECK {
        misc_path"/etc/keepalived/shell/check_mycat_status.sh 10.21.128.156 8066"
        misc_timeout 3
        }
    }
}

裏面涉及一個檢測心跳的腳本,如下所示:

cat /etc/keepalived/shell/check_mycat_status.sh
#!/bin/bash
result=`nc -v -z $1 $2`
flag="succeeded"
if [[ $result =~ $flag ]]
then
         exit 0
else;
         exit 1
fi
#記得要給該腳本賦予執行權限:
chmod 755 check_mycat_status.sh

意思很簡單,就是通過nc命令檢測真實服務器的mycat的端口通不通,如果不通的話,keepalived就把這個mycat剔除出集羣.


然後,在後端真實服務器上需要做一個操作,綁定vip創建ipvs規則:

10.21.128.200,10.21.128.201,10.21.128.156上創建並執行下面的腳本,

#創建規則腳本
vim /shell/realserver 
#!/bin/bash
SNS_VIP=10.21.128.199
#/etc/rc.d/init.d/functions
case "$1" in
start)
        ifconfig lo:0 $SNS_VIP broadcast $SNS_VIP netmask 255.255.255.255 up
        sleep 5
        /sbin/route add ${SNS_VIP}/32 dev lo:0
        echo "1">/proc/sys/net/ipv4/conf/lo/arp_ignore
        echo "2">/proc/sys/net/ipv4/conf/lo/arp_announce
        echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
        echo "2">/proc/sys/net/ipv4/conf/all/arp_announce
        sysctl -p >/dev/null 2>&1
        echo "RealServer Start OK"
;;
stop)
        ifconfig lo:0 down
        /sbin/route del -net $SNS_VIP netmask 255.255.255.255 dev lo:0
        echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
        echo "0">/proc/sys/net/ipv4/conf/lo/arp_announce
        echo "0">/proc/sys/net/ipv4/conf/all/arp_ignore
        echo "0">/proc/sys/net/ipv4/conf/all/arp_announce
        echo "RealServer Stoped"
;;
restart)
/sbin/route del -net $SNS_VIP netmask 255.255.255.255 dev lo:0
/sbin/route add ${SNS_VIP}/32 dev lo:0
;;
*)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac
exit 0
#賦予執行權限
chmod 755 /shell/realserver
#執行一下
/shell/realserver start
#然後查看下網卡狀態
ifconfig lo:0
lo:0      Link encap:Local Loopback  
          inet addr:10.21.128.199  Mask:255.255.255.255
          UP LOOPBACK RUNNING  MTU:16436  Metric:1

需要注意,每次服務器重啓都必須啓動這個綁定,不然lvs就不生效了,例如把他放到/etc/rc.d/rc.local

echo "/shell/realserver start" >>/etc/rc.d/rc.local


萬事俱備,只欠東風,那就啓動keepalived吧.

10.21.128.20810.21.128.209上執行

#因爲是yum安裝,所以有linux服務
/etc/init.d/keepalived start
Starting keepalived:                                       [  OK  ]
---------------------------------------------------------------------
#如果是centos7或者是ubuntu14以上的系統,就需要以下的命令
systemctl start keepalived
systemctl status keepalived
systemctl stop keepalived
systemctl reload keepalived
---------------------------------------------------------------------
#看看vip,因爲主是208,所以vip只會在208出現,除非208掛了
ip addr 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 22:87:35:77:ef:38 brd ff:ff:ff:ff:ff:ff
    inet 10.21.128.208/24 brd 10.21.128.255 scope global eth0
    inet 10.21.128.199/32 scope global eth0    #-------VIP在這
    inet6 fe80::2087:35ff:fe77:ef38/64 scope link 
       valid_lft forever preferred_lft forever
#然後看看當前LVS狀態
ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.21.128.199:8066 rr
  -> 10.21.128.156:8066           Route   2      0          0         
  -> 10.21.128.200:8066           Route   1      0          0         
  -> 10.21.128.201:8066           Route   2      0          0


一切都正常,那麼,我們可以壓測了.

#和之前命令差不多,只是ip不一樣
./sysbench --mysql-host=10.21.128.199 --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_20171128-3.log

我們來看看lvs狀態

#查看鏈接狀態
ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.21.128.199:8066 rr
  -> 10.21.128.156:8066           Route   2      341        340       
  -> 10.21.128.200:8066           Route   1      341        340       
  -> 10.21.128.201:8066           Route   2      342        340       
#加上另一個參數
ipvsadm -L --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
  -> RemoteAddress:Port
TCP  10.21.128.199:8066               2045  3658545        0  326481K        0
  -> 10.21.128.156:8066                682  1131691        0  114278K        0
  -> 10.21.128.200:8066                681  1266405        0  106344K        0
  -> 10.21.128.201:8066                682  1260449        0  105858K        0

爲什麼會沒有out?是不是很奇怪?因爲我們負載均衡類型選擇的是DR模式,這個模式的特點就是當客戶端和真實服務器建立鏈接後,真實服務器會直接把數據發送給客戶端,不再需要keepalived來中轉,所以就沒有out的流量了,也就是爲什麼說效率就更高的原因了.

然後來看看壓測的結果如何?

OLTP test statistics:
    queries performed:
        read:                            17043978
        write:                           4869708
        other:                           2434854
        total:                           24348540
    transactions:                        1217427 (338.00 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 21913686 (6084.05 per sec.)
    other operations:                    2434854 (676.01 per sec.)

General statistics:
    total time:                          3601.8265s
    total number of events:              1217427
    total time taken by event execution: 3687506.3802s
    response time:
         min:                                 30.17ms
         avg:                               3028.93ms
         max:                              75102.41ms
         approx.  99 percentile:           13757.56ms

Threads fairness:
    events (avg/stddev):           1188.8936/33.40
    execution time (avg/stddev):   3601.0804/0.40

每秒事務數Tps達338.00,每秒查詢數Qps達6084.05,平均延時3028.93ms,和一開始相差無幾,基本符合現實.






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