Docker 搭建mysql 集群


MySQL常用集群方案

前后端系統架構圖

 

了解 MySQL 集群之前,先看看單節點數據庫的弊病

  • 大型互聯網程序用戶群體龐大,所以架構需要特殊設計。

  • 單節點數據庫無法滿足大並發時性能上的要求。

  • 單節點的數據庫沒有冗余設計,無法滿足高可用。

  • 單節點 MySQL無法承載巨大的業務量,數據庫負載巨大

常見 MySQL 集群方案

  •     Repliaction 集群方案

  •     PXC 集群方案( Percona XtraDB Cluster )

兩種集群方案特性如下圖

PXC方案 和 Replication方案對比

PXC方案

很明顯 PXC方案在任何一個節點寫入的數據都會同步到其他節點,數據雙向同步的(在任何節點上都可以同時讀寫)

Replication 集群方案

PXC 數據的強一致性

  • PXC 采用同步復制,事務在所有集群節點要么同時提交,要么不提交。

  • Replication 采用異步復制,無法保證數據的一致性。

PXC寫入操作

當一個寫入請求到達PXC集群中的一個 mysql(node1數據庫) 數據庫時,node1數據庫會將該寫入請求同步給集群中的其他所有數據庫,等待所有數據庫都成功提交事務后,node1節點才會將寫入成功的結果告訴給 node1的客戶端。

PXC 的強一致性對保存高價值數據時特別重要。

在看Replication集群寫入操作:

當一個寫入請求到達 Master數據庫時,Master數據庫執行寫入操作,然后 Master 向客戶端返回寫入成功,同時異步的復制寫入操作給 Slave數據庫,如果異步復制時出現問題,從數據庫將無法執行寫入操作,而客戶端得到的是寫入成功。這也

是弱一致性的體現

創建MySQL PXC集群

1 安裝PXC鏡像

docker pull percona/percona-xtradb-cluster:5.7.21  

2 為PXC鏡像改名

docker tag percona/percona-xtradb-cluster:5.7.21 pxc

 3 創建net1網段

docker network create --subnet=172.18.0.0/16 net1

4 創建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 創建備份數據卷(用於熱備份數據)

 docker volume create --name backup

6 創建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

查看容器運行狀態  

docker container ls

 

 可以發現在任意節點創建的數據都會同步到其他節點

數據庫負載均衡

雖然搭建了集群,但是不使用數據庫負載均衡,單節點處理所有請求,負載高,性能差

 

將請求均勻地發送給集群中的每一個節點。

  • 所有請求發送給單一節點,其負載過高,性能很低,而其他節點卻很空閑。

  • 使用Haproxy做負載均衡,可以將請求均勻地發送給每個節點,單節點負載低,性能好

 負載均衡中間件對比

負載均衡首先是數據庫的集群,加入5個集群,每次請求都是第一個的話,有可能第一個數據庫就掛掉了,所以更優的方案是對不同的節點都進行請求,這就需要有中間件進行轉發,比較好的中間件有nginx,haproxy等,因nginx 支持插件,但是

剛剛支持了tcp/ip 協議,haproxy 是一個老牌的中間轉發件。如果要用haproxy的話,可以從官方下載鏡像,然后呢對鏡像進行配置(自己寫好配置文件,因為這個鏡像是沒有配置文件的,配置好之后再運行鏡像的時候進行文件夾的映射,配置文

件開放3306(數據庫請求,然后根據check心跳檢測訪問不同的數據庫,8888 對數據庫集群進行監控))。配置文件里面設置用戶(用戶在數據庫進行心跳檢測,判斷哪個數據庫節點是空閑的,然后對空閑的進行訪問),還有各種算法(比如

輪訓),最大連接數,時間等,還有對集群的監控。配置文件寫好以后運行這個鏡像,鏡像運行成功后進入容器啟動配置文件 。其實haprocy返回的也是一個數據庫實例(但是並不存儲任何的數據,只是轉發請求),這個實例用來check其他節

點。

 安裝haproxy

參考文檔

https://zhangge.net/5125.html

1 從Docker倉庫拉取haproxy鏡像:https://hub.docker.com/_/haproxy

docker pull haproxy

2 創建Haproxy配置文件。供Haproxy容器使用(docker中未生成配置文件,我們需要在宿主機中自己創建配置文件) 

mkdir /home/soft/haproxy
vi /home/soft/haproxy/haproxy.cfg

 配置信息如下

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  
/home/soft/haproxy/haproxy.cfg

3 在數據庫集群中創建空密碼、無權限用戶haproxy,來供Haproxy對MySQL數據庫進行心跳檢測

create user 'haproxy'@'%' identified by '';

 4 創建Haproxy容器(name=h1的原因是為了高可用) 這里要加 --privileged

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

5 進入容器,在容器bash中啟動Haproxy

docker exec -it h1 bash
haproxy -f /usr/local/etc/haproxy/haproxy.cfg

6 接下來便可以在瀏覽器中打開Haproxy監控界面,端口4001,在配置文件中定義有用戶名admin,密碼abc123456。

我這邊訪問的是http://192.168.163.129:4001/dbs,並且要使用用戶名密碼進行登錄(小插曲,使用的是Basic登錄,我的Chrome不知為何被屏蔽了,我最后用的火狐)  

 這時候我們手動掛掉一個Docker節點,看一下變化(我們會發現已經顯示掛掉了)

docker stop node1 

Haproxy不存儲數據,只轉發數據。可以在數據庫中建立Haproxy的連接,端口4002,用戶名和密碼為數據庫集群的用戶名和密碼(用戶名:root密碼:abc123456)

為什么要采用雙機熱備

單節點Haproxy不具備高可用,必須要有冗余設計

雙機就是兩個請求處理程序,比如兩個haproxy,當一個掛掉的時候,另外 一個可以頂上。熱備我理解就是keepalive。在haproxy 容器中安裝keepalive

 虛擬ip

linux系統可以在一個網卡中定義多個IP地址,把這些地址分配給多個應用程序,這些地址就是虛擬IP,Haproxy的雙機熱備方案最關鍵的技術就是虛擬IP。

關鍵就是虛擬ip,定義一個虛擬ip,然后比如兩個haproxy分別安裝keepalive鏡像,因為haproxy是ubuntu系統的,所以安裝用apt-get,keepalive是作用是搶占虛擬ip,搶到的就是主服務器,沒有搶到的就是備用服務器,然后兩個keepalive進行

心跳檢測(就是創建一個用戶到對方那里試探,看是否還活着,mysql的集群之間也是心跳檢測),如果 掛掉搶占ip。所以在啟動keepalive 之前首先要編輯好他的配置文件,怎么搶占,權重是什么,虛擬ip是什么,創建的用戶交什么。配置完啟

動完以后可以ping一下看是否正確,然后將虛擬ip映射到局域網的ip

 使用keepalive實現雙機熱備

  • 定義虛擬IP

  • 在Docker中啟動兩個Haproxy容器,每個容器中還需要安裝Keepalived程序(以下簡稱KA)

  • 兩個KA會爭搶虛擬IP,一個搶到后,另一個沒搶到就會等待,搶到的作為主服務器,沒搶到的作為備用服務器

  • 兩個KA之間會進行心跳檢測,如果備用服務器沒有受到主服務器的心跳響應,說明主服務器發生故障,那么備用服務器就可以爭搶虛擬IP,繼續工作

  • 我們向虛擬IP發送數據庫請求,一個Haproxy掛掉,可以有另一個接替工作

 haproxy雙機熱備方案

  • Docker中創建兩個Haproxy,並通過Keepalived搶占Docker內地虛擬IP

  • Docker內的虛擬IP不能被外網,所以需要借助宿主機Keepalived映射成外網可以訪問地虛擬IP

1 進入Haproxy容器,安裝Keepalived:  

docker exec -it h1 bash
apt-get update
apt-get install keepalived

2 Keepalived配置文件(Keepalived.conf):

Keepalived的配置文件是/etc/keepalived/keepalived.conf  

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  

service keepalived start

啟動成功后,通過 ip a 可以查看網卡中虛擬IP是否成功,另外可以在宿主機中ping成功虛擬IP  172.18.0.201   

可以按照以上步驟,再另外創建一個Haproxy容器,注意映射的宿主機端口不能重復,Haproxy配置一樣。然后在容器中安裝Keepalived,配置也基本一樣(可以修改優先權重)。這樣便基本實現了Haproxy雙機熱備方案
命令如下:

創建Haproxy容器(name=h2的原因是為了高可用)

docker run -it -d -p 4003:8888 -p 4004:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h2 --net=net1 --ip 172.18.0.8 --privileged haproxy

進入容器,在容器bash中啟動Haproxy

docker exec -it h2 bash
haproxy -f /usr/local/etc/haproxy/haproxy.cfg

接下來便可以在瀏覽器中打開Haproxy監控界面,端口4003,在配置文件中定義有用戶名admin,密碼abc123456。

我這邊訪問的是http://192.168.63.144:4003/dbs,並且要使用用戶名密碼進行登錄(小插曲,使用的是Basic登錄,我的Chrome不知為何被屏蔽了,我最后用的火狐)  

進入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
    }
}  

實現外網訪問虛擬ip

宿主機安裝 keepalive

apt-get update
apt-get install keepalived

Keepalived配置文件(Keepalived.conf):

Keepalived的配置文件是/etc/keepalived/keepalived.conf  

#宿主機執行安裝Keepalived
yum -y install keepalived
#修改Keepalived配置文件
vi /etc/keepalived/keepalived.conf
#啟動Keepalived
service keepalived start

Keepalived配置文件如下:  

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
    }
}

啟動Keepalived服務

service keepalived start
#service keepalived status
#service keepalived stop
  1. 之后其他電腦便可以通過虛擬IP 192.168.63.160 的8888和3306端口來訪問宿主機Docker中的 172.18.0.201 的相應端口。

暫停PXC集群的辦法

vi /etc/sysctl.conf
#文件中添加net.ipv4.ip_forward=1這個配置
systemctl restart network

熱備份數據  

冷備份

  • 冷備份是關閉數據庫時候的備份方式,通常做法是拷貝數據文件

  • 是簡單安全的一種備份方式,不能在數據庫運行時備份。

  • 大型網站無法做到關閉業務備份數據,所以冷備份不是最佳選擇

熱備份

  • 熱備份是在系統運行狀態下備份數據

MySQL常見的熱備份有LVM和XtraBackup兩種方案

  • LVM:linux的分區備份命令,可以備份任何數據庫;但是會對數據庫加鎖,只能讀取;而且命令復雜

  • XtraBackup:不需要鎖表,而且免費

XtraBackup

XtraBackup是一款基於InnoDB的在線熱備工具,具有開源免費,支持在線熱備,占用磁盤空間小,能夠非常快速地備份與恢復mysql數據庫

  • 備份過程中不鎖表,快速可靠

  • 備份過程中不會打斷正在執行地事務

  • 備份數據經過壓縮,占用磁盤空間小

全量備份和增量備份

  • 全量備份:備份全部數據。備份過程時間長,占用空間大。第一次備份要使用全量備份

  • 增量備份: 只備份變化的那部分數據。備份的時間短,占用空間小。第二次以后使用增量備份

PXC全量備份

備份要在某個PXC節點的容器內進行,但應該把備份數據保存到宿主機內。所以采用目錄映射技術。先新建Docker卷:

docker volume create backup

挑選一個PXC節點node1,將其容器停止並刪除,然后重新創建一個增加了backup目錄映射的node1容器  

docker stop node1
docker rm node1    # 數據庫數據保存在Docker卷v1中,不會丟失
# 參數改變:
# 1. -e CLUSTER_JOIN=node2;原來其他節點是通過node1加入集群的,現在node1重新創建,需要選擇一個其他節點加入集群
# 2. -v backup:/data;將Docker卷backup映射到容器的/data目錄
docker run -d -u root -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node2 -v v1:/var/lib/mysql -v backup:/data --network=net1 --ip 172.18.0.2 --name=node1 pxc

在node1容器中安裝 percona-xtrabackup-24  

docker exec -it node1 bash
apt-get update
apt-get install percona-xtrabackup-24

之后便可以執行如下命令進行全量備份,備份后的數據會保存在 /data/backup/full 目錄下:  

mkdir /data/backup
mkdir /data/backup/full
#不建議,已過時 innobackupex --backup -u root -p abc123456 --target-dir=/data/backup/full
xtrabackup --backup -uroot -pabc123456 --target-dir=/data/backup/full

官方文檔已經不推薦使用 innobackupex,而推薦使用 xtrabackup 命令  

PXC全量還原

數據庫可以熱備份,但是不能熱還原,否則會造成業務數據和還原數據的沖突。

對於PXC集群為了避免還原過程中各節點數據同步沖突的問題,我們要先解散原來的集群,刪除節點。然后新建節點空白數據庫,執行還原,最后再建立起其他集群節點。

還原前還要將熱備份保存的未提交的事務回滾,還原之后重啟MySQL

1 停止並刪除PXC集群所有節點

docker stop node1 node2 node3 node4 node5
docker rm node1 node2 node3 node4 node5
docker volume rm v1 v2 v3 v4 v5

2 按照之前的步驟重新創建node1容器,並進入容器,執行冷還原  

# 創建卷
docker volume create v1
# 創建容器
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 --name=node1 --network=net1 --ip 172.18.0.2 pxc
# 以root身份進入容器
docker exec -it -uroot node1 bash
# 刪除數據
rm -rf /var/lib/mysql/*
# 准備階段
xtrabackup --prepare --target-dir=/data/backup/full/
# 執行冷還原
xtrabackup --copy-back --target-dir=/data/backup/full/
# 更改還原后的數據庫文件屬主
chown -R mysql:mysql /var/lib/mysql
# 退出容器后,重啟容器
docker stop node1
docker start node1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM