分布式集群架構(gòu)方案

寫在前面:本文寫作前景為在b站上看到的一個三高(高可用、高并發(fā)牍颈、高性能)的分布式集群架構(gòu)方案迄薄,并對其中的pxc集群以及haproxy負(fù)載均衡進(jìn)行了試驗(yàn)。如若文中出現(xiàn)錯誤煮岁,歡迎廣大網(wǎng)友提出讥蔽。
保護(hù)知識產(chǎn)權(quá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ī)熱備理解

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ù)最多需要兩次請求。

Redis Cluster moved重定向

需要注意的是境析,如果集群中某一節(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為例:


后端應(yīng)用程序負(fù)載均衡與雙機(jī)熱備

具體方案不再綴述疲酌。
由于前段方案也是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ī)熱備。


分布式集群架構(gòu)圖

七 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 ''

HAProxy監(jiān)控界面

遇到的坑

  1. 拉取pxc的鏡像總是卡住揭鳞,解決:配置阿里云鏡像加速
  2. 一開始集群節(jié)點(diǎn)為五個,后來啟動HAProxy容器的時候不就該容易無法啟動pxc主節(jié)點(diǎn)也老是掛掉梆奈,整到晚上一點(diǎn)野崇。第二天free -h查看內(nèi)存就剩幾十M,推測內(nèi)存不夠于是在一臺新的阿里云服務(wù)器上配置HAProxy亩钟,成功乓梨!
  3. 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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市场仲,隨后出現(xiàn)的幾起案子和悦,更是在濱河造成了極大的恐慌,老刑警劉巖渠缕,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸽素,死亡現(xiàn)場離奇詭異,居然都是意外死亡亦鳞,警方通過查閱死者的電腦和手機(jī)馍忽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來燕差,“玉大人遭笋,你說我怎么就攤上這事⊥教剑” “怎么了瓦呼?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長测暗。 經(jīng)常有香客問我央串,道長磨澡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任质和,我火速辦了婚禮稳摄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘饲宿。我一直安慰自己秩命,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布褒傅。 她就那樣靜靜地躺著弃锐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪殿托。 梳的紋絲不亂的頭發(fā)上霹菊,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機(jī)與錄音支竹,去河邊找鬼旋廷。 笑死,一個胖子當(dāng)著我的面吹牛礼搁,可吹牛的內(nèi)容都是我干的饶碘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼馒吴,長吁一口氣:“原來是場噩夢啊……” “哼扎运!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起饮戳,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤豪治,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后扯罐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體负拟,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年歹河,在試婚紗的時候發(fā)現(xiàn)自己被綠了掩浙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡秸歧,死狀恐怖厨姚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情寥茫,我是刑警寧澤遣蚀,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響芭梯,放射性物質(zhì)發(fā)生泄漏险耀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一玖喘、第九天 我趴在偏房一處隱蔽的房頂上張望甩牺。 院中可真熱鬧,春花似錦累奈、人聲如沸贬派。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搞乏。三九已至,卻和暖如春戒努,著一層夾襖步出監(jiān)牢的瞬間请敦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工储玫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侍筛,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓撒穷,卻偏偏與公主長得像匣椰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子端礼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

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