一、負載均衡中間件的選擇
上一篇成功搭建了數據庫集羣,但在pxc數據庫集羣中,任何一個節點都是可以讀寫的。
如果pxc集羣上線後,不應該把所有的請求都發送給一個節點,所有節點都應該參與數據請求的處理。
如果想要實現將請求均勻的發送給每個節點,就需要實現負載均衡。
1.1 爲什麼要實現負載均衡?
如果不上線負載均衡,應用服務器將所有請求都發送給一個pxc節點,這個節點壓力特別高,就容易出現崩潰:
因此在結構上就需要進行調整,想要實現需要引入Haproxy技術,Haproxy是一個老牌的中間件產品,Haproxy不是數據庫,它只是一個轉發器而已。使用Haproxy做負載均衡,請求被均勻發送給每個節點,使單節點負載降低,提高性能:
1.2 爲什麼不使用Nginx來實現?
我們都知道Nginx的重要特點就是可以用來實現負載均衡,這裏數據庫節點的負載均衡爲什麼不使用Nginx實現?
對比幾款負載均衡中間件,可以發現:
Nginx對於Http協議的負載均衡支持非常好,但是對於TCP\IP協議的支持並不久。
沒有長久的考驗,不適合貿然在數據庫集羣中來使用Nginx來實現負載均衡。
另外,還有Apache是不支持TCP\IP協議的,
以及,LVS也支持TCP/IP協議的負載均衡,甚至性能更好,但是它不支持在虛擬機上安裝,因此也無法在docker容器中去使用。
二、負載均衡的實現
2.1 拉取haproxy遠程鏡像
docker倉庫中已有haproxy的鏡像,下載即可:
拉取haproxy鏡像 docker pull haproxy
查看鏡像是否拉取成功 docker images
2.2 創建haproxy的配置文件
2.2.1 配置文件部分內容說明
部分重點配置參數說明(這裏只關注和pxc負載均衡有關的部分):
#數據庫負載均衡
listen proxy-mysql
#訪問的IP和端口,表示任何ip地址都可以訪問這個3306的端口。假如有有應用程序向3306端口發送數據庫請求,它就會把請求發送給具體的pxc實例
bind 0.0.0.0:3306
#網絡協議
mode tcp
#負載均衡算法(輪詢算法),請求的轉發算法。
(由於我pxc容器中的mysql數據庫硬件配置都是相同的,因此不需要採用權重算法,當硬件配置不同時才用權重算法給實例分配不同的權重。這裏開啓的是roundrobin,即輪詢算法。)
#輪詢算法:roundrobin
#權重算法:static-rr
#最少連接算法:leastconn
#請求源IP算法:source
balance roundrobin
#日誌的格式
option tcplog
#在MySQL中創建一個沒有權限的haproxy用戶,密碼爲空。Haproxy使用這個賬戶對MySQL數據庫心跳檢測。
option mysql-check user haproxy
#★★★配置具體的負載均衡數據庫節點★★★
#[server] [自定義一個配置信息名] [數據庫節點的ip:容器的端口而不是宿主機的端口] [check(指發送心跳檢測)] [未配置輪詢不會生效的輪詢權重] [最大連接數設置爲2000 可按需自定義]
server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000
server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000
server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000
server MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000
server MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000
#使用keepalive檢測死鏈
option tcpka
2.2.2 完整的配置文件
配置文件如下,可以直接複製到haproxy.cfg中使用。(關於haproxy配置文件的詳細可以參考:https://zhangge.net/5125.html )
global
#工作目錄
chroot /usr/local/etc/haproxy
#日誌文件,使用rsyslog服務中local5日誌設備(/var/log/local5),等級info
log 127.0.0.1 local5 info
#守護進程運行
daemon
defaults
log global
mode http
#日誌格式
option httplog
#日誌中不記錄負載均衡的心跳檢測記錄
option dontlognull
#連接超時(毫秒)
timeout connect 5000
#客戶端超時(毫秒)
timeout client 50000
#服務器超時(毫秒)
timeout server 50000
#監控界面
listen admin_stats
#監控界面的訪問的IP和端口
bind 0.0.0.0:8888
#訪問協議
mode http
#URI相對地址
stats uri /dbs
#統計報告格式
stats realm Global\ statistics
#登陸帳戶信息
stats auth admin:abc123456
#數據庫負載均衡
listen proxy-mysql
#訪問的IP和端口
bind 0.0.0.0:3306
#網絡協議
mode tcp
#負載均衡算法(輪詢算法)
#輪詢算法:roundrobin
#權重算法:static-rr
#最少連接算法:leastconn
#請求源IP算法:source
balance roundrobin
#日誌格式
option tcplog
#在MySQL中創建一個沒有權限的haproxy用戶,密碼爲空。Haproxy使用這個賬戶對MySQL數據庫心跳檢測
option mysql-check user haproxy
server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000
server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000
server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000
server MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000
server MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000
#使用keepalive檢測死鏈
option tcpka
2.2.3 創建haproxy的配置文件
注意先不要去創建haproxy的容器,haproxy的鏡像中是不包含配置文件的,因此需先創建其配置文件。
創建haproxy的配置文件,若目錄不存在需先創建目錄 touch /home/soft/haproxy/haproxy.cfg
將上面貼出的配置文件內容複製進去並保存。
2.3 創建Haproxy容器
創建Haproxy容器:
docker run -it -d -p 4001:8888 -p 4002:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h1 --privileged --net=net1 --ip 172.18.0.7 haproxy
參數說明:
-p 4001:8888 將Haproxy提供的監控界面服務端口8888映射到宿主機的4001端口
-p 4002:3306 將Haproxy提供的數據庫負載均衡的服務端口3306映射到宿主機的4002端口
-v /home/soft/haproxy:/usr/local/etc/haproxy 將宿主機的/home/soft/haproxy目錄映射到容器的/usr/local/etc/haproxy目錄。將來在宿主機的/home/soft/haproxy中放入配置文件,在相映射的容器目錄中就可以使用了。
--name h1 給容器起名,爲了保證Haproxy的高可用,將來也會啓動多個Haproxy容器實例
--privileged 配置權限
--net=net1 使用的網段,數據庫實例使用的都是net1網段,需和數據庫實例使用的網段保持一致
--ip 172.18.0.7 手動分配的ip地址,如不設置,docker虛擬機也會給其分配一個ip地址
haproxy docker run使用的鏡像名
運行結果如圖:
2.4 在haproxy容器中啓動haproxy實例
2.4.1 啓動haproxy實例
由於容器是使用-d做後臺運行的,因此之後還需要進入後臺運行的容器,把haproxy中間件啓動起來。
進入後臺運行的容器:
docker exec -it h1 bash
指定配置文件啓動haproxy實例:
haproxy -f /usr/local/etc/haproxy/haproxy.cfg
運行結果如圖:
2.4.2 創建心跳檢測的用戶賬號
在之前的haproxy配置中配置了一個用於心跳檢測的賬號haproxy。
我們需要在mysql數據庫實例上創建一個叫haproxy的賬號,因爲haproxy中間件要用這個賬號登錄數據庫發送心跳檢測:
2.4.5 查看haproxy監控界面
打開瀏覽器,輸入宿主機ip:4001/dbs,即可查看haproxy的監控界面:
可以看到,其中五個數據庫節點背景色都爲綠,status一項都是UP,也就是說都是穩定運行中。
嘗試停止其中一臺實例node2,運行命令:docker stop node2
刷新再次查看監控界面,可以在監控界面發現node2已經顯示未正常運行:
三、查看haproxy負載均衡功能是否生效
新建連接h1,ip爲宿主機ip,端口爲宿主機的端口(Haproxy服務端口3306映射到宿主機的端口4002,填寫mysql實例的用戶名和密碼。haproxy的庫其實並不會保存數據,只是做請求分發。
打開連接h1,可以看到之前在pxc的mysql實例中創建的test庫和student表。現在對其新增一條數據Jack:
去pxc的node1節點對應的數據庫DB1查看,可以發現jack這條數據已經同步進來:
再查看DB3,也已經存在這條數據了。說明haproxy確實正常運行了: