「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

IT人故事會發表於2019-03-28
原創文章,歡迎轉載。轉載請註明:轉載自IT人故事會,謝謝! 原文連結地址:「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
有了docker虛擬機器,就需要利用平臺部署資料庫的叢集,在實際操作之前介紹下資料庫叢集的方案和各自的特點。原始碼:github.com/limingios/n…

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

叢集的方案

單節點的弊病

  1. 大型網際網路程式使用者群體龐大,所以架構必須要特殊設計
  2. 單節點的資料庫無法滿足效能的要求
案例15年前,高考成績可以在網上查(河南幾十萬考生),那時候基本家裡都沒電腦,都是去網咖白天去網咖也查不了,太慢了,後來半夜通宵有時候可以查到,也就是說白天基本查不了人太多了。晚上看運氣。一個資料庫的例項1萬多人就無法反應了。
  1. 單節點的資料庫沒有冗餘設計,無法滿足高可用

常用的mysql叢集設計方案

  • Replication
  1. 速度快
  2. 弱一致性
  3. 低價值
  4. 場景:日誌,新聞,帖子
  • PXC
  1. 速度慢
  2. 強一致性
  3. 高價值
  4. 場景:訂單,賬戶,財務
Percona Xtradb Cluster,簡稱PXC。是基於Galera外掛的MySQL叢集。相比那些比較傳統的基於主從複製模式的叢集架構MHA和MM+keepalived,galera cluster最突出特點就是解決了詬病已久的資料複製延遲問題,基本上可以達到實時同步。而且節點與節點之間,他們相互的關係是對等的。本身galera cluster也是一種多主架構。galera cluster最關注的是資料的一致性,對待事物的行為時,要麼在所有節點上執行,要麼都不執行,它的實現機制決定了它對待一致性的行為非常嚴格,這也能非常完美的保證MySQL叢集的資料一致性。在PXC裡面任何一個節點都是可讀可寫的。在其他的節點一定是可以讀取到這個資料。
  • 建議PXC使用PerconaServer(MYSQL的改進版,效能提升很大)
  • PXC方案和Replication方案的對比
PXC任意一個節點都可以存在讀寫的方案,也就是任意一個節點都可以當讀或者當寫。同步複製。保證強一致性。

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
Replication方案,主從的方式,他是採用非同步的方式。

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • PXC的資料強一致性
同步複製,事務在所有節點要提交都提交。要麼都不提交

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • Replication弱一致性,主要master成功就成功了。返回給呼叫者。如果slave失敗,也沒辦法。因為已經告訴呼叫者成功了,呼叫者獲取查詢的時候查詢不到資訊。例如:在淘寶買個東西,付款也成功了,查詢訂單沒資訊是不是要罵娘。

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

環境搭建

應用IP地址服務配置安裝應用安裝方式docker-mysql192.168.66.100docker-mysql雙核 8g記憶體docker-mysqldocker
(1). 虛擬機器vagrant講述安裝的步驟
vagrant up複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
(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 </home/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化運維部署-搭建mysql叢集(四)
  • 建立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複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
新建立一個aaa資料庫 結果都可以用

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
哇塞就這麼簡單,成功的搭建了mysql的叢集

增加負載均衡方案

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

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 調整後的方案,使用Haproxy做負載均衡,請求被均勻分發到每個節點,單節點的負載低,效能好。haproxy不是資料庫,只是一個轉發器。

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 負載均衡中介軟體對比
LVS是不知道在虛擬機器環境下安裝的。

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 安裝haproxy
docker-haproxy的介紹:hub.docker.com/_/haproxy/

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 配置檔案
mkdir haproxy/h1
pwd
vi haproxy.cfg複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 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化運維部署-搭建mysql叢集(四)
  • 建立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化運維部署-搭建mysql叢集(四)
  • 進入容器後,載入配置檔案
docker exec -it h1 /bin/bash
haproxy -f /usr/local/etc/haproxy/haproxy.cfg複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 在資料庫中建立一個haproxy的使用者,不需要設定密碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 登入haproxy網頁端

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 客戶端連線haproxy-mysql資料庫

「實戰篇」開源專案docker化運維部署-搭建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複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

高可用負載均衡方案

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

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 虛擬IP技術
haproxy雙機互備離不開一個關鍵的技術,這個技術是虛擬IP,linux可以在一個網路卡內定義多個虛擬IP,得把這些IP地址定義到一個虛擬IP。
  • 利用keepalived實現雙機熱備
定義出來一個虛擬IP,這個方案叫雙機熱備,準備2個keepalived,keepalived 就是為了搶佔虛擬IP的,誰手快誰能搶到,沒搶到的處於等待的狀態。搶到的叫做主伺服器,未搶到的叫做備伺服器。兩個keepalived之前有心跳檢測的,當備用的檢測到主服務掛了,就立馬搶佔虛擬IP。

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • Haproxy雙機熱備方案
「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 安裝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複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
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複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 更新apt源
apt-get clean
apt-get update
apt-get install keepalived
apt-get install vim複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • keepalived配置檔案
容器內的路徑:/etc/keepalived/keepalived.conf
vi /etc/keepalived/keepalived.conf複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  1. VI_1 名稱可以自定義
  2. state MASTER | keepalived的身份(MASTER主伺服器,BACKUP備份伺服器,不會搶佔虛擬機器ip)。如果都是主MASTER的話,就會進行互相爭搶IP,如果搶到了就是MASTER,另一個就是SLAVE。
  3. interface網路卡,定義一個虛擬IP定義到那個網路卡上邊。網路卡裝置的名稱。eth0是docker的虛擬網路卡,宿主機是可以訪問的。
  4. virtual_router_id 51 | 虛擬路由標識,MASTER和BACKUP的虛擬路由標識必須一致。標識可以是0-255。
  5. priority 100 | 權重。MASTER權重要高於BACKUP 數字越大優選級越高。可以根據硬體的配置來完成,權重最大的獲取搶到的級別越高。
  6. advert_int 1 | 心跳檢測。MASTER與BACKUP節點間同步檢查的時間間隔,單位為秒。主備之間必須一致。
  7. authentication | 主從伺服器驗證方式。主備必須使用相同的密碼才能正常通訊。進行心跳檢測需要登入到某個主機上邊所有有賬號密碼。
  8. virtual_ipaddress | 虛擬ip地址,可以設定多個虛擬ip地址,每行一個。根據上邊配置的eth0上配置的ip。
  • 啟動keeplived
容器內啟動
service keepalived start複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
宿主機ping這個ip
ping 172.18.0.201複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

建立haproxy2容器,並配置與haproxy1相同的環境

因為要保證有2個haproxy 和keepalived,這次就不那麼麻煩了。直接對一個映象裡面包括keeplived 和 haproxy。
  • 宿主機建立檔案
mkdir haproxy/h2
cd haproxy/h2
vi haproxy.cfg
vi keepalived.cfg複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 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
hub.docker.com/r/pelin/hap… 對映埠更改為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複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

宿主機安裝keepalived

yum -y install keepalived
vi /etc/keepalived/keepalived.conf
#刪除這個表裡之前存在的內容複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 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
        }
    }複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
  • 啟動宿主機
service keepalived start複製程式碼

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

虛擬機器埠轉發 外部無法訪問

WARNING: IPv4 forwarding is disabled. Networking will not work.複製程式碼
  • 解決方案
宿主機修改
vi /etc/sysctl.conf
# 新增net.ipv4.ip_forward=1

systemctl restart network複製程式碼

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

「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)

相關文章