寫在前面:本文寫作前景為在b站上看到的一個三高(高可用、高并發(fā)牍颈、高性能)的分布式集群架構(gòu)方案迄薄,并對其中的pxc集群以及haproxy負(fù)載均衡進(jìn)行了試驗(yàn)。如若文中出現(xiàn)錯誤煮岁,歡迎廣大網(wǎng)友提出讥蔽。
保護(hù)知識產(chǎn)權(quán)涣易,本文參考了如下博客文章
- pxc集群搭建
http://www.reibang.com/p/eae6b12c1cd5 - haproxy負(fù)載均衡
https://blog.csdn.net/qq_21108311/article/details/82973763 - 分布式集群理解
https://www.cnblogs.com/zyxblogPHP/p/10706206.html
如有侵權(quán)請聯(lián)系刪除
一 為什么需要分布式與集群
為什么需要分布式?舉一個簡單的例子如果應(yīng)用程序和服務(wù)器在同一臺機(jī)器上時冶伞,如果這臺服務(wù)負(fù)載達(dá)到上限需要將整個應(yīng)用遷到一個更高的性能的機(jī)器上新症。如果采用分布式架構(gòu),如果是數(shù)據(jù)庫服務(wù)器性能達(dá)到上限只需要增加數(shù)據(jù)庫服務(wù)器的性能碰缔。將數(shù)據(jù)庫账劲、應(yīng)用程序戳护、緩存等分開也可以方便對各部分進(jìn)行管理金抡。
為什么需要集群?以校園網(wǎng)為例腌且,校園網(wǎng)采用單一的數(shù)據(jù)庫節(jié)點(diǎn)梗肝。當(dāng)選課開始或者成績公布時,大量請求涌入铺董,由于壓力過大這臺服務(wù)器突然宕機(jī)整個系統(tǒng)就會崩潰巫击。采用集群的方案,如果一臺數(shù)據(jù)庫宕機(jī)還會有其它數(shù)據(jù)庫保證整個服務(wù)正常進(jìn)行精续。
采用分布式的集群如果某一節(jié)點(diǎn)性能不夠坝锰,最簡單的方式就可以采用增加節(jié)點(diǎn)的服務(wù)器。
二 MySQL集群
MySQL集群方案有兩種重付,分別為pxc(Percona XtraDB Cluster)和Replication顷级,這兩種方案各有優(yōu)缺點(diǎn)。
pxc為強(qiáng)一致性集群方案确垫,數(shù)據(jù)同步為雙向同步弓颈,集群中的每一個節(jié)點(diǎn)都可以是主節(jié)點(diǎn)。例如:當(dāng)向pxc集群中的某一臺數(shù)據(jù)庫發(fā)出寫操作后删掀,只有當(dāng)集群中所有節(jié)點(diǎn)都寫入完成才會返回寫入成功翔冀。這種方式可以保證每個節(jié)點(diǎn)的數(shù)據(jù)都是一致的,當(dāng)然性能也受集群中最慢的節(jié)點(diǎn)影響披泪。
Replication方案為讀寫分離方案數(shù)據(jù)纤子,數(shù)據(jù)同步為單向同步。當(dāng)向主庫進(jìn)行寫操作后會進(jìn)過一段延遲寫入從庫款票,所以其一致性較弱计福。從庫寫入數(shù)據(jù)后不會同步到主庫
總結(jié)如下:
特點(diǎn) | pxc | Replication |
---|---|---|
速度 | 慢 | 快 |
一致性 | 強(qiáng) | 弱 |
應(yīng)用場景 | 財務(wù)、賬戶徽职、訂單 | 新聞象颖、帖子、日志 |
這里選擇pxc集群搭建
數(shù)據(jù)備份方案:Xtrabackup熱備
三 負(fù)載均衡與雙機(jī)熱備
三大主流負(fù)載均衡器姆钉,Nginx说订,HAProxy抄瓦,LVS,簡單對比如下
- | Nginx | HAProxy | LVS |
---|---|---|---|
免費(fèi) | 是 | 是 | 是 |
虛擬主機(jī) | 支持 | 支持 | 不支持 |
支持協(xié)議 | http | http陶冷、tcp | tcp |
配置 | 簡單 | 簡單 | 復(fù)雜 |
負(fù)載算法 | 輪詢钙姊、加權(quán)輪詢、ip哈希 | 輪詢埂伦、加權(quán)輪詢煞额、原地址保持、請求URL沾谜、根據(jù)cookie | 輪詢膊毁、加權(quán)輪詢、最小連接基跑、權(quán)重最小連接 |
可參考鏈接:https://www.cnblogs.com/HacTF/p/7774106.html
這里選擇HAproxy作為負(fù)載均衡器婚温,HAproxy還提供一個監(jiān)控界面來查看當(dāng)前HAProxy的運(yùn)行狀態(tài)。
關(guān)于雙機(jī)熱備
為什么采用雙機(jī)熱備媳否?在pxc集群中栅螟,如果一臺MySQL掛掉會有其它MySQL保證系統(tǒng)的正常運(yùn)行,但是如果HAProxy掛掉整個pxc集群都將無法訪問篱竭。在這里就需要一個備份HAProxy在主HAproxy掛掉后及時接替主HAProxy的工作保證系統(tǒng)的正常力图。
怎樣進(jìn)行雙機(jī)熱備方案?采用keepalived掺逼。keepalived是以VRRP(Vritrual Router Redundancy Protocol,虛擬路由冗余協(xié)議)協(xié)議為基礎(chǔ)用來保證集群高可用性吃媒,防止單點(diǎn)故障的一個軟件。
keepalived工作原理:keepalived將提供一個雙機(jī)浮動的vip(虛擬ip)坪圾,這樣可以簡單實(shí)現(xiàn)一個雙機(jī)熱備高可用功能晓折。即將N臺提供相同功能的路由器組成一個路由器組,這個組里面有一個master和多個backup兽泄,master上面有一個對外提供服務(wù)的vip(該路由器所在局域網(wǎng)內(nèi)其他機(jī)器的默認(rèn)路由為該vip)漓概,master會發(fā)組播,當(dāng)backup收不到VRRP包時就認(rèn)為master宕掉了病梢,這時就需要根據(jù)VRRP的優(yōu)先級來選舉一個backup當(dāng)master胃珍。以此保證路由器的高可用。
keepalived的配置可用自行查找資料
pxc集群負(fù)載均衡與雙機(jī)熱備理解
四 Redis集群
redis-cluste集群方案是redis官方在3.0版本后提供的分布式集群方案蜓陌。在該方案中不存在中心節(jié)點(diǎn)觅彰。集群中每個節(jié)點(diǎn)存儲的數(shù)據(jù)都不一樣,并且節(jié)點(diǎn)之間互相連接钮热。
redis-cluster中有一個“槽”的概念填抬,在一個集群中一共有16384個槽。每一個key會經(jīng)過計算算出數(shù)據(jù)存在哪一個槽中隧期,計算方式為CRC16(key) mode 16384飒责。不論是存或者取數(shù)據(jù)key都會先經(jīng)過此運(yùn)算計算槽赘娄。在物理機(jī)中,集群會把不同的槽映射到不同的物理機(jī)中宏蛉。例如遣臼,集群中有三臺機(jī)器,A對應(yīng)槽為0-5500拾并,B對應(yīng)槽為5501-11000揍堰,C對應(yīng)槽為11001-16384。當(dāng)新增一個節(jié)點(diǎn)時cluster會從各節(jié)點(diǎn)拿出一部分槽分配到新節(jié)點(diǎn)上嗅义。例如屏歹,A:1501-5500,B:7001-11000芥喇,C:12501-16384西采,D:0-1500,5501-7000,11001-12500凰萨。
每個節(jié)點(diǎn)都會通過通訊共享槽與集群中各個節(jié)點(diǎn)的關(guān)系继控。當(dāng)客戶端向redis cluster中的任一節(jié)點(diǎn)發(fā)送請求,當(dāng)前節(jié)點(diǎn)會計算key對應(yīng)的槽胖眷,如果該槽正好在該節(jié)點(diǎn)上則返回key對應(yīng)的數(shù)據(jù)武通,如果該槽不在該節(jié)點(diǎn)上會返回moved重定向異常,客戶端從重定向異常中獲取正確目標(biāo)的節(jié)點(diǎn)珊搀,然后從目標(biāo)節(jié)點(diǎn)中請求數(shù)據(jù)冶忱。該方式保證了獲取數(shù)據(jù)最多需要兩次請求。
需要注意的是境析,如果集群中某一節(jié)點(diǎn)掛掉該節(jié)點(diǎn)的數(shù)據(jù)就會無法訪問囚枪。為保證集群的高可用性,redis cluster加入了主從模式劳淆,一個主節(jié)點(diǎn)對應(yīng)多個從節(jié)點(diǎn)链沼。主節(jié)點(diǎn)提供數(shù)據(jù),從節(jié)點(diǎn)從主節(jié)點(diǎn)復(fù)制數(shù)據(jù)沛鸵,保證主從節(jié)點(diǎn)數(shù)據(jù)一致括勺。如果主節(jié)點(diǎn)掛掉,從節(jié)點(diǎn)會接替主節(jié)點(diǎn)曲掰,隨后故障主節(jié)點(diǎn)修復(fù)該節(jié)點(diǎn)會自動降級為從節(jié)點(diǎn)疾捍。
關(guān)于redis cluster集群我找到一篇比較詳細(xì)的文章,可以參考:https://www.cnblogs.com/williamjie/p/11132211.html
五 應(yīng)用程序與前端
關(guān)于應(yīng)用程序的部署栏妖,因?yàn)楦髡Z言的方案不同乱豆,Java有Tomcat,Python有uWSGI和Gunicorn吊趾。
在應(yīng)用程序部署好后也需要負(fù)載均衡器做負(fù)載宛裕,為防止負(fù)載均衡器意外掛掉也需要進(jìn)行雙機(jī)熱備房官。Nginx是一款開源,高性能续滋,輕量級的負(fù)載均衡器和反向代理服務(wù)器翰守。雙機(jī)熱備方案同樣使用keepalived爭搶虛擬ip的形式。以Python為例:
具體方案不再綴述疲酌。
由于前段方案也是Nginx負(fù)載和keepalived雙機(jī)熱備的方式蜡峰,這里也不再綴述。
六 總體架構(gòu)
在這里前后端分離的分布式總體架構(gòu)已經(jīng)明確了朗恳。請求從前端服務(wù)器開始湿颅,Nginx對前端服務(wù)器做負(fù)載均衡,為防止Nginx掛掉使用keepalived爭搶虛擬ip方式進(jìn)行雙機(jī)熱備粥诫。對數(shù)據(jù)的請求由后端應(yīng)用程序開始油航,請求到達(dá)后端的Nginx,由Nginx進(jìn)行反向代理與負(fù)載均衡怀浆,為防止Nginx意外掛掉同樣使用keepalived進(jìn)行雙機(jī)熱備谊囚。如果訪問熱點(diǎn)數(shù)據(jù)則先在redis集群里尋找,如果redis集群中沒有則向pxc數(shù)據(jù)庫集群中進(jìn)行請求执赡。pxc集群同樣需要使用HAProxy做負(fù)載均衡镰踏,為防止HAProxy掛掉使用keepalived做雙機(jī)熱備。
七 pxc集群搭建與負(fù)載均衡
注:這里不詳細(xì)描述具體步驟沙合,詳細(xì)步驟可參考最上面附的兩篇博客
環(huán)境準(zhǔn)備:Centos7(1核2G奠伪,阿里云)、docker
關(guān)于docker的操作可以參考https://yeasy.gitbooks.io/docker_practice/content/
或者docker --help
首懈,這里主要涉及的有操作有網(wǎng)段network
绊率,卷 volume
,鏡像image
究履,容器container
滤否,可分別用docker network --help
查看相應(yīng)的操作。
前提準(zhǔn)備:
前往阿里云控制臺的安全組實(shí)例配置中把將要使用的端口開放挎袜,創(chuàng)建網(wǎng)段顽聂,創(chuàng)建卷
可配置阿里云的鏡像加速器(強(qiáng)烈建議)
集群搭建
創(chuàng)建網(wǎng)段:docker network create --subnet=172.19.0.0/24 pxc-test-network
創(chuàng)建卷:docker volume create pxc-test-volume1
拉取鏡像:docker pull percona/percona-xtradb-cluster:5.7
可將鏡像重命名:docker tag percona/percona-xtradb-cluster:5.7 pxc
創(chuàng)建第一個節(jié)點(diǎn),pxc集群創(chuàng)建第一個節(jié)點(diǎn)數(shù)據(jù)庫實(shí)例化會比較慢盯仪,如果第一個節(jié)點(diǎn)沒有完成實(shí)例化或者實(shí)例化失敗后面的節(jié)點(diǎn)加入的時候會失敗紊搪。
docker run -d -p 7306:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=pxc_cluster -v pxc-test-volume1:/var/lib/mysql --name=pxc_node1 --net=pxc-test-network --ip=172.19.0.2 pxc
可以是Navicat或者其它軟件連接MySQL,如果連接成功則證明第一個節(jié)點(diǎn)創(chuàng)建成功全景。
創(chuàng)建第二個節(jié)點(diǎn)并加入集群:
docker run -d -p 7307:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=pxc_cluster -e CLUSTER_JOIN=pxc_node1 -v pxc-test-volume2:/var/lib/mysql --name=pxc_node2 --net=pxc-test-network --ip=172.19.0.3 pxc
創(chuàng)建第三個節(jié)點(diǎn)并加入集群:
docker run -d -p 7308:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=pxc_cluster -e CLUSTER_JOIN=pxc_node1 -v pxc-test-volume3:/var/lib/mysql --name=pxc_node3 --net=pxc-test-network --ip=172.19.0.4pxc
參數(shù)解釋:
- MYSQL_ROOT_PASSWORD:MySQL用戶密碼耀石,用戶是root
- CLUSTER_NAME:集群名字
- CLUSTER_JOIN:與某個節(jié)點(diǎn)同步
HAProxy負(fù)載均衡
拉取鏡像docker pull haproxy
編寫配置文件并將配置文件映射到docker容器內(nèi)這里為/data/haproxy/haproxy.cfg
(后附上配置文件詳情)
啟動容器docker run -it -d -p 8001:8888 -p 8002:3306 -v /data/haproxy:/usr/local/etc/haproxy --name haproxy_node1 --privileged --net=pxc-test-network --ip 172.19.0.07 docker.io/haproxy
進(jìn)入容器:docker exec -it haproxy bash
啟用配置文件:haproxy -f /usr/local/etc/haproxy/haproxy.cfg
然后可放問監(jiān)控界面,http://你的ip:port/dbs爸黄,輸入用戶名和密碼(在配置文件配置)
要記得在MySQL中創(chuàng)建haproxy的用戶滞伟,在一個節(jié)點(diǎn)創(chuàng)建就行了pxc會自動同步
CREATE USER 'haproxy@'%' IDENTIFIED BY ''
遇到的坑
- 拉取pxc的鏡像總是卡住揭鳞,解決:配置阿里云鏡像加速
- 一開始集群節(jié)點(diǎn)為五個,后來啟動HAProxy容器的時候不就該容易無法啟動pxc主節(jié)點(diǎn)也老是掛掉梆奈,整到晚上一點(diǎn)野崇。第二天
free -h
查看內(nèi)存就剩幾十M,推測內(nèi)存不夠于是在一臺新的阿里云服務(wù)器上配置HAProxy亩钟,成功乓梨! - pxc集群為五個節(jié)點(diǎn)的時候,往節(jié)點(diǎn)寫入數(shù)據(jù)成功清酥,然后查這一條數(shù)據(jù)失敗扶镀,docker查看主節(jié)點(diǎn)容易掛掉,頓時懵逼焰轻。首先想是不是配置有問題臭觉,后來推測是不是因?yàn)閮?nèi)存不夠,集群節(jié)點(diǎn)改為三個辱志,成功蝠筑!
附:HAProxy配置文件haproxy.cfg
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 root:root
#數(shù)據(jù)庫負(fù)載均衡
listen proxy-mysql
#訪問的IP和端口(前面ip=0代表任何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 NODE1 47.100.48.93:7306 check weight 1 maxconn 2000
server NODE2 47.100.48.93:7307 check weight 1 maxconn 2000
server NODE3 47.100.48.93:7308 check weight 1 maxconn 2000
server NODE4 47.100.48.93:7309 check weight 1 maxconn 2000
server NODE5 47.100.48.93:7310 check weight 1 maxconn 2000
#使用keepalive檢測死鏈
option tcpka