關於Atlas的詳細介紹請訪問:https://github.com/Qihoo360/Atlas/blob/master/README_ZH.mdnode
爲何要使用Atlas?應用程序直連數據庫很差嗎?還要在前面加上一層代理,會不會下降應用的讀寫性能?會不會增長維護管理的成本?我想這是每一個使用atlas以前的疑問。mysql
一、爲何要使用Atlas?git
咱們使用atlas,主要使用它的讀寫分離和從庫負載均衡功能。由於我們這讀業務遠遠多於寫,故採用讀寫分離的架構再合適不過了。以前實現讀寫分離,通常都是經過應用程序實現的,這樣大大增長了開發的難度。而使用atlas,能夠將應用和數據庫分離開來,程序員專一業務邏輯開發便可,數據庫對於應用徹底透明。另外,才用讀寫分離,還能夠增長冗餘,增長了機器的處理能力,對於讀操做爲主的應用,使用讀寫分離能夠確保寫的服務器壓力更小。程序員
二、應用程序直連數據庫很差嗎?還要在前面加上一層代理,會不會下降應用的讀寫性能? github
這裏有人專門的測試過,請參考:https://github.com/Qihoo360/Atlas/wiki/Atlas%E7%9A%84%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95sql
下面經過實驗介紹Atlas的部署實現讀寫分離和從庫負載均衡功能。數據庫
1、Atlas安裝後端
【環境說明】:服務器
默認三臺機器上都已安裝mysql5.6,且主從複製已經配置完成。 角色 主機名 ip地址 功能 主庫 node1 192.168.245.129 (w/r) candidate_master node2 192.168.245.131 (r) 從庫 node3 192.168.245.132 (r)
atlas monitor 192.168.245.133 讀寫分離 vip: 192.168.245.100
一、這裏採用官方推薦的rpm安裝方式,比較簡單,下載rpm包:https://github.com/Qihoo360/Atlas/releases架構
[root@monitor software]# yum install Atlas-2.2.1.el6.x86_64.rpm
安裝的目錄在:/usr/local/mysql-proxy
(1).Atlas只能安裝運行在64位的系統上。
(2).Centos 5.X安裝 Atlas-XX.el5.x86_64.rpm,Centos 6.X安裝Atlas-XX.el6.x86_64.rpm。
(3).後端mysql版本應大於5.1,建議使用Mysql 5.6
二、配置Atlas
Atlas運行須要依賴一個配置文件(test.cnf)。在運行Atlas以前,須要對該文件進行配置。Atlas的安裝目錄是/usr/local /mysql-proxy,進入安裝目錄下的conf目錄,能夠看到已經有一個名爲test.cnf的默認配置文件,咱們只須要修改裏面的某些配置項,不 須要從頭寫一個配置文件。
[mysql-proxy] #帶#號的爲非必需的配置項目 #管理接口的用戶名 admin-username = user #管理接口的密碼 admin-password = pwd #Atlas後端鏈接的MySQL主庫的IP和端口,可設置多項,用逗號分隔 proxy-backend-addresses = 127.0.0.1:3306 #Atlas後端鏈接的MySQL從庫的IP和端口,@後面的數字表明權重,用來做負載均衡,若省略則默認爲1,可設置多項,用逗號分隔 #proxy-read-only-backend-addresses = 127.0.0.1:3305@1 #用戶名與其對應的加密過的MySQL密碼,密碼使用PREFIX/bin目錄下的加密程序encrypt加密,下行的user1和user2爲示例,將其替換爲你的MySQL的用戶名和加密密碼! pwds = user1:+jKsgB3YAG8=, user2:GS+tr4TPgqc= #設置Atlas的運行方式,設爲true時爲守護進程方式,設爲false時爲前臺方式,通常開發調試時設爲false,線上運行時設爲true,true後面不能有空格。 daemon = true #設置Atlas的運行方式,設爲true時Atlas會啓動兩個進程,一個爲monitor,一個爲worker,monitor在worker意外退出後會自動將其重啓,設爲false時只有worker,沒有monitor,通常開發調試時設爲false,線上運行時設爲true,true後面不能有空格。 keepalive = true #工做線程數,對Atlas的性能有很大影響,若是追求Atlas處理SQL請求時的QPS,將event-threads值設置爲CPU個數的2-4倍。若是追求Atlas處理SQL請求的完成時間,將event-threads值設置爲CPU個數便可。 event-threads = 8 #日誌級別,分爲message、warning、critical、error、debug五個級別 log-level = message #日誌存放的路徑 log-path = /usr/local/mysql-proxy/log #SQL日誌的開關,可設置爲OFF、ON、REALTIME,OFF表明不記錄SQL日誌,ON表明記錄SQL日誌,REALTIME表明記錄SQL日誌且實時寫入磁盤,默認爲OFF #sql-log = OFF #慢日誌輸出設置。當設置了該參數時,則日誌只輸出執行時間超過sql-log-slow(單位:ms)的日誌記錄。不設置該參數則輸出所有日誌。 #sql-log-slow = 10 #實例名稱,用於同一臺機器上多個Atlas實例間的區分 #instance = test #Atlas監聽的工做接口IP和端口 proxy-address = 0.0.0.0:1234 #Atlas監聽的管理接口IP和端口 admin-address = 0.0.0.0:2345 #分表設置,此例中person爲庫名,mt爲表名,id爲分表字段,3爲子表數量,可設置多項,以逗號分隔,若不分表則不須要設置該項 #tables = person.mt.id.3 #默認字符集,設置該項後客戶端再也不須要執行SET NAMES語句 #charset = utf8 #容許鏈接Atlas的客戶端的IP,能夠是精確IP,也能夠是IP段,以逗號分隔,若不設置該項則容許全部IP鏈接,不然只容許列表中的IP鏈接 #client-ips = 127.0.0.1, 192.168.1 #Atlas前面掛接的LVS的物理網卡的IP(注意不是虛IP),如有LVS且設置了client-ips則此項必須設置,不然能夠不設置 #lvs-ips = 192.168.1.1
(1)pwds參數加密密碼獲取:
[root@monitor bin]# cd /usr/local/mysql-proxy/bin [root@monitor bin]# ./encrypt root DAJnl8cVzy8=
(2)event-threads設置:
若是追求Atlas處理SQL請求時的QPS,將event-threads值設置爲CPU個數的2-4倍。若是追求Atlas處理SQL請求的完成時間,將event-threads值設置爲CPU個數便可。
(3)Atlas的工做端口
proxy-address項配置,例如proxy-address = 0.0.0.0:1234表明客戶端應該使用1234這個端口鏈接Atlas來發送SQL請求。
(4)Atlas的管理端口
admin-address項配置,例如admin-address = 0.0.0.0:2345表明DBA應該使用2345這個端口鏈接Atlas來執行運維管理操做。
(5)管理接口的用戶名和密碼
admin-username項和admin-password項設置,這兩項是用來進入Atlas的管理界面的,與後端鏈接的MySQL沒有關係,因此能夠任意設置,不須要MySQL在配置上作任何改動。
2、Atlas啓動
進入/usr/local/mysql-proxy/bin目錄,執行下面的命令啓動、重啓或中止Atlas。
(1) ./mysql-proxyd test start,啓動Atlas。
(2) ./mysql-proxyd test restart,重啓Atlas。
(3) ./mysql-proxyd test stop,中止Atlas。
[root@monitor bin]# ./mysql-proxyd test start #查看是否啓動 [root@monitor bin]# ps -ef | grep mysql-proxy root 13451 1 0 01:39 ? 00:00:00 /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conf/test.cnf root 13452 13451 0 01:39 ? 00:00:00 /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conf/test.cnf
這時,atlas已經啓動成功了,先嚐試在atlas本機上鍊接,做爲應用程序能夠鏈接上了。
[root@monitor conf]# /data/mysql/bin/mysql -uroot -proot -h 192.168.245.133 -P1234 -c Warning: Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 5 Server version: 5.0.81-log MySQL Community Server (GPL) Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
dba管理用戶這樣鏈接:
[root@monitor bin]# /data/mysql/bin/mysql -uadmin -padmin -h 127.0.0.1 -P2345
在遠程機器上(內網的同一網段中)用SQLyog客戶端進行鏈接,報錯鏈接不上:ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.245.133' (113)
用戶名和密碼都是對的,在安裝atlas的本機上能夠鏈接上atlas,但是換到別的機器上就不行了,那隻能是端口問題了,是否防火牆阻止了呢?因而在別的機器上測試133機器的1234端口,果真是端口不通:
[root@node3 mysql]# ssh -v -p 1234 root@192.168.245.133 OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * debug1: Connecting to 192.168.245.133 [192.168.245.133] port 1234. debug1: connect to address 192.168.245.133 port 1234: No route to host ssh: connect to host 192.168.245.133 port 1234: No route to host
接下來就好辦了,在atlas機器上執行:iptables -F ,而後就通了,再次經過sqlyog鏈接,解決問題。
[root@node3 mysql]# ssh -v -p 1234 root@192.168.245.133 OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * debug1: Connecting to 192.168.245.133 [192.168.245.133] port 1234. debug1: Connection established.
3、測試讀寫分離
一、中止主從複製:爲了看清inset操做究竟是分配到主庫仍是從庫上
mysql> stop slave; Query OK, 0 rows affected (0.07 sec)
二、鏈接atlas並測試
(1)測試insert操做:
[root@monitor log]# /data/mysql/bin/mysql -uroot -proot -h 192.168.245.133 -P 1234 Warning: Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.0.81-log MySQL Community Server (GPL) Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> insert into backup.test(id) values(3); #測試插入操做 Query OK, 1 row affected (0.02 sec)
而後到主庫上查看:
#這是沒插入以前的數據 (product)root@192.168.245.129 [(none)]> select * from backup.test; +----+ | id | +----+ | 1 | | 2 | | 4 | | 5 | +----+ 4 rows in set (0.10 sec) #插入後,有數據了!神奇吧 (product)root@192.168.245.129 [(none)]> select * from backup.test; +----+ | id | +----+ | 1 | | 2 | | 3 | | 4 | | 5 | +----+ 5 rows in set (0.00 sec)
從庫上的數據依然沒變,說明寫操做只分配到主庫上:
(product)root@127.0.0.1 [backup]> select * from test; +----+ | id | +----+ | 1 | | 2 | | 4 | | 5 | +----+ 4 rows in set (0.00 sec)
(2)測試select操做:爲了效果,保持主庫數據和從庫數據的不一致,以下:
#主庫129上的數據: (product)root@192.168.245.129 [(none)]> select * from a.a1; +----+------+ | id | name | +----+------+ | 1 | a | | 2 | b | +----+------+ 2 rows in set (0.00 sec) #從庫上的數據: (product)root@127.0.0.1 [a]> select * from a.a1; +----+------+ | id | name | +----+------+ | 3 | c | | 4 | d | +----+------+ 2 rows in set (0.00 sec) #在atlas中發送select請求,數據以下: mysql> select * from a.a1; +----+------+ | id | name | +----+------+ | 3 | c | | 4 | d | +----+------+ 2 rows in set (0.02 sec)
有時主從有延時,能夠經過/*master*/將select強制發送到主庫,因爲mysql命令行默認是過濾掉註釋的,須要在鏈接mysql命令行時指定-c參數:
#mysql -c參數介紹 -c, --comments Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments. #鏈接mysql [root@monitor bin]# /data/mysql/bin/mysql -uroot -proot -h 127.0.0.1 -P1234 -c mysql> /*master*/select * from a.a1; +----+------+ | id | name | +----+------+ | 1 | test | | 2 | b | +----+------+ 2 rows in set (0.02 sec) #查看後臺日誌,已經發向主庫了 [11/18/2015 21:31:15] C:127.0.0.1:48380 S:192.168.245.100:3306 OK 15.525 "/*master*/ select * from a.a1"
(3)過濾update和delete不帶where子句:
mysql> update a.a1 set name='test'; ERROR 1105 (07000): Proxy Warning - Syntax Forbidden mysql> update a.a1 set name='test' where id=1; Query OK, 1 row affected (0.02 sec) Rows matched: 1 Changed: 1 Warnings: 0 #後臺日誌顯示:[11/18/2015 21:16:15] C:127.0.0.1:47135 S:192.168.245.100:3306 OK 21.627 "update a.a1 set name='test' where id=1"
(4)特殊sql語句測試:
[11/18/2015 22:47:02] C:192.168.245.1:65459 S:192.168.245.131:3306 OK 9.374 "select * from a.`a1` for update"
從執行日誌能夠發現,這類語句是發向從庫上的。不能保證鎖定master,因此此寫法謹慎使用。
咱們知道,一個存儲過程可能很複雜,裏面可能有各類sql語句,那麼這些語句atlas是怎麼處理的呢?咱們先來建立一個簡單的存儲過程,裏面有delete,select,insert等操做:
DELIMITER $$ CREATE PROCEDURE a.p_test() BEGIN DECLARE cc INT DEFAULT 0; SELECT COUNT(*) INTO cc FROM a.a2; IF cc > 0 THEN DELETE FROM a.a2; END IF; INSERT INTO a.a2(id,NAME) VALUES(1,'a'),(2,'b'),(3,'c'); END$$ DELIMITER ;
查看後臺日誌,建立存儲過程是發向主庫(192.168.245.100)的,我想這個你們都沒有疑問:
[11/18/2015 23:00:21] C:192.168.245.1:65459 S:192.168.245.100:3306 OK 23.551 "create procedure a.p_test() begin DECLARE cc INT DEFAULT 0; select count(*) into cc from a.a2; if cc > 0 then delete from a.a2; end if; insert into a.a2(id,name) values(1,'a'),(2,'b'),(3,'c'); END"
關鍵時刻到來了,那麼執行存儲過程呢?這個時候別忘了開啓主從複製,讓從庫上也有這個存儲過程。執行日誌以下:
[11/18/2015 23:07:48] C:192.168.245.1:65459 S:192.168.245.100:3306 OK 30.336 "call a.p_test()"
【結論】如今知道了吧,在處理存儲過程,不管裏面是否select等,通通的都在主庫上面執行。
對於一些調整參數的語句如set read-only=1;show variables like ...這類語句都是發往從庫上執行的,因此對於這類語句強烈建議鏈接到真正的庫上執行。
[11/18/2015 22:45:12] C:192.168.245.1:65459 S:192.168.245.131:3306 OK 5.872 "SHOW VARIABLES LIKE 'profiling'" [11/18/2015 22:45:12] C:192.168.245.1:65459 S:192.168.245.131:3306 OK 26.542 "SET PROFILING = 1" [11/18/2015 22:45:12] C:192.168.245.1:65459 S:192.168.245.131:3306 OK 2.113 "SET profiling_history_size = 0" [11/18/2015 22:45:12] C:192.168.245.1:65459 S:192.168.245.131:3306 OK 0.833 "SET profiling_history_size = 15" [11/18/2015 22:45:12] C:192.168.245.1:65459 S:192.168.245.131:3306 OK 8.288 "SHOW STATUS" [11/18/2015 22:45:12] C:192.168.245.1:65459 S:192.168.245.131:3306 OK 3.652 "SHOW STATUS"
使用Alter語句操做數據庫的時候,每次操做的都是master.能夠經過atlas的接口發佈DDL語句。
4、Atlas結合MHA測試
因爲咱們數據庫架構是主從複製+MHA實現主庫的高可用。若是主庫掛了,這時atlas怎麼處理呢?通過詳細的測試,大體處理步驟以下:
【說明】
一、主庫上綁定vip,在atlas配置文件中主庫設置爲vip地址,這樣不管主庫怎麼切換,最終的vip不會改變。atlas永遠把vip對應的服務器看成主庫。
二、因爲備用主庫原來是從庫,即在atlas配置文件中是做爲從庫的,故當接管爲主庫時,這時該庫既能夠寫入也能夠讀。故須要手工移除從庫的讀功能。(到管理界面,remove backend idx)
三、若是須要修復原主庫,那麼原主庫做爲新主庫的從庫存在。能夠手工加入atlas中(add slave ip:port)
【結論】:能夠很好的支持MHA切換,可是須要注意以上第2點內容。