ProxySQL實(shí)現(xiàn)MySQL讀寫分離

之前我們已經(jīng)介紹了MySQL的高可用

這樣我們至少保證了我們的服務(wù)不會(huì)因?yàn)镸ySQL掛掉而不能使用,不過按照之前的配置我們?cè)L問的時(shí)候依然訪問的是單個(gè)節(jié)點(diǎn),接下來我們就要想辦法為節(jié)點(diǎn)分擔(dān)壓力了,本文介紹的方案是:使用ProxySQL實(shí)現(xiàn)MySQL讀寫分離

ProxySQL是一個(gè)讀寫分離的中間件,開源項(xiàng)目,優(yōu)勢(shì)是強(qiáng)大的規(guī)則引擎、支持在線配置州疾、支持負(fù)載均衡,詳情可以參考官方文檔

ProxySQL還支持prepare皇拣、query cache严蓖、連接池,這些特性不在本文的介紹范圍內(nèi)

這里需要說明一下,讀寫分離方案是要看實(shí)際場(chǎng)景的颗胡。
如果對(duì)數(shù)據(jù)實(shí)時(shí)性要求極高毫深,例如訂單系統(tǒng),是不適合讀寫分離方案的杭措,因?yàn)樽x數(shù)據(jù)節(jié)點(diǎn)同步寫數(shù)據(jù)節(jié)點(diǎn)的數(shù)據(jù)是有一定時(shí)間差的费什。
當(dāng)然也不是就不能用,只是針對(duì)這種場(chǎng)景需要單獨(dú)設(shè)置此時(shí)讀數(shù)據(jù)和寫數(shù)據(jù)使用同一節(jié)點(diǎn)

下面介紹一下ProxySQL的安裝和配置

說明一下服務(wù)器情況:

1. 一共三臺(tái)服務(wù)器手素,系統(tǒng)ubuntu16.04 64位
2. IP分別為:192.168.1.222鸳址、192.168.1.223、192.168.1.224泉懦,均安裝了MySQL5.7
3. 222為master節(jié)點(diǎn)稿黍,223和224都是slave節(jié)點(diǎn)
4. mha-manager裝在223上,三臺(tái)機(jī)器都裝了mha-node

ProxySQL安裝

下載安裝包

wget https://github.com/sysown/proxysql/releases/download/v1.4.9/proxysql_1.4.9-dbg-ubuntu16_amd64.deb

安裝

dpkg -i proxysql_1.4.9-dbg-ubuntu16_amd64.deb

啟動(dòng)服務(wù)

service proxysql start

ProxySQL配置

ProxySQL的配置是支持兩種方式的:配置文件崩哩,數(shù)據(jù)庫

數(shù)據(jù)庫的配置方式在第一次啟動(dòng)服務(wù)的時(shí)候也是基于配置文件的(/etc/proxysql.cnf)巡球,后續(xù)所有的配置都是在SQLLite中進(jìn)行,并且不會(huì)更新proxysql.cnf配置文件邓嘹,配置是存儲(chǔ)在/var/lib/proxysql/proxysql.db中

前面提到的在線配置就是基于數(shù)據(jù)庫的酣栈,所以這里我們就講解在數(shù)據(jù)庫中的配置方式

1. 創(chuàng)建服務(wù)賬號(hào)和monitor賬號(hào)

登錄master數(shù)據(jù)庫

mysql mysql -u root -p

添加賬號(hào)并授權(quán)

GRANT ALL ON *.* TO 'proxysql'@'192.168.1.%' IDENTIFIED BY 'proxysql';
GRANT SELECT ON *.* TO 'monitor'@'192.168.1.%' IDENTIFIED BY 'monitor';

要先創(chuàng)建兩個(gè)數(shù)據(jù)庫賬號(hào)用于后續(xù)配置,其中proxysql用于操作數(shù)據(jù)庫汹押,monitor用于監(jiān)控

2. 登錄到proxysql管理端

proxysql管理端口默認(rèn)是6032矿筝,默認(rèn)的用戶名密碼都是admin。

mysql -uadmin -padmin -h127.0.0.1 -P6032

3. 查看數(shù)據(jù)庫信息

mysql> show databases;
+-----+---------------+-------------------------------------+
| seq | name          | file                                |
+-----+---------------+-------------------------------------+
| 0   | main          |                                     |
| 2   | disk          | /var/lib/proxysql/proxysql.db       |
| 3   | stats         |                                     |
| 4   | monitor       |                                     |
| 5   | stats_history | /var/lib/proxysql/proxysql_stats.db |
| 6   | myhgm         |                                     |
+-----+---------------+-------------------------------------+
6 rows in set (0.00 sec)

main:默認(rèn)數(shù)據(jù)庫棚贾,存放用戶驗(yàn)證窖维、路由規(guī)則等信息。我們要做的配置都是針對(duì)這個(gè)庫的
disk:持久化到硬盤的配置
stats:proxysql運(yùn)行抓取的統(tǒng)計(jì)信息妙痹,如各命令的執(zhí)行次數(shù)铸史、查詢執(zhí)行時(shí)間等
monitor:monitor模塊收集的信息,db的健康情況怯伊、各種檢查等

4. 查看配置表

mysql> show tables;
+--------------------------------------------+
| tables                                     |
+--------------------------------------------+
| debug_levels                               |
| global_variables                           |
| mysql_collations                           |
| mysql_group_replication_hostgroups         |
| mysql_query_rules                          |
| mysql_query_rules_fast_routing             |
| mysql_replication_hostgroups               |
| mysql_servers                              |
| mysql_users                                |
| proxysql_servers                           |
| runtime_checksums_values                   |
| runtime_global_variables                   |
| runtime_mysql_group_replication_hostgroups |
| runtime_mysql_query_rules                  |
| runtime_mysql_query_rules_fast_routing     |
| runtime_mysql_replication_hostgroups       |
| runtime_mysql_servers                      |
| runtime_mysql_users                        |
| runtime_proxysql_servers                   |
| runtime_scheduler                          |
| scheduler                                  |
+--------------------------------------------+
21 rows in set (0.00 sec)

global_variables:各種變量琳轿,包括監(jiān)聽的端口、管理賬號(hào)耿芹、是否禁用monitor等崭篡,詳情可以參考[官方文檔](https://github.com/sysown/proxysql/wiki/Global-variables)
mysql_*:mysql開頭的表就是我們配置要操作的表,具體都是干什么的還是看官方文檔吧猩系,介紹的很細(xì)媚送,后面我會(huì)針對(duì)讀寫分離的配置做介紹
runtime_*:runtime開頭的表是運(yùn)行時(shí)讀的表中燥,不能通過DML語句修改寇甸,我們針對(duì)mysql開頭的表做完配置修改之后,要執(zhí)行**load mysql xxx to runtime**以將對(duì)應(yīng)的配置加載到運(yùn)行時(shí)環(huán)境
注意:當(dāng)執(zhí)行完load語句將配置加載到運(yùn)行時(shí)環(huán)境后,還要執(zhí)行**save mysql xxx to disk**將配置存到硬盤上拿霉,以便下次重啟時(shí)加載吟秩,如果忘記執(zhí)行,當(dāng)重啟時(shí)本次修改的配置會(huì)丟失

5. 添加DB實(shí)例

我們一共有三個(gè)節(jié)點(diǎn)(一個(gè)master兩個(gè)slave)绽淘,要進(jìn)行讀寫分離涵防,這里我們將master設(shè)為寫節(jié)點(diǎn),兩個(gè)slave設(shè)為讀節(jié)點(diǎn)

mysql> insert into mysql_servers(hostgroup_id,hostname,port,weight,max_connections,max_replication_lag,comment) values(1000,'192.168.1.222',3306,1,1000,10,'write group');
Query OK, 1 row affected (0.00 sec)

mysql> insert into mysql_servers(hostgroup_id,hostname,port,weight,max_connections,max_replication_lag,comment) values(2000,'192.168.1.223',3306,1,1000,10,'read group');
Query OK, 1 row affected (0.00 sec)

mysql> insert into mysql_servers(hostgroup_id,hostname,port,weight,max_connections,max_replication_lag,comment) values(2000,'192.168.1.224',3306,1,1000,10,'read group');
Query OK, 1 row affected (0.00 sec)

mysql> select * from mysql_servers;
+--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| hostgroup_id | hostname      | port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment     |
+--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| 1000         | 192.168.1.222 | 3306 | ONLINE | 1      | 0           | 1000            | 10                  | 0       | 0              | write group |
| 2000         | 192.168.1.223 | 3306 | ONLINE | 1      | 0           | 1000            | 10                  | 0       | 0              | read group  |
| 2000         | 192.168.1.224 | 3306 | ONLINE | 1      | 0           | 1000            | 10                  | 0       | 0              | read group  |
+--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
3 rows in set (0.00 sec)

hostgroup_id:一個(gè)角色一個(gè)id沪铭,該表的主鍵是hostgroup_id+hostname+port
hostname:db實(shí)例IP
port:db實(shí)例端口
weight:權(quán)重壮池,如果有多個(gè)相同角色的實(shí)例,會(huì)優(yōu)先選擇權(quán)重高的
status:狀態(tài)
    -ONLINE 正常
    -SHUNNED 臨時(shí)被剔除
    -OFFLINE_SOFT 軟離線狀態(tài)杀怠,不再接受新的連接椰憋,已建立的連接會(huì)等待
    -OFFLINE_HARD 離線,不接收新連接赔退, 已建立的連接也會(huì)強(qiáng)制斷開(宕機(jī)或者網(wǎng)絡(luò)不可用)
max_connections:最大連接數(shù)
max_replication_lag:允許的最大延遲

6. 添加服務(wù)賬號(hào)

mysql> INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('proxysql','proxysql',1000);
Query OK, 1 row affected (0.01 sec)

mysql> select * from mysql_users;
+----------+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+
| username | password | active | use_ssl | default_hostgroup | default_schema | schema_locked | transaction_persistent | fast_forward | backend | frontend | max_connections |
+----------+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+
| proxysql | proxysql | 1      | 0       | 1000              | NULL           | 0             | 1                      | 0            | 1       | 1        | 10000           |
+----------+----------+--------+---------+-------------------+----------------+---------------+------------------------+--------------+---------+----------+-----------------+
1 row in set (0.01 sec)

7. 設(shè)置監(jiān)控賬號(hào)

mysql> set mysql-monitor_username='monitor';
Query OK, 1 row affected (0.00 sec)

mysql> set mysql-monitor_password='monitor';
Query OK, 1 row affected (0.00 sec)

8. 添加規(guī)則

讀寫分離規(guī)則

mysql> insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(1,1,'^SELECT.*FOR UPDATE$',1000,1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(2,1,'^SELECT',2000,1);
Query OK, 1 row affected (0.00 sec)

mysql> select rule_id,active,match_digest,destination_hostgroup,apply from mysql_query_rules;
+---------+--------+----------------------+-----------------------+-------+
| rule_id | active | match_digest         | destination_hostgroup | apply |
+---------+--------+----------------------+-----------------------+-------+
| 1       | 1      | ^SELECT.*FOR UPDATE$ | 1000                  | 1     |
| 2       | 1      | ^SELECT              | 2000                  | 1     |
+---------+--------+----------------------+-----------------------+-------+
2 rows in set (0.00 sec)

9. 完善配置

我們的mysql集群是基于MHA的橙依,master掛掉之后,slave會(huì)提升為新的master硕旗,這個(gè)時(shí)候我們希望proxysql的規(guī)則自動(dòng)變更窗骑,在mysql_servers中增加一條記錄,將新的master的hostname和port添加到寫的hostgroup中

proxysql是支撐這種配置的漆枚,根據(jù)mysql_replication_hostgroups中的數(shù)據(jù)创译,proxysql通過檢測(cè)到各server的read_only值來自動(dòng)為server設(shè)置hostgroup_id

mysql> insert into  mysql_replication_hostgroups (writer_hostgroup,reader_hostgroup,comment) values(1000,2000,'Reading and Writing Separation');
Query OK, 1 row affected (0.00 sec)

mysql> select * from runtime_mysql_replication_hostgroups;
+------------------+------------------+--------------------------------+
| writer_hostgroup | reader_hostgroup | comment                        |
+------------------+------------------+--------------------------------+
| 1000             | 2000             | Reading and Writing Separation |
+------------------+------------------+--------------------------------+
1 row in set (0.01 sec)

10. 將配置加載到運(yùn)行時(shí)

mysql> load mysql users to runtime;
Query OK, 0 rows affected (0.00 sec)

mysql> load mysql servers to runtime;
Query OK, 0 rows affected (0.00 sec)

mysql> load mysql query rules to runtime;
Query OK, 0 rows affected (0.00 sec)

mysql> load mysql variables to runtime;
Query OK, 0 rows affected (0.00 sec)

mysql> load admin variables to runtime;
Query OK, 0 rows affected (0.00 sec)

11. 將配置保存到硬盤

mysql> save mysql users to disk;
Query OK, 0 rows affected (0.15 sec)

mysql> save mysql servers to disk;
Query OK, 0 rows affected (0.33 sec)

mysql> save mysql query rules to disk;
Query OK, 0 rows affected (0.36 sec)

mysql> save mysql variables to disk;
Query OK, 96 rows affected (0.09 sec)

mysql> save admin variables to disk;
Query OK, 32 rows affected (0.09 sec)

到此讀寫分離的相關(guān)配置就大功告成了!之后我們的應(yīng)用可以通過配置中配置proxysql用戶連接proxysql服務(wù)操作我們的mysql集群

mysql -uproxysql -pproxysql -h 127.0.0.1 -P 6033
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末浪读,一起剝皮案震驚了整個(gè)濱河市昔榴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碘橘,老刑警劉巖互订,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異痘拆,居然都是意外死亡仰禽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門纺蛆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吐葵,“玉大人,你說我怎么就攤上這事桥氏∥虑停” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵字支,是天一觀的道長(zhǎng)凤藏。 經(jīng)常有香客問我奸忽,道長(zhǎng),這世上最難降的妖魔是什么揖庄? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任栗菜,我火速辦了婚禮,結(jié)果婚禮上蹄梢,老公的妹妹穿的比我還像新娘疙筹。我一直安慰自己,他們只是感情好禁炒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布而咆。 她就那樣靜靜地躺著,像睡著了一般幕袱。 火紅的嫁衣襯著肌膚如雪翘盖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天凹蜂,我揣著相機(jī)與錄音馍驯,去河邊找鬼。 笑死玛痊,一個(gè)胖子當(dāng)著我的面吹牛汰瘫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播擂煞,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼混弥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了对省?” 一聲冷哼從身側(cè)響起蝗拿,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蒿涎,沒想到半個(gè)月后哀托,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡劳秋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年仓手,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玻淑。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嗽冒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出补履,到底是詐尸還是另有隱情添坊,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布箫锤,位于F島的核電站贬蛙,受9級(jí)特大地震影響驰弄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜速客,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望五鲫。 院中可真熱鬧溺职,春花似錦、人聲如沸位喂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽塑崖。三九已至七冲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間规婆,已是汗流浹背澜躺。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抒蚜,地道東北人掘鄙。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像嗡髓,于是被迫代替她去往敵國(guó)和親操漠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容