真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

ProxySQL亮點(diǎn)、安裝、配置及測(cè)試等解析

下文內(nèi)容主要給大家?guī)?lái)ProxySQL亮點(diǎn)、安裝、配置及測(cè)試等解析,這里所講到的知識(shí),與書(shū)籍略有不同,都是創(chuàng)新互聯(lián)專(zhuān)業(yè)技術(shù)人員在與用戶(hù)接觸過(guò)程中,總結(jié)出來(lái)的,具有一定的經(jīng)驗(yàn)分享價(jià)值,希望給廣大讀者帶來(lái)幫助。

10年積累的成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶(hù)對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶(hù)得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站策劃后付款的網(wǎng)站建設(shè)流程,更有新津縣免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。


一、亮點(diǎn)

  1. 幾乎所有的配置均可在線更改(其配置數(shù)據(jù)基于SQLite存儲(chǔ)),無(wú)需重啟proxysql
  2. 基于正則和client_addr的強(qiáng)大和靈活的路由規(guī)則
  3. 詳細(xì)的狀態(tài)統(tǒng)計(jì),統(tǒng)計(jì)結(jié)果和pt-query-digest對(duì)慢日志的分析結(jié)果類(lèi)似,相當(dāng)于有了統(tǒng)一的查看sql性能和sql語(yǔ)句統(tǒng)計(jì)的入口(Designed by a DBA for DBAs)
  4. 自動(dòng)重連和重新執(zhí)行機(jī)制(auto-reconnect and automatic re-execution of queries using it's Connections Pool
    ):若一個(gè)請(qǐng)求在鏈接或執(zhí)行過(guò)程中意外中斷,proxysql會(huì)根據(jù)其內(nèi)部機(jī)制重新執(zhí)行該操作
  5. query cache功能:比MySQL自帶QC更靈活,可在mysql_query_rules表中依據(jù)digest,match_pattern,client_addr等維度控制哪類(lèi)語(yǔ)句可以緩存
  6. 支持連接池(connection pool)并且支持multiplexing,區(qū)別于atlas之流的連接池實(shí)現(xiàn)。文中有詳細(xì)對(duì)比說(shuō)明

ProxySQL亮點(diǎn)、安裝、配置及測(cè)試等解析

二、安裝

rpm包下載地址

https://github.com/sysown/proxysql/releases 推薦rpm形式安裝

Installing from source

Make sure you have installed the equivalent for each of these packages for your operating system:

automake
bzip2
cmake
make
gcc    #>4.4版本
gcc-c++
git
openssl
openssl-devel
patch

git clone https://github.com/sysown/proxysql.git

Go to the directory where you cloned the repo (or unpacked the tarball) and run:

make 
sudo make install

Compilation time should be around a couple of minutes for the first time around. The configuration file will be found at /etc/proxysql.cnfafterwards.

在make這一步遇到了錯(cuò)誤:

g++ -fPIC -c -o obj/ProxySQL_GloVars.oo ProxySQL_GloVars.cpp -std=c++11 -I../include -I../deps/jemalloc/jemalloc/include/jemalloc -I../deps/mariadb-client-library/mariadb_client/include -I../deps/libconfig/libconfig-1.4.9/lib -I../deps/re2/re2 -I../deps/sqlite3/sqlite3 -O2 -ggdb  -Wall 
cc1plus: 錯(cuò)誤:無(wú)法識(shí)別的命令行選項(xiàng)“-std=c++11”
make[1]: *** [obj/ProxySQL_GloVars.oo] 錯(cuò)誤 1
make[1]: Leaving directory `/usr/local/src/proxysql-master/lib'
make: *** [build_lib] 錯(cuò)誤 2

網(wǎng)查是由于gcc版本低導(dǎo)致,centos 6的yum源(以及epel源)都只能獲取到4.4.7版本

包 gcc-4.4.7-17.el6.x86_64 已安裝并且是最新版本
包 gcc-c++-4.4.7-17.el6.x86_64 已安裝并且是最新版本
而centos7上為4.8版本

換到centos7上,將上述軟件安裝/更新之后,make步驟完成,但是make install步驟又出了問(wèn)題:

install -m 0755 src/proxysql /usr/local/bin
install -m 0600 etc/proxysql.cnf /etc
install -m 0755 etc/init.d/proxysql /etc/init.d
if [ ! -d /var/lib/proxysql ]; then mkdir /var/lib/proxysql ; fi
update-rc.d proxysql defaults
make: update-rc.d:命令未找到
make: *** [install] 錯(cuò)誤 127

update-rc.d是ubuntu的自啟動(dòng)腳本管理軟件,未成功安裝不影響使用。

安裝完成后,自動(dòng)在/etc/init.d/proxysql增加服務(wù)管理腳本(需要把/usr/local/bin/加入\$PATH或者軟鏈至 \$PATH目錄下,腳本中直接用到proxysql命令)


三、配置

配置文件/etc/proxysql.cnf和配置數(shù)據(jù)庫(kù)文件/var/lib/proxysql/proxysql.db,如果存在 “proxysql.db”文件,則啟動(dòng)過(guò)程不解析proxysql.cnf文件;配置文件只在第一次啟動(dòng)的時(shí)候讀取

官方推薦用admin interface方式

登陸admin interface:

mysql -uadmin -padmin -P6032 -h227.0.0.1
登陸成功后,可通過(guò)對(duì)main庫(kù)(默認(rèn)登陸后即在此庫(kù))的global_variables表中的
    admin-admin_credentials
    admin-mysql_ifaces
兩個(gè)變量進(jìn)行更改來(lái)修改登錄認(rèn)證

注意:admin interface對(duì)配置的存儲(chǔ)是基于SQLite的,SQLite支持標(biāo)準(zhǔn)的SQL語(yǔ)法,與mysql也基本兼容。但是無(wú)法用use語(yǔ)句切換數(shù)據(jù)庫(kù),作者對(duì)use語(yǔ)句做了兼容(不報(bào)錯(cuò)),但是卻沒(méi)有實(shí)際效果。

配置后端DB server:
兩種方式,區(qū)別在于:
    1. 一種是在往mysql_servers表中添加server時(shí)就為其劃分好hostgroup_id(例如0表示寫(xiě)組,1表示讀組)
    2. 另一種往mysql_servers表中添加server時(shí)不區(qū)分hostgroup_id(例如全部設(shè)為0),然后通過(guò)mysql_replication_hostgroups表中的值,根據(jù)proxysql檢測(cè)到的各server的read_only變量值來(lái)自動(dòng)為后端server設(shè)置hostgroup_id

    這里強(qiáng)烈推薦用第一種方式:
    因?yàn)榈谝环N是完全由我們控制的;而第二種假如我們誤將讀server的read_only屬性設(shè)置為0,則proxysql會(huì)將其重新分配到寫(xiě)組,這絕對(duì)是不期望的。

四、功能測(cè)試

實(shí)驗(yàn)環(huán)境
MySQL [(none)]> select * from mysql_servers;        
+--------------+--------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname     | port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+--------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 0            | 192.168.1.21 | 3307 | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 1            | 192.168.1.10 | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 1            | 192.168.1.4  | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
+--------------+--------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+

#proxysql server的IP為:192.168.1.34
負(fù)載均衡測(cè)試

配置好一主(db1,hostgroup0)兩從(db2和db3,hostgroup1)    ,并且在'mysql_query_rules'表中增加一條路由規(guī)則

insert into mysql_query_rules (rule_id,active,match_digest,destination_hostgroup,apply) values (10,1,'^SELECT',1,1)

意為所有以select開(kāi)頭的語(yǔ)句路由到hostgroup1,其余語(yǔ)句路由到hostgroup0

在兩臺(tái)server的mysql-client分別連接至proxysql的6033端口,執(zhí)行'select @@hostname'觀察其分配到的后端server

以mysql -e的形式執(zhí)行該命令則能夠看到請(qǐng)求在兩臺(tái)讀server之間變換

[root@db1 ~]#  mysql -udm -p'dm' -h292.168.1.34 -P6033 -e "select @@hostname" -s -N.
db1
[root@db1 ~]#  mysql -udm -p'dm' -h292.168.1.34 -P6033 -e "select @@hostname" -s -N
db5
[root@db1 ~]#  mysql -udm -p'dm' -h292.168.1.34 -P6033 -e "select @@hostname" -s -N
db5
[root@db1 ~]#  mysql -udm -p'dm' -h292.168.1.34 -P6033 -e "select @@hostname" -s -N
db1
[root@db1 ~]#  mysql -udm -p'dm' -h292.168.1.34 -P6033 -e "select @@hostname" -s -N
db1
[root@db1 ~]#  mysql -udm -p'dm' -h292.168.1.34 -P6033 -e "select @@hostname" -s -N
db5
再實(shí)驗(yàn)下mysql -e跟多條語(yǔ)句會(huì)如何
[root@db1 ~]# mysql -udm -p'dm' -P6033 -h292.168.1.34 -e "select @@hostname;select @@hostname;select @@hostname" -s -N
dm-web5
dm-web5
dm-web5

由以上結(jié)果可能會(huì)猜想并可印證:在一個(gè)client的一個(gè)鏈接周期內(nèi),所有query路由到同一臺(tái)后端。  
但是:這只是個(gè)假象(是因?yàn)檎糜玫搅藄elect @ 語(yǔ)句。按作者所說(shuō): sends a query that implicitly disables multiplexing. For example, if you run "SELECT @a" , ProxySQL will disable multiplexing for that client and will always use the same backend connection.),proxysql的負(fù)載方式目前僅為加權(quán)輪詢(xún)一種(經(jīng)過(guò)作者確認(rèn)的),并無(wú)其他機(jī)制。

后端server宕機(jī)測(cè)試  

對(duì)上述架構(gòu)用sysbench做只讀測(cè)試,過(guò)程中關(guān)閉(service mysqld stop)某一臺(tái)server (測(cè)試均在mysql-monitor_enabled=false的前提下)

測(cè)試命令

alias sysbench_test='sysbench --test=/usr/share/doc/sysbench/tests/db/oltp.lua\
--mysql-user=dm --mysql-password='dm' --mysql-port=6033\
--mysql-host=192.168.1.34 --oltp-tables-count=16\
--num-threads=8 run --oltp-skip-trx=on --oltp-read-only=on'

結(jié)果如下

[root@db3 ~]# sysbench_test 
sysbench 0.5:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 8
Random number generator seed is 0 and will be ignored

Threads started!

ALERT: mysql_drv_query() for query 'SELECT c FROM sbtest16 WHERE id=4964' failed: 2013 Lost connection to MySQL server during query
ALERT: mysql_drv_query() for query 'SELECT c FROM sbtest12 WHERE id=4954' failed: 2013 Lost connection to MySQL server during query
ALERT: mysql_drv_query() for query 'SELECT c FROM sbtest7 WHERE id BETWEEN 4645 AND 4645+99' failed: 2013 Lost connection to MySQL server during query

不是說(shuō)好的自動(dòng)重連/重執(zhí)行嗎?為毛報(bào)錯(cuò)了呢(atlas有同樣問(wèn)題)

但是兩者通過(guò)上述的sysbench命令所拋出的錯(cuò)誤經(jīng)過(guò)多次比較,有不同:
proxysql報(bào)錯(cuò)就一種
    failed: 2013 Lost connection to MySQL server during query
atlas報(bào)錯(cuò)則是兩種
    failed: 2013 Lost connection to MySQL server during
    failed: 1317 Query execution was interrupted
是不是說(shuō)明re-execute有效呢?(no,其實(shí)這個(gè)思路就不對(duì))

測(cè)試方法錯(cuò)了:其實(shí)關(guān)閉后端mysql服務(wù)來(lái)測(cè)試“reconnect”特性應(yīng)該說(shuō)從本質(zhì)上就是不對(duì)的,mysql正常關(guān)閉會(huì)kill掉其上的所有processlist,我們可以用mysql-client來(lái)做一些驗(yàn)證

mysql> select @@hostname;
+------------+
| @@hostname |
+------------+
| db1        |
+------------+
1 row in set (0.00 sec)
**通過(guò)別的tty重啟該mysql**
mysql> select @@hostname;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    4
Current database: *** NONE ***
+------------+
| @@hostname |
+------------+
| db1        |
+------------+
1 row in set (0.00 sec)

可以看到mysql-client是具有重連(reconnect)功能的,然后我們來(lái)做一個(gè)kill掉mysql-client線程(也就是mysql在關(guān)閉時(shí)會(huì)kill掉所有線程)的操作

mysql> select @@hostname;
+------------+
| @@hostname |
+------------+
| db1        |
+------------+
1 row in set (0.00 sec)
**在mysql服務(wù)端查詢(xún)并kill掉這個(gè)鏈接**
mysql> select @@hostname;
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql> 

我們看到了之前sysbenche測(cè)試過(guò)程中關(guān)閉一臺(tái)從庫(kù)時(shí)的報(bào)錯(cuò)。也就是說(shuō)這個(gè)場(chǎng)景下這個(gè)報(bào)錯(cuò)不是proxysql的‘reconnect’機(jī)制的問(wèn)題,倒更像是‘re-execute’機(jī)制的問(wèn)題。而kill操作應(yīng)該理解為是mysql“主動(dòng)”的動(dòng)作,而非“異?!?,所以這就不符合proxysql 的"re-execute"特性了,故而會(huì)報(bào)錯(cuò)

應(yīng)該換一種方式來(lái)進(jìn)行這個(gè)測(cè)試

  • 模擬網(wǎng)絡(luò)層無(wú)法通信的異常

    我們?cè)趦膳_(tái)slave上通過(guò)iptables阻斷peoxysql到本機(jī)的3306端口來(lái)模擬無(wú)法鏈接和鏈接中斷異常

    在sysbench開(kāi)始之后再重啟iptables已經(jīng)建立的鏈接會(huì)被保留,所以新規(guī)則要放到第一條的位置  
    -A INPUT -s 192.168.1.34 -p tcp -m tcp --dport 3306 -j DROP

    首先    :?jiǎn)?dòng)sysbench只讀測(cè)試  
    然后    :在測(cè)試結(jié)束前,修改db1的iptables,禁止來(lái)自proxysql的請(qǐng)求進(jìn)入  
    然后    :觀察sysbench的輸出和proxysql.log的輸出  
    結(jié)果    :sysbench等待很長(zhǎng)時(shí)間,依然無(wú)法完成,同時(shí),proxysql也不會(huì)把db1標(biāo)記為SHUNNED  
    proxysql.log輸出:

    2016-09-02 11:37:54 MySQL_Session.cpp:49:kill_query_thread(): [WARNING] KILL QUERY 133 on 192.168.1.4:3306
    2016-09-02 11:37:54 MySQL_Session.cpp:49:kill_query_thread(): [WARNING] KILL QUERY 136 on 192.168.1.4:3306
    2016-09-02 11:37:54 MySQL_Session.cpp:49:kill_query_thread(): [WARNING] KILL QUERY 135 on 192.168.1.4:3306
    2016-09-02 11:37:54 MySQL_Session.cpp:49:kill_query_thread(): [WARNING] KILL QUERY 137 on 192.168.1.4:3306
    2016-09-02 11:37:54 MySQL_Session.cpp:49:kill_query_thread(): [WARNING] KILL QUERY 138 on 192.168.1.4:3306
    2016-09-02 11:37:54 MySQL_Session.cpp:49:kill_query_thread(): [WARNING] KILL QUERY 134 on 192.168.1.4:3306
    可以看到在mysql-default_query_timeout=30000,30s之后proxysql確實(shí)kill了超時(shí)的語(yǔ)句。
    30s這個(gè)時(shí)間可以通過(guò)執(zhí)行‘service iptables restart’的時(shí)間和proxysql.log里日志的時(shí)間來(lái)判定,這個(gè)設(shè)置30s是有效的

    然后,直接對(duì)后端node(db1)進(jìn)行同樣的測(cè)試,發(fā)現(xiàn)結(jié)果是一樣的,sysbench等待很長(zhǎng)時(shí)間依然無(wú)法完成也無(wú)報(bào)錯(cuò)。
    從這一點(diǎn)似乎可以判定在這個(gè)測(cè)試方法下,未達(dá)到預(yù)期結(jié)果的原因可能不在proxysql,而在sysbench本身。

    通過(guò)對(duì)重啟iptables之后的通信進(jìn)行抓包(分別對(duì)針對(duì)proxysql和mysql在這個(gè)測(cè)試場(chǎng)景下進(jìn)行抓包),命令如下:
    ~]# date; service iptables restart; tcpdump -i em2 host 192.168.1.35 and port 3306 and host not 192.168.1.10 -w /tmp/sysbench-proxysql-network-issue.pacp
    ~]# date; service iptables restart; tcpdump -i em2 host 192.168.1.34 and port 3306 and host not 192.168.1.10 -w /tmp/sysbench-proxysql-network-issue.pacp

    發(fā)現(xiàn),sysbench“一直”在重傳由于iptables新規(guī)則而無(wú)法返回的幾個(gè)請(qǐng)求,所以就成了“無(wú)窮盡等待的樣子” (atlas 在這個(gè)場(chǎng)景下有同樣問(wèn)題)

    照理說(shuō),proxysql kill掉了一些查詢(xún),會(huì)返回給sysbench錯(cuò)誤,但為什么sysbench并未將錯(cuò)誤展示出來(lái)呢(可能是因?yàn)閞e-execute機(jī)制)

    最后,通過(guò)跟作者溝通,發(fā)現(xiàn)是由于沒(méi)開(kāi)啟monitor模塊,導(dǎo)致proxysql無(wú)法檢測(cè)到后端出了什么類(lèi)型的錯(cuò)誤,也就無(wú)法執(zhí)行對(duì)應(yīng)各種后端錯(cuò)誤的一些操作(之前我是特意關(guān)掉了monitor模塊)

測(cè)試對(duì)prepare語(yǔ)句的支持

好多框架用prepare語(yǔ)句來(lái)避免SQL注入等安全問(wèn)題,同時(shí)能在MySQL解析查詢(xún)方面降低一些開(kāi)銷(xiāo),所以對(duì)于prepare語(yǔ)句支持與否也很重要

首先要從MySQL協(xié)議層面了解prepare語(yǔ)句,分為兩種(參考)

  • Prepared Statements in Application Programs  
    或者稱(chēng)為BINARY protocol

抓包分析一次prepare,set,execute過(guò)程,可以觀察到,客戶(hù)端發(fā)送的是COM_STMT_PREPARE

ProxySQL亮點(diǎn)、安裝、配置及測(cè)試等解析
ProxySQL亮點(diǎn)、安裝、配置及測(cè)試等解析

  • Prepared Statements in SQL Scripts
    或者稱(chēng)為TEXT protocol

抓包分析一次prepare,set,execute過(guò)程,可觀察到客戶(hù)端發(fā)送的是COM_QUERY  
ProxySQL亮點(diǎn)、安裝、配置及測(cè)試等解析  
ProxySQL亮點(diǎn)、安裝、配置及測(cè)試等解析  
ProxySQL亮點(diǎn)、安裝、配置及測(cè)試等解析  

關(guān)于prepare語(yǔ)句,作者給出的回復(fù)和計(jì)劃如下:
這是我在實(shí)驗(yàn)1.2.1版本時(shí)跟作者的溝通?,F(xiàn)在已經(jīng)發(fā)布1.3.5了,從1.3版本開(kāi)始,兩種協(xié)議都支持了。但是在設(shè)置字符集方面,對(duì)于binary protocol 的prepare set names xxx普通query(set names 'utf8' collate 'utf8_general_ci')(注意加了校對(duì)規(guī)則,不加校對(duì)規(guī)則可以)語(yǔ)句還無(wú)法正確處理(例如,php的laravel框架默認(rèn)就是以第一種形式設(shè)置字符集)。
修正:經(jīng)測(cè)試1.3.7版本,以上兩prepare語(yǔ)句的小bug都已解決

MySQL supports two type of prepared statements:  
using API 
using SQLFurther details here  
SQL support currently not supported either, because PREPARE doesn't disable multiplexing, so it is possible that ProxySQL sends PREPARE in a connection, and EXECUTE into another.

SQL support will be fixed in v1.2.3 , see #684 .  
API support is planned in ProxySQL 1.3 .


五、connection-pool和multiplexing(并對(duì)比Atlas)

首先來(lái)精確理解一下這兩個(gè)詞,依作者回復(fù)

They are very related to each other
Connection pool is a cache of connections that can be reused.
Multiplexing is a technique to reuse these connections.

后期逐漸了解到了proxysql的multiplexing。連接池是一個(gè)共享的池子里面有跟后端創(chuàng)建好的一些連接,一個(gè)服務(wù)端腳本的執(zhí)行過(guò)程中可能有多次sql請(qǐng)求:

  • atlas的連接池:從連接池中分配一條連接,在整個(gè)腳本執(zhí)行期間一直占有并使用該連接直到腳本執(zhí)行完畢,然后將連接歸還連接池
  • 而proxysql的連接池:腳本執(zhí)行過(guò)程中的每次sql請(qǐng)求都經(jīng)歷一次分配連接----使用----歸還的過(guò)程

很顯然,對(duì)于連接池的使用效率上來(lái)說(shuō),理論上多數(shù)情況下proxysql的方式會(huì)更加高效并且與DB間維護(hù)的鏈接數(shù)量會(huì)更少

測(cè)試場(chǎng)景:

10條`select * from test.test_table`,10條`select @@hostname`;
ProxySQL/Atlas IP 192.168.1.35;兩個(gè)讀節(jié)點(diǎn)IP分別為192.168.1.37和192.168.1.38;
每次測(cè)試完之前重啟ProxySQL/Atlas;

分兩次測(cè)試,第一次測(cè)試腳本如下(每條命令一次連接)

!#/bin/sh
for i  in {1..10};do
    mysql -uuser -p'passwd' -P6033 -h292.168.1.35 -e "select @@hostname;"    #select @xxx,會(huì)禁用multiplexing
done
for i  in {1..10};do
    mysql -uuser -p'passwd' -P6033 -h292.168.1.35 -e "select id from test.test_table;"    #普通查詢(xún)
done

第二次測(cè)腳本如下(一次連接,執(zhí)行所有命令)

for i in {1..10};do
    query1 += 'select @@hostname;'    #select @xxx,會(huì)禁用multiplexing
    query2 += 'select id from test.test_table;'    #普通查詢(xún)
done
echo $query1$query2 | mysql -uuser -p'passwd' -P6033 -h292.168.1.35

對(duì)ProxySQL進(jìn)行測(cè)試分析
通過(guò)tcpdump抓包wireshark分析,通過(guò)ProxySQL對(duì)20條查詢(xún)的路由情況及其和后端MySQL之間的建立連接情況(通過(guò)ProxySQL上的原端口號(hào))來(lái)分析連接池和禁用multiplexing的情況。結(jié)果匯總?cè)缦?/p>

第一次測(cè)試(每條命令一次連接)

select @xxx          #會(huì)禁用multiplexing
                     1.35源端口
    1.35---->1.37    42094 42096 42097 42099 42102    (轉(zhuǎn)發(fā)5次)
    1.35---->1.38    37971 37974 37976 37977 37979    (轉(zhuǎn)發(fā)5次)

普通查詢(xún)
                     1.35源端口
    1.35---->1.37    42105    (轉(zhuǎn)發(fā)3次)
    1.35---->1.38    37980    (轉(zhuǎn)發(fā)7次)                

第二次測(cè)試(一次連接,執(zhí)行所有命令)

select @xxx          #會(huì)禁用multiplexing
                     1.35源端口
    1.35---->1.37             (轉(zhuǎn)發(fā)0次)
    1.35---->1.38    37817    (轉(zhuǎn)發(fā)10次)

普通查詢(xún)
                     1.35源端口
    1.35---->1.37             (轉(zhuǎn)發(fā)0次)
    1.35---->1.38    37817    (轉(zhuǎn)發(fā)10次)                

對(duì)比來(lái)看Atlas的分時(shí)分析
第一次測(cè)試(每條命令一次連接)

select @xxx          
                     1.35源端口
    1.35---->1.37                                     (轉(zhuǎn)發(fā)0次)
    1.35---->1.38    38405 38407 38409 38411 38413    (轉(zhuǎn)發(fā)10次)
                     38415 38417 38419 38421 38423
普通查詢(xún)
                     1.35源端口
    1.35---->1.37                                     (轉(zhuǎn)發(fā)0次)
    1.35---->1.38    38385 38387 38389 38391 38393    (轉(zhuǎn)發(fā)10次)
                     38395 38397 38399 38401 38403

第二次測(cè)腳本如下(一次連接,執(zhí)行所有命令)

select @xxx          
                     1.35源端口
    1.35---->1.37    42435    (轉(zhuǎn)發(fā)5次)
    1.35---->1.38    38312    (轉(zhuǎn)發(fā)5次)

普通查詢(xún)
                     1.35源端口
    1.35---->1.37    42435    (轉(zhuǎn)發(fā)5次)
    1.35---->1.38    38312    (轉(zhuǎn)發(fā)5次)

由上面測(cè)試分析結(jié)果可以明顯的看到

ProxySQL的負(fù)載均衡策略是基于權(quán)重的輪詢(xún),但并不是嚴(yán)格的逐條輪詢(xún)。而且可以看到在一次連接之內(nèi):由于某些語(yǔ)句(select @xx 或者prepare語(yǔ)句)導(dǎo)致ProxySQL自動(dòng)關(guān)閉multiplexing之后,在本次鏈接之后的所有語(yǔ)句都會(huì)被路由到同一臺(tái)MySQL

atlas做的僅僅是輪詢(xún)轉(zhuǎn)發(fā),他不會(huì)去區(qū)分查詢(xún)類(lèi)型(例如有些查詢(xún)是要路由到后端唯一的MySQL)
而且,在`第一次測(cè)試(每條命令一次連接)`中,atlas將所有的20條請(qǐng)求都路由到了1.38這臺(tái)MySQL,并且每次都要新建連接(并沒(méi)有用到其連接池)

六、proxysql對(duì)后端server健康檢查

  1. 可以主動(dòng)

    來(lái)看一下其相關(guān)參數(shù):
    | mysql-monitor_enabled                  | true                            |
    | mysql-monitor_history                  | 600000                          |
    | mysql-monitor_connect_interval         | 120000                          |
    | mysql-monitor_connect_timeout          | 200                             |
    | mysql-monitor_ping_interval            | 60000                           |
    | mysql-monitor_ping_max_failures        | 3                               |
    | mysql-monitor_ping_timeout             | 100                             |

    這兩種檢測(cè)的區(qū)別,據(jù)作者回復(fù)和抓包分析,總結(jié)如下:

    Pingis done using mysql_ping()  
        通過(guò)抓包分析,是通過(guò)現(xiàn)有的鏈接(連接池中)發(fā)送一個(gè)Request Ping語(yǔ)句  
    Connectis done using mysql_real_connect()  
        這是一個(gè)客戶(hù)端到云服務(wù)器建立鏈接,登錄,退出登錄,關(guān)閉鏈接的完整過(guò)程

    這兩個(gè)函數(shù)的返回值不同,可以幫助proxysql理解與后端鏈接除了哪些問(wèn)題。

    模擬場(chǎng)景,驗(yàn)證以上各設(shè)置并加深理解其故障檢測(cè)機(jī)制:
    兩個(gè)前提

    1. 在web1和web5在proxysql均為online狀態(tài)下;
    2. 無(wú)客戶(hù)端訪問(wèn)ProxySQL,即只驗(yàn)證monitor模塊的行為

    修改web1 MySQL配置文件中max_connections = 3;重啟web1 MySQL,在其他tty打開(kāi)幾個(gè)MySQL鏈接以確保proxysql無(wú)法鏈接該MySQL。同時(shí)在proxysql server上打開(kāi)抓包功能tcpdump -i em2 host 192.168.1.4 and port 3306 -w /tmp/web_shun.pcap,然后通過(guò)wireshark對(duì)比上面各值進(jìn)行分析。  
    附件:數(shù)據(jù)包文件

    通過(guò)分析可驗(yàn)以以下設(shè)置的有效性

    mysql-monitor_connect_interval
    mysql-monitor_ping_interval
    mysql-monitor_ping_max_failures
    mysql-shun_recovery_time_sec
    mysql-ping_interval_server_msec
  2. 可以被動(dòng)

    被動(dòng)就是將全局變量‘mysql-monitor_enabled’置為false,這種情況下,后端server故障后,proxysql不會(huì)主動(dòng)探知,而是在有請(qǐng)求被“正?!甭酚傻皆搒erver之后才會(huì)在runtime層更改該server狀態(tài)為‘SHUNNED’ 或者重新變?yōu)椤甇NLINE’。這個(gè)過(guò)程,應(yīng)用無(wú)感知(表現(xiàn)為mysql-client命令和sysbench均無(wú)報(bào)錯(cuò))
    相關(guān)變量為

    | mysql-shun_on_failures                 | 5                               |
    | mysql-shun_recovery_time_sec           | 60                              |
    | mysql-query_retries_on_failure         | 1                               |
    | mysql-connect_retries_on_failure       | 5                               |
    | mysql-connect_retries_delay            | 1                               |
    | mysql-connection_max_age_ms            | 0                               |
    | mysql-connect_timeout_server           | 1000                            |
    | mysql-connect_timeout_server_max       | 10000                           |

    ###七、關(guān)于proxysql和mysql中的最大連接數(shù)
    首先明確下MySQL中的最大連接數(shù)由max_connections變量控制,proxysql中的最大連接數(shù)有兩個(gè)方面的設(shè)置mysql_users.max_connectionsmysql_servers.max_connections

下面就直接說(shuō)下我的結(jié)論摘自我github上的issue

  1. if the mysql_servers.max_connections is reached, some of the connections will wait until the mysql-connect_timeout_server_max is reached. then proxysql will return error message SQLSTATE[HY000]: General error: 9001 Max connect timeout reached while reaching hostgroup 1 after 10000ms.
  2. if the mysql_users.max_connections is reached, then the client will see the error message 1040: Too many connections
  3. If backend's global variable 'max_connections' is reached and proxysql has no ConnFree with the backend, then client can accomplish the connection with proxysql but all queries will return ERROR 1040 (#HY00): Too many connections, and the monitor will consider this backend is shun and will be loged to the proxysql.log

###八、據(jù)我所知的bug和不足
bug:

  1. 對(duì)于prepare語(yǔ)句(Prepared Statements in Application Programs,見(jiàn)上文解釋。例如laravel框架的prepare語(yǔ)句),如果在backend上更改了表結(jié)構(gòu),在一些情況下會(huì)導(dǎo)致proxysql返回如下錯(cuò)誤  
    SQLSTATE[HY000]: General error: 2057 A stored procedure returning result sets of different size was called. This is not supported by libmysql
  2. 對(duì)于prepare語(yǔ)句的set names xxx語(yǔ)句還不能有效處理
  3. 對(duì)于非prepare語(yǔ)句的set names xxx collate xxxx還不能有效處理
    不足:
  4. 前后端賬號(hào)分離:可以多個(gè)frontend用戶(hù)對(duì)應(yīng)一個(gè)或少數(shù)banckend用戶(hù),簡(jiǎn)化后端MySQL上的授權(quán)操作,尤其是項(xiàng)目多而且之間庫(kù)表關(guān)聯(lián)較緊密時(shí);還能將前端用戶(hù)和stats中相關(guān)表或者錯(cuò)誤日志關(guān)聯(lián),非常方便的在眾多接入到ProxySQL的項(xiàng)目中定位到異常項(xiàng)目。
  5. 錯(cuò)誤日志中對(duì)于SQL類(lèi)錯(cuò)誤只記錄了SQL語(yǔ)句和MySQL返回的錯(cuò)誤信息,沒(méi)有關(guān)聯(lián)到用戶(hù)和庫(kù)表,在眾多項(xiàng)目中僅憑一條SQL語(yǔ)句去尋找源頭難度可想而知(其實(shí)這個(gè)跟第一條是有關(guān)聯(lián)的)。
  6. 通過(guò)admin接口進(jìn)行管理時(shí),在作出多處修改時(shí),無(wú)法一次性將修改應(yīng)用到內(nèi)存,也無(wú)法一次性將所有修改保存至磁盤(pán)。例如對(duì)mysql_servers, mysql_users,mysql_query_rules都做了修改,就得分別使這三個(gè)方面的更改生效和保存至磁盤(pán)。反過(guò)來(lái)同理,假如做了一些更改但是最終想丟棄這些更改也無(wú)法方便的將其回復(fù)到修改之前的狀態(tài)。

###總結(jié)
穩(wěn)定性方面:目前我們已經(jīng)部分業(yè)務(wù)切換到了ProxySQL上,運(yùn)行一直穩(wěn)定,未遇到cpu負(fù)載高或者占用內(nèi)存多等情況。

運(yùn)維/DBA友好:借助于ProxySQL的錯(cuò)誤日志,我們發(fā)現(xiàn)了之前沒(méi)注意到的一些SQL問(wèn)題(如主鍵重復(fù)類(lèi)的問(wèn)題等)。還通過(guò)stats庫(kù)里的相關(guān)表定位了一些問(wèn)題。

性能方面:也強(qiáng)于atlas(參見(jiàn)文章)

個(gè)人覺(jué)得,解決掉上述幾點(diǎn)bug和不足的話(且不說(shuō)可能會(huì)出現(xiàn)的其他feature),ProxySQL就會(huì)更加強(qiáng)大和完美。

對(duì)于以上關(guān)于ProxySQL亮點(diǎn)、安裝、配置及測(cè)試等解析,如果大家還有更多需要了解的可以持續(xù)關(guān)注我們創(chuàng)新互聯(lián)的行業(yè)推新,如需獲取專(zhuān)業(yè)解答,可在官網(wǎng)聯(lián)系售前售后的,希望該文章可給大家?guī)?lái)一定的知識(shí)更新。


當(dāng)前題目:ProxySQL亮點(diǎn)、安裝、配置及測(cè)試等解析
文章路徑:http://weahome.cn/article/gdjphi.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部