〇 Atlas架構(gòu)介紹
Atlas是Qihoo360開發(fā)的一個中間件,位于Client和MySQL Server中間層,可以作為讀寫分離,分庫分表中間件。
對于MySQL Server而言,Atlas像是個Client,而對于Client而言,Atlas則是一個DB server。

〇 實驗結(jié)構(gòu)
OS: CentOS 6.5 64bit
MySQL version: 5.6.30
Master:192.168.1.185
Slave:192.168.1.186
proxy(Atlas):192.168.1.187
客戶端:192.168.1.192
〇?MySQL部分:?
(主從建立步驟略)
主/從上建立具有增刪改查賬號:
GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'dev'@'192.168.1.187' IDENTIFIED BY 'dev';
FLUSH PRIVILEGES;
從庫上可以設(shè)置:
SET GLOBAL read_only=1;
如果該從庫永遠(yuǎn)不用做master,可以寫到配置文件中。
〇?Atlas部分:
Atlas開發(fā)者給出部分建議:
1、Atlas只能運行在64bit的發(fā)行版本上
2、若曾經(jīng)安裝過,在新安裝時會報錯:如“file /usr/local/mysql-proxy/bin/encrypt from install of Atlas-2.0.1-1.x86_64 conflicts with file from package Atlas-1.0.3-1.x86_64”,此時需要sudo rpm –e Atlas-1.0.3-1.x86_64,再執(zhí)行新的安裝。
3、建議使用MySQL 5.6,此外,不宜小于MySQL 5.1
在proxy機上安裝Atlas:
wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm
通過rpm包安裝方式,默認(rèn)的配置文件在
/usr/local/mysql-proxy/conf/test.cnf
首先可以先獲取一下之前步驟中,dev@'192.168.1.187'這個用戶加密后的密碼:
# /usr/local/mysql-proxy/bin/encrypt dev
A2OS3vFVUmY=
因為之前給dev用戶的密碼的明文是dev,所以此處也對dev加密,加密后的密碼輸出在其后,也就是A2OS3vFVUmY=這個密碼稍后要添加到Atlas配置文件中。
test.cnf配置文件內(nèi)容可以參考這個:
[mysql-proxy]
# 基礎(chǔ)設(shè)置
# 以守護(hù)進(jìn)程方式啟動?
daemon = true
#?設(shè)置atlas的運行方式,若為true,則表示多一個monitor,該進(jìn)程會在woker進(jìn)程掛掉后將其重啟。若為false,則只有一個工作進(jìn)程woker。
keepalive = true
# atlas實例名,便于區(qū)分一臺機子上的不同atlas
instance = test
# 工作線程數(shù),atlas開發(fā)人員推薦將其設(shè)置為CPU個數(shù)的2~4倍。
event-threads = 8
# SQL日志的開關(guān),共有三個可選項:OFF、ON、REALTIME,分別為:不記錄sql日志、記錄sql日志,并等待緩沖區(qū)填滿后,才會落地到磁盤、記錄sql日志并實時寫入磁盤。
sql-log = OFF
# 等同于客戶端連接到mysql-server后輸入SET names utf8;
charset = utf8
# 如果這樣配置,可以通過mysql -h127.0.0.1 -P2345 -uadmin -padmin可以連接到Atlas管理界面
admin-username = admin
admin-password = admin
# 該參數(shù)設(shè)置Atlas后臺管理地址和端口
admin-address = 192.168.1.187:2345
# 設(shè)置主庫和從庫的地址,其中主庫為寫庫,從庫為只讀庫
# 主庫地址
proxy-backend-addresses = 192.168.1.185:3306
# 設(shè)置讀庫地址和端口
proxy-read-only-backend-addresses = 192.168.1.186:3306
# 若配置為主庫也分擔(dān)讀請求,并且設(shè)置權(quán)重為 (主:從)=(1:3),則可以寫作
#proxy-read-only-backend-addresses = 192.168.1.185:3306@1, 192.168.1.186:3306@3
# 設(shè)置Atlas工作監(jiān)聽的地址和端口,應(yīng)用程序?qū)⑦B接到這個地址,既然客戶端把Atlas當(dāng)做一個mysql-server,故此處直接寫成3306端口
proxy-address = 192.168.1.187:3306
# 設(shè)置用戶的密碼(這個密碼為MySQL中dev用戶通過Atlas加密程序加密后的密碼),多個可以用逗號隔開
pwds = dev:A2OS3vFVUmY=
# 設(shè)置Atlas日志信息,其中l(wèi)og-level有message、warning、critical、error、debug五個級別
log-level = message
# 日志存放的路徑,日志名為$instance_name.log,比如$log-path/test.log
log-path = /usr/local/mysql-proxy/log
# 設(shè)置允許連接Atlas的客戶端ip,非必須,可以是多個,可以是精準(zhǔn)ip也可以是ip段,比如:
#client-ips = 127.0.0.1, 192.168.1
#?掛接lvs的物理網(wǎng)卡ip,若有l(wèi)vs結(jié)構(gòu),且設(shè)置了client-ips,則必須設(shè)置此項,反之可不設(shè)置。
#lvs-ips = 192.168.1.1?
配置好后,直接啟動就好:
/usr/local/mysql-proxy/bin/mysql-proxyd test start
其中test為配置文件中instance的值。
當(dāng)然可以檢查一下是否已經(jīng)啟動成功:
/usr/local/mysql-proxy/bin/mysql-proxyd?test?status
MySQL-Proxy?of?test?is running?(5176)
MySQL-Proxy?of?test?is running?(5177)
比如這樣就可以連接到Atlas后臺界面:
mysql -h192.168.1.187 -P2345 -uadmin -padmin
進(jìn)去之后可以查看當(dāng)前配置的DBserver和狀態(tài)。
mysql>?SELECT?*?FROM?backends;
+-------------+--------------------+-------+------+
|?backend_ndx?|?address?|?state?|?type?|
+-------------+--------------------+-------+------+
|?1? ? ??|?192.168.1.185:3306?|?up|?rw|
|?2?|?192.168.1.186:3306?|?up|?ro|
+-------------+--------------------+-------+------+
2 rows?in?set?(0.00 sec)
當(dāng)然更多的選項可以通過SELECT * FROM help;來獲?。?/p>
mysql> SELECT * FROM help;
+----------------------------+---------------------------------------------------------+
| command????????????????????| description?????????????????????????????????????????????|????
+----------------------------+---------------------------------------------------------+
| SELECT * FROM help?????????| shows this help?????????????????????????????????????????|
| SELECT * FROM backends????| lists the backends and their state??????????????????????|
| SET OFFLINE $backend_id???| offline backend server, $backend_id is backend_ndx's id |
| SET ONLINE $backend_id????| online backend server, ...??????????????????????????????|
| ADD MASTER $backend???????| example: "add master 127.0.0.1:3306", ...???????????????|
| ADD SLAVE $backend????????| example: "add slave 127.0.0.1:3306", ...????????????????|
| REMOVE BACKEND $backend_id | example: "remove backend 1", ...????????????????????????|
| SELECT * FROM clients??????| lists the clients???????????????????????????????????????|
| ADD CLIENT $client????????| example: "add client 192.168.1.2", ...??????????????????|
| REMOVE CLIENT $client??????| example: "remove client 192.168.1.2", ...???????????????|
| SELECT * FROM pwds????????| lists the pwds??????????????????????????????????????????|
| ADD PWD $pwd?????????? ? ??| example: "add pwd user:raw_password", ...???????????????|
| ADD ENPWD $pwd????????????| example: "add enpwd user:encrypted_password", ...???????|
| REMOVE PWD $pwd???????????| example: "remove pwd user", ...?????????????????????????|
| SAVE CONFIG???????????????| save the backends to config file????????????????????????|
| SELECT VERSION?????????????| display the version of Atlas????????????????????????????|
+----------------------------+---------------------------------------------------------+
其他參數(shù):
sql-log-slow?=?10 # 類似于mysql的long_query_time,如果設(shè)置了該選項,則日志只記錄超過該值的日志記錄,若沒有添加這個參數(shù)選項,則表示全部記錄,單位為ms?
wait-timeout?=?10 # Atlas會關(guān)閉超過該時間之后一直未活躍的連接,單位s
tables?=?db_name.table_name.user_id.100 # 分表設(shè)置,其中格式為:【庫名.表名.分表字段.子表數(shù)量】,若設(shè)置多項則用逗號分隔。注,子表必須已經(jīng)存在,其中子表命名規(guī)則為:【表名_數(shù)字】,范圍為【0,子表數(shù)量-1】,即百表為table_name_0 table_name_1?...?table_name_99。
〇?測試:
為了方便看到請求是否讀寫分離,可以先在master & slave兩個實例上打開general_log,并放入表中:
SET?GLOBAL log_output='TABLE';
SET?GLOBAL general_log=on;
master上創(chuàng)建一張測試表:
master>?CREATE?TABLE?test.a(id?int);
Query OK,?0 rows affected?(0.03 sec)
然后再到客戶端(192.168.1.192)嘗試對Atlas(192.168.1.187)發(fā)起增刪改查請求:
此處寫了一個php腳本來模擬請求:
<?php
$con?=?mysql_connect("192.168.1.187","dev","dev");
if?(!$con){
??die('connect error: '?.?mysql_error());
??}
mysql_select_db("my_db",?$con);
mysql_query("INSERT INTO test.a SELECT 1;");
mysql_query("UPDATE test.a SET id=222 WHERE id=1;");
mysql_query("DELETE FROM test.a WHERE id=222;");
mysql_query("INSERT INTO test.a SELECT 123456;");
mysql_query("SELECT count(1) FROM test.a;");
mysql_close($con);
?>
此處可以通過?yum install -y php php-mysql?來安裝一下php相關(guān)依賴。
執(zhí)行這個php腳本后,可以分別檢查一下master(192.168.1.185)和從庫(192.168.1.186)的general log:
master>?SELECT?user_host,?argument
????->?FROM mysql.general_log?
????->?WHERE user_host='dev[dev] @ [192.168.1.187]'?;
+-----------------------------+-------------------------------------+
|?user_host?|?argument?|
+-----------------------------+-------------------------------------+
|?dev[dev]?@?[192.168.1.187] ?|?INSERT?INTO?test.a SELECT 1?|
|?dev[dev]?@?[192.168.1.187]|?UPDATE?test.a SET id=222 WHERE id=1?|
|?dev[dev]?@?[192.168.1.187]??|?DELETE FROM?test.a WHERE id=222 ????|
|?dev[dev]?@?[192.168.1.187]|?INSERT?INTO?test.a SELECT 123456 ???|
+-----------------------------+-------------------------------------+
4 rows?in?set?(0.00 sec)
slave>?SELECT user_host,?argument
???->?FROM mysql.general_log?
???->?WHERE user_host='dev[dev] @ [192.168.1.187]'?;
+-----------------------------+-----------------------------+
|?user_host?|?argument|
+-----------------------------+-----------------------------+
|?dev[dev]?@?[192.168.1.187]??|?SELECT count(1)?FROM?test.a?|
+-----------------------------+-----------------------------+
1 rows?in?set?(0.00 sec)
最后再檢查一下跑完這個php腳本后的test.a表的數(shù)據(jù),是否和預(yù)期的一致:
slave> SELECT * FROM test.a;
+--------+
| id ????|
+--------+
| 123456 |
+--------+
1 row in set (0.00 sec)
當(dāng)然,顯然是與預(yù)期一致。
顯然Atlas作為proxy,已經(jīng)將寫請求提交給master(192.168.1.185),將讀請求提交給slave(192.168.1.186)。
對于客戶端和開發(fā)人員,只需要獲取一個Atlas的服務(wù)器地址、端口、用戶名及密碼便可使用讀寫分離。
Atlas也可以實現(xiàn)分表功能,此處可自行翻閱Atlas Home。