「實戰篇」開源項目docker化運維部署-搭建mysql集羣(四)

有了docker虛擬機,就需要利用平臺部署數據庫的集羣,在實際操作之前介紹下數據庫集羣的方案和各自的特點。源碼:https://github.com/limingios/netFuture/tree/master/mysql-pxc/

集羣的方案
單節點的弊病
大型互聯網程序用戶羣體龐大,所以架構必須要特殊設計
單節點的數據庫無法滿足性能的要求
案例15年前,高考成績可以在網上查(河南幾十萬考生),那時候基本家裏都沒電腦,都是去網吧白天去網吧也查不了,太慢了,後來半夜通宵有時候可以查到,也就是說白天基本查不了人太多了。晚上看運氣。一個數據庫的實例1萬多人就無法反應了。

單節點的數據庫沒有冗餘設計,無法滿足高可用
常用的mysql集羣設計方案
Replication
速度快
弱一致性
低價值
場景:日誌,新聞,帖子
PXC
速度慢
強一致性
高價值
場景:訂單,賬戶,財務
Percona Xtradb Cluster,簡稱PXC。是基於Galera插件的MySQL集羣。相比那些比較傳統的基於主從複製模式的集羣架構MHA和MM+keepalived,galera cluster最突出特點就是解決了詬病已久的數據複製延遲問題,基本上可以達到實時同步。而且節點與節點之間,他們相互的關係是對等的。大數據學習扣qun74零零加【41三八yi】本身galera cluster也是一種多主架構。galera cluster最關注的是數據的一致性,對待事物的行爲時,要麼在所有節點上執行,要麼都不執行,它的實現機制決定了它對待一致性的行爲非常嚴格,這也能非常完美的保證MySQL集羣的數據一致性。在PXC裏面任何一個節點都是可讀可寫的。在其他的節點一定是可以讀取到這個數據。

建議PXC使用PerconaServer(MYSQL的改進版,性能提升很大)

PXC方案和Replication方案的對比

PXC任意一個節點都可以存在讀寫的方案,也就是任意一個節點都可以當讀或者當寫。同步複製。保證強一致性。

Replication方案,主從的方式,他是採用異步的方式。

PXC的數據強一致性
同步複製,事務在所有節點要提交都提交。要麼都不提交

Replication弱一致性,主要master成功就成功了。返回給調用者。如果slave失敗,也沒辦法。因爲已經告訴調用者成功了,調用者獲取查詢的時候查詢不到信息。例如:在淘寶買個東西,付款也成功了,查詢訂單沒信息是不是要罵娘。

環境搭建
應用 IP地址 服務 配置 安裝應用 安裝方式
docker-mysql 192.168.66.100 docker-mysql 雙核 8g內存 docker-mysql docker
(1). 虛擬機vagrant講述安裝的步驟

vagrant up

(2).機器window/mac開通遠程登錄root用戶下

su -

密碼

vagrant

設置 PasswordAuthentication yes

vi /etc/ssh/sshd_config
sudo systemctl restart sshd
PXC集羣安裝介紹
PXC既可以在linux系統安裝,也可以在docker上面安裝。

安裝鏡像PXC鏡像
docker pull percona/percona-xtradb-cluster

本地安裝

docker load /soft/pxc.tar.gz
創建內部網絡的
處於安全,需要給PXC集羣實例創建Docker內部網絡,都出可虛擬機自帶的網段是172.17.0., 這是內置的一個網段,當你創建了網絡後,網段就更改爲172.18.0.,

docker network create net1
docker network inspect net1
docker network rm net1

設置網段

docker network create --subnet=172.18.0.0/24 net1

創建Docker 卷
一旦生成docker容器,不要在容器內保存業務的數據,要把數據放到宿主機上,可以把宿主機的一個目錄映射到容器內,如果容器出現問題,只需要吧容器刪除,重新建立一個新的容器把目錄映射給新的容器。

之前一直有個疑問,如果直接映射目錄的吧,存在失敗的問題,現在終於知道解決方案了,直接映射docker卷就可以可以忽略這個問題了。

容器中的PXC節點映射數據目錄的解決方法

docker volume create name --v1
mysql pxc搭建
腳本開發

!/bin/bash

echo "創建網絡"
docker network create --subnet=172.18.0.0/24 net1

echo "創建5個docker卷"
docker volume create v1
docker volume create v2
docker volume create v3
docker volume create v4
docker volume create v5

echo "創建節點 node1"
docker run -d -p 3306:3306 --net=net1 --name=node1 \

    -e CLUSTER_NAME=PXC \
    -e MYSQL_ROOT_PASSWORD=a123456 \
    -e XTRABACKUP_PASSWORD=a123456 \
    -v v1:/var/lib/mysql \
    --privileged \
    --ip 172.18.0.2 \
    percona/percona-xtradb-cluster

sleep 1m
echo "創建節點 node2"
docker run -d -p 3307:3306 --net=net1 --name=node2 \

    -e CLUSTER_NAME=PXC \
    -e MYSQL_ROOT_PASSWORD=a123456 \
    -e XTRABACKUP_PASSWORD=a123456 \
    -e CLUSTER_JOIN=node1 \
    -v v2:/var/lib/mysql \
    --privileged \
    --ip 172.18.0.3 \
    percona/percona-xtradb-cluster

sleep 1m
echo "創建節點 node3"
docker run -d -p 3308:3306 --net=net1 --name=node3 \

    -e CLUSTER_NAME=PXC \
    -e MYSQL_ROOT_PASSWORD=a123456 \
    -e XTRABACKUP_PASSWORD=a123456 \
    -e CLUSTER_JOIN=node1 \
    -v v3:/var/lib/mysql \
    --privileged \
    --ip 172.18.0.4 \
    percona/percona-xtradb-cluster

sleep 1m
echo "創建節點 node4"
docker run -d -p 3309:3306 --net=net1 --name=node4 \

    -e CLUSTER_NAME=PXC \
    -e MYSQL_ROOT_PASSWORD=a123456 \
    -e XTRABACKUP_PASSWORD=a123456 \
    -e CLUSTER_JOIN=node1 \
    -v v4:/var/lib/mysql \
    --privileged \
    --ip 172.18.0.5 \
    percona/percona-xtradb-cluster

sleep 1m
echo "創建節點 node5"
docker run -d -p 3310:3306 --net=net1 --name=node5 \

    -e CLUSTER_NAME=PXC \
    -e MYSQL_ROOT_PASSWORD=a123456 \
    -e XTRABACKUP_PASSWORD=a123456 \
    -e CLUSTER_JOIN=node1 \
    -v v5:/var/lib/mysql \
    --privileged \
    --ip 172.18.0.6 \
    percona/percona-xtradb-cluster

新建立一個aaa數據庫 結果都可以用

哇塞就這麼簡單,成功的搭建了mysql的集羣

增加負載均衡方案
目前數據庫都是獨立的ip,在開發的時候總不能隨機連接一個數據庫吧。如果想請求,統一的口徑,這就需要搭建負載均衡了。雖然上邊已經搭建了集羣,但是不使用數據庫負載均衡,單節點處理所有請求,負載高,性能差。下圖就是一個節點很忙,其他節點很閒。

調整後的方案,使用Haproxy做負載均衡,請求被均勻分發到每個節點,單節點的負載低,性能好。haproxy不是數據庫,只是一個轉發器。

負載均衡中間件對比
LVS是不知道在虛擬機環境下安裝的。

安裝haproxy
docker-haproxy的介紹:https://hub.docker.com/_/haproxy/

配置文件
mkdir haproxy/h1
pwd
vi haproxy.cfg

haproxy.cfg配置
登錄:admin
密碼:abc123456

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  

創建docker下的haproxy容器
docker run -it -d -p 4001:8888 \
-p 4002:3306 \
-v /root/haproxy/h1:/usr/local/etc/haproxy \
--name h1 --privileged --net=net1 \
--ip 172.18.0.7 haproxy

進入容器後,加載配置文件
docker exec -it h1 /bin/bash
haproxy -f /usr/local/etc/haproxy/haproxy.cfg

在數據庫中創建一個haproxy的用戶,不需要設置密碼

登錄haproxy網頁端
http://192.168.66.100:4001/dbs

客戶端連接haproxy-mysql數據庫

正常的連接haproxy,傳遞增刪蓋查,其實是通過輪詢的方式。選擇mysql的節點。均勻的分發給mysql的實例。不會吧數據庫的請求都集中在一個節點上。把請求分散出去,每個數據庫實例獲取到的請求就小很多了。這就是數據庫的負載。

虛擬機重啓後,發現pxc起不起來了
查看日誌發現,node1無法啓動,輸入命令查看docker logs node1

It may not be safe to bootstrap the cluster from this node. It was not the last one to leave the cluster and may not contain all the updates. To force cluster bootstrap with this node, edit the grastate.dat file manually and set safe_to_bootstrap to 1 .
解決方案

查看node1掛載點的文件地址

docker volume inspect v1

進入目錄下

cd /var/lib/docker/volumes/v1/_data

編輯文件grastate.dat

vi grastate.dat

高可用負載均衡方案
目前haproxy只有一個,單haproxy不具備高可用,必須冗餘設計。haproxy不能形成瓶頸。

虛擬IP技術
haproxy雙機互備離不開一個關鍵的技術,這個技術是虛擬IP,linux可以在一個網卡內定義多個虛擬IP,得把這些IP地址定義到一個虛擬IP。

利用keepalived實現雙機熱備
定義出來一個虛擬IP,這個方案叫雙機熱備,準備2個keepalived,keepalived 就是爲了搶佔虛擬IP的,誰手快誰能搶到,沒搶到的處於等待的狀態。搶到的叫做主服務器,未搶到的叫做備服務器。兩個keepalived之前有心跳檢測的,當備用的檢測到主服務掛了,就立馬搶佔虛擬IP。

Haproxy雙機熱備方案

安裝keepalived

keepalived必須在haproxy所在的容器之內,也可以在docker倉庫裏面下載一個haproxy-keepalived的鏡像。這裏直接在容器內安裝keepalived。

docker exec -it h1 /bin/bash

寫入dns,防止apt-get update找不到服務器

echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null
apt-get clean
apt-get update
apt-get install vim
vi /etc/apt/sources.list

sources.list 添加下面的內容

deb http://mirrors.163.com/ubuntu/ precise main universe restricted multiverse
deb-src http://mirrors.163.com/ubuntu/ precise main universe restricted multiverse
deb http://mirrors.163.com/ubuntu/ precise-security universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-security universe main multiverse restricted
deb http://mirrors.163.com/ubuntu/ precise-updates universe main multiverse restricted
deb http://mirrors.163.com/ubuntu/ precise-proposed universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-proposed universe main multiverse restricted
deb http://mirrors.163.com/ubuntu/ precise-backports universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-backports universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-updates universe main multiverse restricted

更新apt源
apt-get clean
apt-get update
apt-get install keepalived
apt-get install vim

keepalived配置文件
容器內的路徑:/etc/keepalived/keepalived.conf

vi /etc/keepalived/keepalived.conf

VI_1 名稱可以自定義
state MASTER | keepalived的身份(MASTER主服務器,BACKUP備份服務器,不會搶佔虛擬機ip)。如果都是主MASTER的話,就會進行互相爭搶IP,如果搶到了就是MASTER,另一個就是SLAVE。
interface網卡,定義一個虛擬IP定義到那個網卡上邊。網卡設備的名稱。eth0是docker的虛擬網卡,宿主機是可以訪問的。
virtual_router_id 51 | 虛擬路由標識,MASTER和BACKUP的虛擬路由標識必須一致。標識可以是0-255。
priority 100 | 權重。MASTER權重要高於BACKUP 數字越大優選級越高。可以根據硬件的配置來完成,權重最大的獲取搶到的級別越高。
advert_int 1 | 心跳檢測。MASTER與BACKUP節點間同步檢查的時間間隔,單位爲秒。主備之間必須一致。
authentication | 主從服務器驗證方式。主備必須使用相同的密碼才能正常通信。進行心跳檢測需要登錄到某個主機上邊所有有賬號密碼。
virtual_ipaddress | 虛擬ip地址,可以設置多個虛擬ip地址,每行一個。根據上邊配置的eth0上配置的ip。
啓動keeplived
容器內啓動

service keepalived start

宿主機ping這個ip

ping 172.18.0.201

創建haproxy2容器,並配置與haproxy1相同的環境
因爲要保證有2個haproxy 和keepalived,這次就不那麼麻煩了。直接對一個鏡像裏面包括keeplived 和 haproxy。

宿主機創建文件
mkdir haproxy/h2
cd haproxy/h2
vi haproxy.cfg
vi keepalived.cfg

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  

keepalived.cfg
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
}

}
docker的方式一下安裝好 haproxy 和keepalived
https://hub.docker.com/r/pelin/haproxy-keepalived/
映射端口更改爲4003 4004 name修改h2

docker run -it -d --privileged -p 4003:8888\

-p 4004:3306 \
-v /root/haproxy/h2/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg \
-v /root/haproxy/h2/keepalived.conf:/etc/keepalived/keepalived.conf \
--name haproxy-keepalived \
--net=net1 \
--name h2 \
--ip 172.18.0.8 \
pelin/haproxy-keepalived

宿主機安裝keepalived
yum -y install keepalived
vi /etc/keepalived/keepalived.conf

刪除這個表裏之前存在的內容

keepalived.cof
vrrp_instance VI_1 {

    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
           192.168.66.200
    }
}

virtual_server 192.168.66.200 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.66.200 3306 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 172.18.0.201 3306 {
        weight 1
    }
}

啓動宿主機
service keepalived start

虛擬機端口轉發 外部無法訪問

WARNING: IPv4 forwarding is disabled. Networking will not work.
解決方案
宿主機修改

vi /etc/sysctl.conf

添加net.ipv4.ip_forward=1

systemctl restart network

PS:如果通過docker的方式直接拉取haproxy和keepalived鏡像,比直接在鏡像裏面安裝應用方便很多,建議各位老鐵儘量避免在容器內安裝應用,這樣真心麻煩不爽,別人封裝的鏡像根據pull的量好好看看api就可以使用了。像h1如果容器stop後,重新start,還需要進入容器把keeplived給起起來。而h2直接start裏面的haproxy和keeplived,同時都起起來了。 兩個容器的採用的熱備的方案,讓用戶毫無感知,切換ip的形式真是美滋滋。mysql集羣的高性能,高負載,高可用基本完成了,可用按照這個思路搭建不同的主機下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章