魅族經(jīng)過2014-2015年的轉(zhuǎn)型以及銷量大爆發(fā)后,隨之而來的互聯(lián)網(wǎng)服務(wù)業(yè)務(wù)越來越多,用戶基數(shù)越來越大,之前單機(jī)房的擴(kuò)展架構(gòu)已經(jīng)滿足不了魅 族的發(fā)展,此外加上國內(nèi)復(fù)雜網(wǎng)絡(luò)環(huán)境下,單機(jī)房無法滿足我們的可靠性需求。近年經(jīng)常出現(xiàn)的光纜被挖、機(jī)房掉電。如支付寶光纖被挖斷,導(dǎo)致業(yè)務(wù)中斷;去年微 信也出現(xiàn)大面積故障,同樣是光纖被挖斷。除了單機(jī)房故障風(fēng)險外,用戶就近接入的需求也很強(qiáng)烈。
多機(jī)房方案最大的挑戰(zhàn)是機(jī)房之間網(wǎng)絡(luò)延遲所帶來的一系列問題如一致性,當(dāng)然業(yè)界也有一些成熟的方案,例如阿里的單元化方案,按用戶把業(yè)務(wù)封閉在一個單元里;騰訊的set方案,還有微博的跨機(jī)房方案,主要是集中寫,提供了快速切換的方案。
我們借鑒以上幾種方案,把業(yè)務(wù)進(jìn)行一些梳理,映射到下面兩種業(yè)務(wù):
這類業(yè)務(wù)主要是讀取,極少寫入,所以我們甚至把這類業(yè)務(wù)歸納為只讀業(yè)務(wù)。
應(yīng)用商店單機(jī)房架構(gòu)如下圖:
經(jīng)過對業(yè)務(wù)可用性做分級,應(yīng)用商店(API接口)的可用性要求最高,運營后臺和開發(fā)者社區(qū)的可用性需求稍低。
基于以上分析,我們只需要對應(yīng)用商店(API接口)提供多機(jī)房方案。
應(yīng)用商店多機(jī)房架構(gòu)如下圖:
核心機(jī)房的部署基本不需要改動,我們?nèi)A東機(jī)房的數(shù)據(jù)通過MySQL的同步功能復(fù)制,榜單類數(shù)據(jù)的讀取與核心機(jī)房一致,從Redis緩存讀取。Redis緩存的數(shù)據(jù)實用定時任務(wù)從DB里獲取定時刷到Redis里。
為了保證數(shù)據(jù)一致性,"寫"依然是單點寫,是跨機(jī)房直接寫入核心機(jī)房。分兩種,一種是通過消息隊列,寫入遠(yuǎn)程機(jī)房,即使機(jī)房間網(wǎng)絡(luò)出現(xiàn)問題,我們 的"寫"可以堆積在MQ里,基本不影響用戶體驗,堆積的數(shù)據(jù)待網(wǎng)絡(luò)通順后再拉去。另一種"寫"要求馬上知道是否"寫"成功,所以是跨機(jī)房直接寫入數(shù)據(jù)庫, 這部分如果網(wǎng)絡(luò)出問題,將導(dǎo)致失敗,我們可以做降級處理。
另外機(jī)房間流量調(diào)度我們實用GSLB來調(diào)度,后面有詳細(xì)闡述。
我們這里的讀寫均衡業(yè)務(wù)有一個重要特性,就是所有數(shù)據(jù)可以按照用戶維度來切分。相互關(guān)聯(lián)度不大。例如我們的同步業(yè)務(wù),同步業(yè)務(wù)把手機(jī)端的所有數(shù)據(jù) (聯(lián)系人、短信、設(shè)置、wifi、輸入法偏好 ...)同步到云端,遇到手機(jī)丟失、刷機(jī)需要清數(shù)據(jù)時,可以隨時把數(shù)據(jù)拉下來,做到數(shù)據(jù)永不丟失。
下面是同步業(yè)務(wù)單機(jī)房架構(gòu):
我們的用戶訪問接口也分兩部分,一部分供手機(jī)端實用的API,另外一部分在Web端用戶可以直接操作(對聯(lián)系人做修改)。Web接口獲取到的請求轉(zhuǎn)發(fā)到后端的服務(wù),如聯(lián)系人同步、消息同步、設(shè)置項同步等服務(wù)。后端服務(wù)再根據(jù)用戶路由信息,存儲到不同DB分片。
這里做跨機(jī)房方案比較方便,直接按照用戶做全局路由,路由到不同機(jī)房即可。
跨機(jī)房架構(gòu)圖如下:
我們把業(yè)務(wù)數(shù)據(jù)和服務(wù)打包到單個Unit,一個Unit服務(wù)一定數(shù)量的用戶。每個Unit包含了完整的數(shù)據(jù)和服務(wù),可以單獨部署。每個機(jī)房有多個Unit,每個用戶的數(shù)據(jù)在本地有一份備份、在遠(yuǎn)程同樣也有一份備份。當(dāng)機(jī)房故障時,可以把備份數(shù)據(jù)拉起來服務(wù)用戶。
用戶通過API訪問我們的服務(wù)時,使用GSLB來做調(diào)度,用戶訪問業(yè)務(wù)服務(wù)時,先從GSLB獲取用戶數(shù)據(jù)所在位置(用戶數(shù)據(jù)同時僅在某一個機(jī)房提供服務(wù)),然后把客戶端請求調(diào)度到合適的機(jī)房。
Web請求是一個挑戰(zhàn),因為Web服務(wù)無法使用GSLB,所以不能精準(zhǔn)的調(diào)度用戶請求。這塊的方案在后續(xù)的流量調(diào)度里講到。
說到多機(jī)房,就牽涉到流量調(diào)度。流量調(diào)度最簡單的就是使用智能DNS服務(wù)。如下圖:
只能DNS根據(jù)LocalDNS來的請求里的IP來判定您是哪個那個ISP,哪個區(qū)域的用戶,從而調(diào)度到對應(yīng)ISP,對應(yīng)區(qū)域的機(jī)房,核心在智能DNS的IP庫。有幾個缺點:
由此就針對特定業(yè)務(wù),我們接入了GSLB服務(wù):
這個服務(wù)避開DNS請求,發(fā)起請求前,訪問我們自己的GSLB服務(wù)(或者 HttpDNS),業(yè)務(wù)可以帶上用戶標(biāo)識,來定位自己的數(shù)據(jù)在哪個機(jī)房,使用IP來訪問業(yè)務(wù)服務(wù)。
帶來幾個明顯好處:
目前我們所有客戶端的訪問,都接入GSLB,例如上面提到的應(yīng)用中心、用戶同步的API訪問等。
但是也存在問題,這種方案僅適應(yīng)于有客戶端的Http、Https請求,不適合瀏覽器訪問,瀏覽器不清楚你的GSLB是什么東西。用戶同步的API 訪問可以用GSLB來做,但是Web訪問的時候,是不能用GSLB來做流量調(diào)度的,因為瀏覽器不認(rèn)GSLB, 如果使用智能DNS也無法根據(jù)用戶ID精準(zhǔn)調(diào)度流量。
基于以上考慮,我們提出了第三種方案,GSLB+智能DNS:
用戶請求服務(wù)前,找到DNS解析到的一個服務(wù)器,去獲取數(shù)據(jù),后端服務(wù)會先找GSLB服務(wù)查找用戶數(shù)據(jù)所在機(jī)房,如果用戶數(shù)據(jù)在本機(jī)房,則直接返回數(shù)據(jù),否則,重定向用戶請求到合適的機(jī)房重新發(fā)起請求。
這種方案可能導(dǎo)致用戶瀏覽器里域名變換,影響用戶體驗,另外依然無法避免域名劫持。
本篇文章主要介紹魅族在多機(jī)房容災(zāi)的方案以及實施過程中碰到的問題和對策,以及魅族核心機(jī)房的遷移方案和問題的解決方案。
您在多機(jī)房部署方面擁有哪些心得及經(jīng)驗?歡迎在評論中分享。