Haproxy+PXC搭建Mysql集群

安裝環(huán)境

centos7, docker

集群方案介紹

大型網(wǎng)站數(shù)據(jù)庫需要應(yīng)對高負(fù)載虫几、實現(xiàn)高可用寓娩。而單節(jié)點數(shù)據(jù)庫在并發(fā)量大的情況下無法滿足性能要求趟径,且一臺宕機(jī)雾家,整個服務(wù)受影響英融。

  • Mysql集群:PXC
  • 負(fù)載均衡:Haproxy
  • 高可用:Keepalived
高可用Mysql集群方案

搭建pxc集群

安裝pxc鏡像

docker官方倉庫(https://hub.docker.com)搜索 percona-xtradb-cluster盏檐,拉取鏡像命令為: docker pull percona/percona-xtradb-cluster
終端執(zhí)行:

// 安裝pxc鏡像
? docker pull percona/percona-xtradb-cluster
// 查看鏡像
? docker images
REPOSITORY                                        TAG                 IMAGE ID            CREATED             SIZE
docker.io/percona/percona-xtradb-cluster        latest              f3abd21f393a        3 days ago          72.1 MB
// 鏡像名稱太長歇式,為方便使用,修改一下
? docker tag docker.io/percona/percona-xtradb-cluster pxc
// 刪除原鏡像
docker rmi docker.io/percona/percona-xtradb-cluster

創(chuàng)建Docker內(nèi)部網(wǎng)絡(luò)

出于安全考慮胡野,不要把pxc容器的IP直接暴露出去材失,而是創(chuàng)建docker內(nèi)部網(wǎng)絡(luò)。

// 網(wǎng)段subnet自定義硫豆,網(wǎng)段名自定義為network20
? docker network create --subnet=172.20.0.0/16 network20
2e9196b0637074cad609be8e4e890aa3e889209af8c2b55ce8097981000bf53f
// 查看網(wǎng)段詳細(xì)信息
? docker network inspect network20

創(chuàng)建Docker卷

docker的使用原則之一:不要在容器內(nèi)保存業(yè)務(wù)數(shù)據(jù)龙巨,而應(yīng)該保存在宿主機(jī)中
實現(xiàn)方式:通過目錄映射熊响,把宿主機(jī)的目錄映射到容器內(nèi)旨别,運(yùn)行容器時,把數(shù)據(jù)保存在映射目錄中耘眨,也就是保存在宿主機(jī)中昼榛。當(dāng)容器發(fā)生故障時,只需把故障容器刪除掉剔难,重新啟動一個容器胆屿,把宿主機(jī)的目錄映射給新容器。
pxc運(yùn)行在容器中偶宫,無法直接使用映射目錄非迹,會發(fā)生閃退。需要借助Docker卷完成映射纯趋。

// 創(chuàng)建一個docker卷憎兽,自定義名稱為 volume-mysql-1
? docker volume create --name volume-mysql-1
// 可以查看數(shù)據(jù)卷在宿主機(jī)上當(dāng)真實目錄
? docker volume inspect volume-mysql-1
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/volume-mysql-1/_data", // 數(shù)據(jù)卷在宿主機(jī)真實的路徑
        "Name": "volume-mysql-1", // 數(shù)據(jù)卷名稱
        "Options": {},
        "Scope": "local"
    }
]

創(chuàng)建PXC容器

  • 命令分解
// -d 創(chuàng)建出的容器后臺運(yùn)行
docker run -d
// -p 端口映射,[宿主機(jī)端口]:[容器端口]
-p 3311:3306
// -e 啟動參數(shù)吵冒,MYSQL_ROOT_PASSWORD數(shù)據(jù)庫root密碼
-e MYSQL_ROOT_PASSWORD=123456
// CLUSTER_NAME集群名稱
-e CLUSTER_NAME=pxc-test 
// XTRABACKUP_PASSWORD數(shù)據(jù)庫間節(jié)點同步密碼
-e XTRABACKUP_PASSWORD=123456 
// -v 目錄映射纯命,[宿主機(jī)目錄(數(shù)據(jù)卷)]:[容器目錄]
-v volume-mysql-1:/var/lib/mysql
// 最高權(quán)限
--privileged
// --name 容器名稱
--name mysql-node1
// --net 給容器指定網(wǎng)段,指定IP
--net network20 --ip 172.20.0.2 
// 鏡像名
pxc

執(zhí)行指令創(chuàng)建第一個pxc節(jié)點

// 創(chuàng)建第一個pxc節(jié)點 mysql-node1
? docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc-test -e XTRABACKUP_PASSWORD=123456 -v volume-mysql-1:/var/lib/mysql --privileged --name mysql-node1 --net network20 --ip 172.20.0.2 pxc

注意:容器創(chuàng)建很快就會完成痹栖,但是容器內(nèi)mysql數(shù)據(jù)庫的初始化大概需要2分鐘左右亿汞,一定要等到mysql初始化完成后,再創(chuàng)建第2個容器揪阿,否則第2個容器會發(fā)生閃退疗我! 判斷mysql-node1是否完成初始化,可以在宿主機(jī)終端執(zhí)行指令:docker exec -it mysql-node1 mysql -uroot -p南捂,看是否連接成功吴裤。

創(chuàng)建第2-5個pxc節(jié)點,與第1個節(jié)點略有區(qū)別:

  • 修改映射宿主機(jī)端口號(-p)
  • 修改容器名稱 (--name)
  • 修改映射的數(shù)據(jù)卷 (-v)
  • 修改分配的IP地址 (--ip)
  • 增加一個參數(shù)用于加入集群溺健,和第一個pxc節(jié)點進(jìn)行同步: -e CLUSTER_JOIN=mysql-node1
  • 除第1個容器以外麦牺,其余mysql初始化時間非常短,無需等待
// 創(chuàng)建pxc容器 mysql-node2
? docker run -d -p 3312:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc-test -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=mysql-node1 -v volume-mysql-2:/var/lib/mysql --privileged --name mysql-node2 --net network20 --ip 172.20.0.3 pxc
// 創(chuàng)建pxc容器 mysql-node3
? docker run -d -p 3313:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc-test -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=mysql-node1 -v volume-mysql-3:/var/lib/mysql --privileged --name mysql-node3 --net network20 --ip 172.20.0.4 pxc
// 創(chuàng)建pxc容器 mysql-node4
? docker run -d -p 3314:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc-test -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=mysql-node1 -v volume-mysql-4:/var/lib/mysql --privileged --name mysql-node4 --net network20 --ip 172.20.0.5 pxc
// 創(chuàng)建pxc容器 mysql-node5
? docker run -d -p 3315:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc-test -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=mysql-node1 -v volume-mysql-5:/var/lib/mysql --privileged --name mysql-node5 --net network20 --ip 172.20.0.6 pxc

檢測pxc集群的數(shù)據(jù)同步

可在宿主機(jī)上直接登陸某個容器的mysql客戶端;也可以使用mysql可視化工具枕面,如Navicat等遠(yuǎn)程登陸愿卒,遠(yuǎn)程登陸的需要防火墻開放端口缚去。
以下演示宿主機(jī)終端驗證方法:

// 登陸mysql-node1節(jié)點的mysql終端潮秘,創(chuàng)建db=demo,table=user
? docker exec -it mysql-node1 mysql -uroot -p
mysql> create database demo;
mysql> use demo
Database changed
Query OK, 1 row affected (0.02 sec)
mysql> create table student(id int unsigned not null auto_increment, name varchar(50) not null default '', primary key (id)) engine=innodb;
Query OK, 0 rows affected (0.04 sec)
mysql> exit
Bye

// 退出mysql-node1易结,登陸mysql-node2
? docker exec -it mysql-node2 mysql -uroot -p
mysql> use demo
Database changed
mysql> show tables;
+----------------+
| Tables_in_demo |
+----------------+
| student        |
+----------------+
1 row in set (0.01 sec)
// 其它節(jié)點同mysql-node2

任意節(jié)點寫入新數(shù)據(jù)枕荞,其它節(jié)點都會同步。至此搞动,pxc集群搭建完成躏精。

haproxy配置負(fù)載均衡

負(fù)載均衡簡單介紹

負(fù)載均衡可以使應(yīng)用數(shù)據(jù)均勻的落在pxc集群的每一個節(jié)點上。如果不使用負(fù)載均衡鹦肿,單節(jié)點處理所有請求矗烛,會導(dǎo)致該節(jié)點負(fù)載高、性能差箩溃;其它節(jié)點卻空閑浪費(fèi)瞭吃。
haproxy做負(fù)載均衡器,它不是數(shù)據(jù)庫涣旨,只是一個轉(zhuǎn)發(fā)件歪架。


負(fù)載均衡器

Docker安裝Haproxy鏡像

// 拉取鏡像
? docker pull haproxy
// 查看鏡像
? docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
docker.io/haproxy           latest              f3abd21f393a        3 days ago          72.1 MB
pxc                         latest              70b3670450ef        4 weeks ago         408 MB

創(chuàng)建haproxy配置文件

// 宿主機(jī)上創(chuàng)建haproxy配置文件,路徑自己指定霹陡,之后創(chuàng)建容器會用到
? touch /home/softconf/haproxy/haproxy.cfg
// haproxy.conf寫入下列內(nèi)容和蚪,具體配置需要修改
global
    #工作目錄
    chroot /usr/local/etc/haproxy
    #日志文件,使用rsyslog服務(wù)中l(wèi)ocal5日志設(shè)備(/var/log/local5)烹棉,等級info
    log 127.0.0.1 local5 info
    #守護(hù)進(jìn)程運(yùn)行
    daemon

defaults
    log global
    mode    http
    #日志格式
    option  httplog
    #日志中不記錄負(fù)載均衡的心跳檢測記錄
    option  dontlognull
    #連接超時(毫秒)
    timeout connect 5000
    #客戶端超時(毫秒)
    timeout client  50000
    #服務(wù)器超時(毫秒)
    timeout server  50000

#監(jiān)控界面
listen  admin_stats
    #監(jiān)控界面的訪問的IP和端口
    bind  0.0.0.0:8888
    #訪問協(xié)議
    mode        http
    #URI相對地址
    stats uri   /dbs
    #統(tǒng)計報告格式
    stats realm     Global\ statistics
    #登陸帳戶信息
    stats auth  admin:admin123456
#數(shù)據(jù)庫負(fù)載均衡
listen  proxy-mysql
    #訪問的IP和端口
    bind  0.0.0.0:3306
    #網(wǎng)絡(luò)協(xié)議
    mode  tcp
    #負(fù)載均衡算法(輪詢算法)
    #輪詢算法:roundrobin
    #權(quán)重算法:static-rr
    #最少連接算法:leastconn
    #請求源IP算法:source
    balance  roundrobin
    #日志格式
    option  tcplog
    #在MySQL中創(chuàng)建一個沒有權(quán)限的haproxy用戶攒霹,密碼為空。Haproxy使用這個賬戶對MySQL數(shù)據(jù)庫心跳檢測
    option  mysql-check user haproxy
    server  MySQL_1 172.20.0.2:3306 check weight 1 maxconn 2000
    server  MySQL_2 172.20.0.3:3306 check weight 1 maxconn 2000
    server  MySQL_3 172.20.0.4:3306 check weight 1 maxconn 2000
    server  MySQL_4 172.20.0.5:3306 check weight 1 maxconn 2000
    server  MySQL_5 172.20.0.6:3306 check weight 1 maxconn 2000
    #使用keepalive檢測死鏈
    option  tcpka

haproxy.cnf 與pxc相關(guān)配置 重點查看listen proxy-mysql

創(chuàng)建haproxy容器

// -p 端口號 8888 :haproxy后臺監(jiān)控界面端口浆洗,與haproxy.cnf中的配置一致
// -p 端口號 3306 :haproxy對外提供負(fù)載均衡服務(wù)端口催束,可以直接通過該端口連接到pxc集群
// -v 目錄映射,把宿主機(jī)的配置文件所在目錄映射到容器的工作目錄中
// --name 容器名辅髓,建議帶數(shù)字編號1泣崩,高可用時haproxy需要配置成雙節(jié)點
// --net 網(wǎng)段需要和pxc集群在同一網(wǎng)段中
// --ip 可以指定IP,當(dāng)不指定時docker虛擬機(jī)會默認(rèn)分配一個
? docker run -it -d -p 4001:8888 -p 4002:3306 -v /home/softconf/haproxy:/usr/local/etc/haproxy --name mysql-haproxy1 --privileged --net=network20 haproxy
// 進(jìn)入容器中洛口,榮國配置文件啟動 haproxy
? docker exec -it mysql-haproxy1 bash
root@0672cb121dde:/# haproxy -f /usr/local/etc/haproxy/haproxy.cfg

創(chuàng)建mysql的haproxy用戶

進(jìn)入pxc某個節(jié)點矫付,在mysql中創(chuàng)建haproxy用戶。haproxy中間件需要使用該賬號登陸數(shù)據(jù)庫第焰,發(fā)送心跳檢測买优。

// 登陸一個pxc節(jié)點的mysql終端
? docker exec -it mysql-node2 mysql -uroot -p
mysql> use mysql
Database changed
mysql> create user 'haproxy'@'%' identified by '';
mysql> flush privileges;

驗證haproxy

通過瀏覽器訪問haproxy監(jiān)控頁面,遠(yuǎn)程訪問需要開放端口(CentOS7使用firewalld打開關(guān)閉防火墻與端口)

  • 訪問地址:http://宿主機(jī)IP:4001/dbs
  • 訪問路徑配置文件中:stats uri /dbs
  • 用戶名、密碼在配置文件中:stats auth admin:admin123456
    haproxy監(jiān)控頁面

在監(jiān)控見面中可以看到5個節(jié)點都是啟動狀態(tài)杀赢,當(dāng)暫停/停止一個pxc節(jié)點時烘跺,監(jiān)控界面的down節(jié)點狀態(tài)(顏色)發(fā)生變化。由于haproxy會將請求發(fā)送至其它可用節(jié)點脂崔,此時pxc集群仍然可用滤淳。

// 終端執(zhí)行命令,暫停一個節(jié)點
?  haproxy docker pause mysql-node2
haproxy監(jiān)控界面 - node down

mysql客戶端連接haproxy

// 宿主機(jī)上連接mysql客戶端
// -P 端口號砌左,haproxy的3306端口映射到宿主機(jī)的4002端口
// -p 密碼脖咐,pxc集群中的mysql密碼
?  haproxy mysql -h127.0.0.1 -P4002 -uroot -p
// 或通過navicat工具連接,-h為宿主機(jī)的公網(wǎng)IP

// 進(jìn)入mysql后汇歹,操作的所有數(shù)據(jù)都同步到pxc集群的全部節(jié)點
...

TODO : 集群高可用

單節(jié)點的Haproxy不具備高可用屁擅,必須要有冗余設(shè)計。
keepalived與haproxy安裝在同一個容器中产弹,搶占虛擬IP派歌。
阿里云服務(wù)器不支持虛擬IP,keepalived實現(xiàn)高可用待實現(xiàn)

Tips

Keepalived+mysql 雙主一般來說胶果,有幾個需要注意的點,原文地址:MySQL 高可用性keepalived+mysql雙主

1.采用 keepalived 作為高可用方案時作谭,兩個節(jié)點最好都設(shè)置成 BACKUP模式稽物,避免因為意外情況下(比如 腦裂)相互搶占導(dǎo)致往兩個節(jié)點寫入相同數(shù)據(jù)而引發(fā)沖突;
2.把兩個節(jié)點的 auto_increment_increment(自增步長)和 auto_increment_offset(自增起始值)設(shè)成不同值折欠。其目的是為了避免 master 節(jié)點意外宕機(jī)時贝或,可能會有部分 binlog 未能及時復(fù)制到slave上被應(yīng)用,從而會導(dǎo)致slave新寫入數(shù)據(jù)的自增值和原先master上沖突了锐秦,因此一開始就使其錯開咪奖;當(dāng)然了,如果有合適的容錯機(jī)制能解決主從自增 ID 沖突的話酱床,也可以不這么做羊赵;
3.slave 節(jié)點服務(wù)器配置不要太差,否則更容易導(dǎo)致復(fù)制延遲扇谣。作為熱備節(jié)點的 slave 服務(wù)器昧捷,硬件配置不能低于 master 節(jié)點;
4.如果對延遲問題很敏感的話罐寨,可考慮使用 MariaDB 分支版本靡挥,或者直接上線 MySQL 5.7 最新版本,利用多線程復(fù)制的方式可以很大程度降低復(fù)制延遲鸯绿;

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末跋破,一起剝皮案震驚了整個濱河市簸淀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌毒返,老刑警劉巖租幕,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拧簸,居然都是意外死亡劲绪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門狡恬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來珠叔,“玉大人蝎宇,你說我怎么就攤上這事弟劲。” “怎么了姥芥?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵兔乞,是天一觀的道長。 經(jīng)常有香客問我凉唐,道長庸追,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任台囱,我火速辦了婚禮淡溯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘簿训。我一直安慰自己咱娶,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布强品。 她就那樣靜靜地躺著膘侮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪的榛。 梳的紋絲不亂的頭發(fā)上琼了,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音夫晌,去河邊找鬼雕薪。 笑死,一個胖子當(dāng)著我的面吹牛晓淀,可吹牛的內(nèi)容都是我干的所袁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼要糊,長吁一口氣:“原來是場噩夢啊……” “哼纲熏!你這毒婦竟也來了妆丘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤局劲,失蹤者是張志新(化名)和其女友劉穎勺拣,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鱼填,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡药有,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了苹丸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愤惰。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赘理,靈堂內(nèi)的尸體忽然破棺而出宦言,到底是詐尸還是另有隱情,我是刑警寧澤商模,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布奠旺,位于F島的核電站,受9級特大地震影響施流,放射性物質(zhì)發(fā)生泄漏响疚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一瞪醋、第九天 我趴在偏房一處隱蔽的房頂上張望忿晕。 院中可真熱鬧,春花似錦银受、人聲如沸践盼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宏侍。三九已至,卻和暖如春蜀漆,著一層夾襖步出監(jiān)牢的瞬間谅河,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工确丢, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留绷耍,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓鲜侥,卻偏偏與公主長得像褂始,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子描函,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容