集羣的方案
單節點的弊病
-
大型互聯網程序用戶羣體龐大,因此架構必需要特殊設計
-
單節點的數據庫沒法知足性能的要求
案例15年前,高考成績能夠在網上查(河南幾十萬考生),那時候基本家裏都沒電腦,都是去網吧白天去網吧也查不了,太慢了,後來半夜通宵有時候能夠查到,也就是說白天基本查不了人太多了。晚上看運氣。一個數據庫的實例1萬多人就沒法反應了。
-
單節點的數據庫沒有冗餘設計,沒法知足高可用
經常使用的mysql集羣設計方案
-
速度快
-
弱一致性
-
低價值
-
場景:日誌,新聞,帖子
-
速度慢
-
強一致性
-
高價值
-
場景:訂單,帳戶,財務
Percona Xtradb Cluster,簡稱PXC。是基於Galera插件的MySQL集羣。相比那些比較傳統的基於主從複製模式的集羣架構MHA和MM+keepalived,galera cluster最突出特色就是解決了詬病已久的數據複製延遲問題,基本上能夠達到實時同步。並且節點與節點之間,他們相互的關係是對等的。自己galera cluster也是一種多主架構。galera cluster最關注的是數據的一致性,對待事物的行爲時,要麼在全部節點上執行,要麼都不執行,它的實現機制決定了它對待一致性的行爲很是嚴格,這也能很是完美的保證MySQL集羣的數據一致性。在PXC裏面任何一個節點都是可讀可寫的。在其餘的節點必定是能夠讀取到這個數據。
PXC任意一個節點均可以存在讀寫的方案,也就是任意一個節點均可以當讀或者當寫。同步複製。保證強一致性。
Replication方案,主從的方式,他是採用異步的方式。
同步複製,事務在全部節點要提交都提交。要麼都不提交
環境搭建
應用IP地址服務配置安裝應用安裝方式docker-mysql192.168.66.100docker-mysql雙核 8g內存docker-mysqldocker
vagrant up複製代碼
(2).機器window/mac開通遠程登陸root用戶下
su -
vagrant
vi /etc/ssh/sshd_config
sudo systemctl restart sshd複製代碼
PXC集羣安裝介紹
PXC既能夠在linux系統安裝,也能夠在docker上面安裝。
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容器,不要在容器內保存業務的數據,要把數據放到宿主機上,能夠把宿主機的一個目錄映射到容器內,若是容器出現問題,只須要吧容器刪除,從新創建一個新的容器把目錄映射給新的容器。
以前一直有個疑問,若是直接映射目錄的吧,存在失敗的問題,如今終於知道解決方案了,直接映射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,在開發的時候總不能隨機鏈接一個數據庫吧。若是想請求,統一的口徑,這就須要搭建負載均衡了。雖然上邊已經搭建了集羣,可是不使用數據庫負載均衡,單節點處理全部請求,負載高,性能差。下圖就是一個節點很忙,其餘節點很閒。
LVS是不知道在虛擬機環境下安裝的。
mkdir haproxy/h1
pwd
vi haproxy.cfg複製代碼
登陸:admin 密碼:abc123456
global
chroot /usr/local/etc/haproxy
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
bind 0.0.0.0:8888
mode http
stats uri /dbs
stats realm Global\ statistics
stats auth admin:abc123456
listen proxy-mysql
bind 0.0.0.0:3306
mode tcp
balance roundrobin
option tcplog
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
option tcpka複製代碼
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,傳遞增刪蓋查,實際上是經過輪詢的方式。選擇mysql的節點。均勻的分發給mysql的實例。不會吧數據庫的請求都集中在一個節點上。把請求分散出去,每一個數據庫實例獲取到的請求就小不少了。這就是數據庫的負載。
查看日誌發現,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 .複製代碼
解決方案
docker volume inspect v1
cd /var/lib/docker/volumes/v1/_data
vi grastate.dat複製代碼
高可用負載均衡方案
目前haproxy只有一個,單haproxy不具有高可用,必須冗餘設計。haproxy不能造成瓶頸。
haproxy雙機互備離不開一個關鍵的技術,這個技術是虛擬IP,linux能夠在一個網卡內定義多個虛擬IP,得把這些IP地址定義到一個虛擬IP。
定義出來一個虛擬IP,這個方案叫雙機熱備,準備2個keepalived,keepalived 就是爲了搶佔虛擬IP的,誰手快誰能搶到,沒搶到的處於等待的狀態。搶到的叫作主服務器,未搶到的叫作備服務器。兩個keepalived以前有心跳檢測的,當備用的檢測到主服務掛了,就立馬搶佔虛擬IP。
keepalived必須在haproxy所在的容器以內,也能夠在docker倉庫裏面下載一個haproxy-keepalived的鏡像。這裏直接在容器內安裝keepalived。
docker exec -it h1 /bin/bash
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-get clean
apt-get update
apt-get install keepalived
apt-get install vim複製代碼
容器內的路徑:/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。
容器內啓動
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複製代碼
global
chroot /usr/local/etc/haproxy
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
bind 0.0.0.0:8888
mode http
stats uri /dbs
stats realm Global\ statistics
stats auth admin:abc123456
listen proxy-mysql
bind 0.0.0.0:3306
mode tcp
balance roundrobin
option tcplog
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
option tcpka複製代碼
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 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
複製代碼
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
systemctl restart network複製代碼
PS:若是經過docker的方式直接拉取haproxy和keepalived鏡像,比直接在鏡像裏面安裝應用方便不少,建議各位老鐵儘可能避免在容器內安裝應用,這樣真心麻煩不爽,別人封裝的鏡像根據pull的量好好看看api就可使用了。像h1若是容器stop後,從新start,還須要進入容器把keeplived給起起來。而h2直接start裏面的haproxy和keeplived,同時都起起來了。 兩個容器的採用的熱備的方案,讓用戶毫無感知,切換ip的形式真是美滋滋。mysql集羣的高性能,高負載,高可用基本完成了,可用按照這個思路搭建不一樣的主機下。