前言
這篇文章是搭建高可用,高負載的第二篇。來學習的是搭建Mysql數據庫集羣,使其能夠在模擬高併發的情況下,在其中的一些Mysql結點宕機的情況下也能夠正常的訪問,不會因爲一個結點的宕機,就不能夠再提供服務。在上一篇文章中講到的是環境的搭建,具體參看linux環境搭建,裏面詳細講解了環境的搭建,有需要的可以移步去看那篇文章。
正文
選擇哪一種搭建集羣的方式
對於mysql來說有兩種搭建集羣的方法:Replication與PXC,如下圖所示:
對於第一種情況的Replication弱一致性表示是對於當前結點的數據,在集羣中的另外一個結點並不一定能夠訪問到,所以一般也都是價值比較低的數據。對於PXC來說實現的是強一致性,表示對於任意結點中的數據在其他的結點中也都能夠訪問到。對於阿里的服務器集羣,及當下的主流網站,對於數據庫集羣的搭建都是採用第二種方法,下面來看具體的信息。
PXC
對於數據的同步是雙向的,數據在每一個結點上面都可以進行讀寫。
同步複製,事務在所有集羣節點要麼同時提交,要麼不提交
Replication
對於數據的同步是單向的,就是例如我們在名爲Master的結點上寫入數據,對於Slave結點上可以讀取到Master寫入的數據,但是對於在Slave上寫入的數據,在Master就不能讀取到。
安裝docker
既然是要在Docker上配置mysql數據庫集羣,這裏就先在linux服務器上安裝Docker(這裏說明以下對於dockers也是虛擬機,VM也是虛擬機,爲什麼說不使用到VM進行虛擬環境的搭建,然後搭建數據庫集羣? 因爲對於VM來說是重量級的,對於Docker來說是輕量級的。對於VM每一個Vm虛擬機都是切實佔用內存空間。但是對於Docker來說多個docker虛擬機來共享分配的空間大小,基礎的配置不變,只是在其上進行了進一步的封裝,更加便捷與易於管理與維護)
Docker操作的基本命令
- 先更新軟件包,其中的
-y
表示確定的意思
yum -y update
- 安裝Docker虛擬機。-y也表示確定意思。
yum install -y docker
- 運行、重啓、關閉Docker虛擬機
service docker start
service docker restart
service docker stop
- 搜索鏡像
docker search 鏡像名稱
eg: docker search java
注意: 這裏直接使用Docker的源鏡像在國外可能會很慢,所以我們這裏使用國內比較好的加速器進行加速。
DaoCloud跳轉鏈接
複製以下代碼進入到linux環境下運行,注意若是無法複製,使用XShell連接複製運行。
運行成功以後,輸入命令 vi /etc/docker/daemon.json
,將下圖第一行最後的,
去掉。然後重新啓動docker
輸入service docker restart
。
5. 下載鏡像
docker pull 鏡像名稱
- 查看鏡像
docker images
- 刪除鏡像
docker rmi 鏡像名稱
- 運行容器
docker run 啓動參數 鏡像名稱
- 查看容器列表
docker ps -a
- 停止、掛起、恢復容器
docker stop 容器ID
docker pause 容器ID
docker unpase 容器ID
- 查看容器信息
docker inspect 容器ID
12.刪除容器
docker rm 容器ID
- 數據卷管理
docker volume create 數據卷名稱 #創建數據卷
docker volume rm 數據卷名稱 #刪除數據卷
docker volume inspect 數據卷名稱 #查看數據卷
- 網絡管理
docker network ls 查看網絡信息
docker network create --subnet=網段 網絡名稱
docker network rm 網絡名稱
- 避免VM虛擬機掛起恢復之後,Docker虛擬機斷網
vi /etc/sysctl.conf
- 文件中添加
net.ipv4.ip_forward=1
這個配置
#重啓網絡服務
systemctl restart network
安裝PXC集羣
- 前面我們提到我們使用PXC進行集羣的搭建,所以先要對PXC鏡像進行安裝。
docker pull percona/percona-xtradb-cluster
2. 爲鏡像更改名字:
docker tag percona/percona-xtradb-cluster pxc
3. 創建net1網段
docker network create --subnet=172.18.0.0/16 net1
-
創建5個數據卷
docker volume create --name v1
docker volume create --name v2
docker volume create --name v3
docker volume create --name v4
docker volume create --name v5
-
創建5節點的PXC集羣
注意,每個MySQL容器創建之後,因爲要執行PXC的初始化和加入集羣等工作,耐心等待1分鐘左右再用客戶端連接MySQL。另外,必須第1個MySQL節點啓動成功,用MySQL客戶端能連接上之後,再去創建其他MySQL節點。
#創建第1個MySQL節點
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql -v backup:/data --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc
#創建第2個MySQL節點
docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v2:/var/lib/mysql -v backup:/data --privileged --name=node2 --net=net1 --ip 172.18.0.3 pxc
#創建第3個MySQL節點
docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v3:/var/lib/mysql --privileged --name=node3 --net=net1 --ip 172.18.0.4 pxc
#創建第4個MySQL節點
docker run -d -p 3309:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v4:/var/lib/mysql --privileged --name=node4 --net=net1 --ip 172.18.0.5 pxc
#創建第5個MySQL節點
docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v5:/var/lib/mysql -v backup:/data --privileged --name=node5 --net=net1 --ip 172.18.0.6 pxc
這個時候,我們就創建了5個SQL節點,我們可以使用本地的Navicat進行測試連接:
此時PXC集羣已經搭建完成,對於在一個數據庫中進行的更改,在其他數據庫中也能夠看得到,這裏我們在db5中添加一個新表student,添加一定的字段:
發現在db3
中,可以看到也有對應的更改。
負載均衡
至於搭建負載均衡,可能很多小夥伴想到的是使用nginx進行負載均衡的搭建,這裏來進行一個對比:對於Tcp/IP協議Haprosy已經成功運行了很多年,但是對於Nginx來說纔剛剛開始支持,並且對於Haproxy支持的類型也比較多和穩定。
對於以上PXC集羣已經搭建完成,這個時候就可以將數據進行同步。但是對於數據庫上線以後,我們不能夠將所有的數據請求打在同一個節點的上面,既然集羣已經搭建完成,我們就需要讓所有的節點都參與到數據的讀寫中,在數據請求到達時候要均勻的分佈到每一個結點,所以就需要使用到負載均衡,將所有的節點都能夠承擔數據的訪問請求。
- 安裝Haproxy鏡像
docker pull haproxy
- 使用
配置文件如下:
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
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200427222412956.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDAxNTA0Mw==,size_16,color_FFFFFF,t_70)
#日誌中不記錄負載均衡的心跳檢測記錄
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
- 創建兩個Haproxy容器
#創建第1個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
#進入h1容器,啓動Haproxy
docker exec -it h1 bash
haproxy -f /usr/local/etc/haproxy/haproxy.cfg
#創建第2個Haproxy負載均衡服務器
docker run -it -d -p 4003:8888 -p 4004:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h2 --privileged --net=net1 --ip 172.18.0.8 haproxy
#進入h2容器,啓動Haproxy
docker exec -it h2 bash
haproxy -f /usr/local/etc/haproxy/haproxy.cfg
完成以上以後我們就可以開始進行本地的驗證驗證是否成功。前面提到了映射到本地的4001端口,就是說由Docker虛擬機的8888端口映射到linux虛擬機的4001端口,然後我們在本地進行連接的訪問處理:
輸入http://XXX.XXX.2.34/4001/dbs 發現對於以下的五個節點都有正常的運行。
然後我們使用以下語句,掛掉一個結點docker stop node1
再次查看情況。發現Mysql_1已經停止運行。
這個時候,在本地進行連接:
然後在h1中進行一個更改,會發現對於其他的數據庫連接也會有相對應的更改(除去db1,因爲前面我們已經把db1給停掉)。
通過以上的操作我們就暫時完成了對多個數據庫進行了集羣的搭建,使用到的是PXC,數據的強一致性。但是對於我們有了數據庫集羣,我們訪問時候還是會訪問到同一個節點,所以需要使用到負載均衡,使得我們搭建的數據庫集羣,在面對數據請求時候,能夠將請求分佈在各個節點之上,減少單個結點的壓力。
雙機熱備
前面我們提到使用到了Haproxy技術實現了負載均衡,但是情況如下圖所示:對於前端發送過來的請求通過Haproxy將請求數據分發確實能夠降低每一個數據庫實例的負載,但是若是Haproxy直接出現了故障,前端發起的請求就根本不可能到達後端的數據庫,所以對於一個Haproxy不能夠成爲我們的瓶頸,還是要設置多個Haproxy實現雙機熱備。
想要實現雙機熱備技術我們需要先了解一個知識點就是虛擬IP。
在linux的網卡中可以設置多個虛擬ip地址,然後將這些ip地址分配給對應的程序。
具體實現細節
- 首先我們需要先定義對應的虛擬ip,然後將兩個Haproxy定義在兩個容器中,這裏使用到了
KeepAlived
,將Haproxy存放在這兩個容器中,此時這兩個容器來搶佔設置的虛擬Ip,如下圖所示:對應的兩個KeepAlived
誰先搶到虛擬ip就被認定爲是主服務器,對於備用服務器會和主服務器之間進行心跳檢測,如果備用服務器沒有收到主服務器的心跳檢測響應,就意味着主服務器可能出現了故障,這個時候備用服務器就可以去搶用虛擬IP。
- 以上我們介紹了雙機熱備的實現原理,現在來整體觀看一下具體的實現流程:
- 首先最右邊是數據庫集羣,就是我們在最開始搭建的五個數據庫結點的集羣,然後使用到Haproxy實現負載均衡。
- 使用到一個Haproxy進行負載均衡可能就會出現一個Haproxy出現故障時候,對於整個數據庫的集羣都不能夠再訪問,所以需要搭建雙機熱備(兩個Haproxy來實現)使用到Keepalived,搭建容器來搶用虛擬ip地址如下圖中的172.18.0.15。
- 對於這個虛擬ip地址是docker內部的ip地址,需要使用到宿主機的Keepalived來將宿主機的192.168.99.65地址映射到docker內部的虛擬ip地址。
- 此時流程執行是:
- 訪問到節點192.168.99.65時候,keepalived映射到docker內部的*172.18.0.15**。
- 對於這個虛擬ip地址兩個Haproxy容器來搶佔這個ip地址,搶到的是主服務器,沒有搶到的就是備用服務器,兩者之前會開啓心跳檢測,在一個發生故障時候,另外一個能夠及時替補上。
- 最後使用負載均衡訪問數據庫節點,減少單個數據庫結點的壓力。
安裝keepalived
因爲我們有兩個Haproxy,所以要先進入到對應的haproxy中:
- 對應的haproxy節點1
#進入h1容器
docker exec -it h1 bash
#更新軟件包
apt-get update
#安裝VIM
apt-get install vim
#安裝Keepalived
apt-get install keepalived
#編輯Keepalived配置文件(參考下方配置文件)
vim /etc/keepalived/keepalived.conf
# 這裏若是不想下載vim可以使用 cat追加的方式
#啓動Keepalived
service keepalived start
#宿主機執行ping命令
ping 172.18.0.201
將文件內容追加的配置文件中:
進行測試連接:
h1配置文件信息如下:
vrrp_instance VI_1 {
state MASTER
# 對於state的值有兩個屬性有兩個屬性,一個是 MASTER(表示主服務器,對於BACKUP表示備用服務器,我們在配置的時候將兩個值都設置爲MASTER 來共同搶用虛擬ip。)
interface eth0
# 保存到哪一個網卡,是一個虛擬的網卡
virtual_router_id 51
# keepalived 0-255 之間
priority 100
# 權重設置 硬件配置調整數字。
advert_int 1
# 心跳檢測,1 表示1s。
authentication {
auth_type PASS
auth_pass 123456
}
# 心跳檢測登錄到某一個結點。
virtual_ipaddress {
172.18.0.201
}
# 虛擬ip設置 docker內部能看到
}
- 對應的haproxy節點2 (配置如同h1所示,這裏不再進行逐一演示)
#進入h2容器
docker exec -it h2 bash
#更新軟件包
apt-get update
#安裝VIM
apt-get install vim
#安裝Keepalived
apt-get install keepalived
#編輯Keepalived配置文件
vim /etc/keepalived/keepalived.conf
#啓動Keepalived
service keepalived start
#宿主機執行ping命令
ping 172.18.0.201
配置文件內容如下:
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
172.18.0.201
}
}
-
宿主機安裝Keepalived,實現雙擊熱備
#宿主機執行安裝Keepalived yum -y install keepalived #修改Keepalived配置文件 vi /etc/keepalived/keepalived.conf #啓動Keepalived service keepalived start
Keepalived配置文件如下:
進入到/etc/keepalived/keepalived.conf 進行修改如下:vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.99.150 } } virtual_server 192.168.99.150 8888 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 172.18.0.201 8888 { weight 1 } } virtual_server 192.168.99.150 3306 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 172.18.0.201 3306 { weight 1 } }
未完待續