容器下的兩地三中心建設(shè)
1. 關(guān)于兩地三中心

如上圖,兩地三中心的架構(gòu),是為了提高系統(tǒng)的容錯(cuò)、容災(zāi)的能力。當(dāng)一個(gè)數(shù)據(jù)中心不可用時(shí),能夠?qū)㈥P(guān)鍵業(yè)務(wù)的流量切換到其他數(shù)據(jù)中心,可以抵御城市級(jí)的自然災(zāi)害。
兩地指的是,地理上不同的兩座城市,而三中心指的是:
生產(chǎn)中心 同城災(zāi)備中心 異地災(zāi)備中心
2. 機(jī)房的網(wǎng)絡(luò)連接

如上圖,兩地三中心架構(gòu)的前提是,各個(gè)機(jī)房是互聯(lián)互通的。因此,我們需要搭建一個(gè)低延時(shí)的環(huán)形網(wǎng)絡(luò)。光纖的長度,通常在 50 KM 以上。如果租用了運(yùn)營商的專線,延時(shí)可以高一點(diǎn),但通常不會(huì)超過 20 ms。如果是同城光纖,延時(shí)只有 3 ms 左右。
我們需要在機(jī)房間距、延時(shí)二者之間進(jìn)行取舍:
機(jī)房間距離越遠(yuǎn),容災(zāi)能力越強(qiáng),但光纖會(huì)更長,延時(shí)會(huì)更高 機(jī)房間距離越短,容災(zāi)能力越差,但光纖會(huì)越短,延時(shí)會(huì)很低
在同城的兩個(gè)機(jī)房之間,網(wǎng)絡(luò)延時(shí)很低,數(shù)據(jù)一致性很高。而異地機(jī)房,由于距離很遠(yuǎn),可以租用專線與另外兩個(gè)機(jī)房互聯(lián),避免過高的延時(shí)。
3. 應(yīng)用流量的分發(fā)

如上圖,是用戶訪問應(yīng)用時(shí)的流量走向:
用戶通過域名訪問應(yīng)用服務(wù),通過智能 DNS 解析到地理上更近的機(jī)房 IP 在機(jī)房中,使用虛擬機(jī)部署有一個(gè) LB 服務(wù),對(duì)流量進(jìn)行切分,一部分流量被切分到了另外一個(gè)機(jī)房 兩個(gè)機(jī)房的服務(wù),分別響應(yīng)不同用戶的請(qǐng)求
3.1 為什么是異地機(jī)房承載流量
沒有經(jīng)過流量沖擊的路徑是不可靠的。即使做了高可用、容災(zāi),如果沒有常態(tài)化的演練,系統(tǒng)也不會(huì)具備應(yīng)對(duì)的能力。
因此,在多機(jī)房建設(shè)時(shí),非常重要的一點(diǎn)就是,讓更多機(jī)房獲得訪問流量。這里選擇的是,兩個(gè)異地的機(jī)房作為日常主要的流量機(jī)房,原因如下:
更好演練災(zāi)難發(fā)生時(shí)的狀況 租用專線之后,異地機(jī)房延時(shí)能滿足要求 有足夠預(yù)算購買專線帶寬
3.2 為什么 DNS 之后,還有一層 LB
這里可能會(huì)有一個(gè)疑問,在機(jī)房外,DNS 對(duì)流量進(jìn)行了一次切分,在機(jī)房內(nèi),LB 又對(duì)流量進(jìn)行了一次切分,原因如下:
DNS 生效慢,增加一層 LB 能更快切換流量 準(zhǔn)確控制分配至各機(jī)房的流量比例 支持按機(jī)房灰度發(fā)布應(yīng)用的版本
4. 有狀態(tài)與無狀態(tài)的分層

如上圖,有狀態(tài)應(yīng)用和無狀態(tài)應(yīng)用的分層,使得服務(wù)架構(gòu)更加清晰。由無狀態(tài)應(yīng)用對(duì)外提供服務(wù),而有狀態(tài)應(yīng)用為無狀態(tài)應(yīng)用提供服務(wù)。
這里的有狀態(tài)應(yīng)用,使用的是虛擬機(jī)部署的高可用服務(wù),或者直接購買廠商的云服務(wù)中間件。
4.1 無狀態(tài)應(yīng)用

如上圖,無狀態(tài)應(yīng)用基于 Kubernetes 提供運(yùn)行時(shí)環(huán)境。得益于其強(qiáng)大的彈性與自愈能力,我們只需要關(guān)注于對(duì)各種云原生組件的使用,對(duì)參數(shù)的調(diào)優(yōu),即可滿足大部分的業(yè)務(wù)需求。
對(duì)于無狀態(tài)應(yīng)用,我們通常會(huì)采用 Ingress 或 NodePort 的方式,對(duì)外暴露服務(wù)。兩者的區(qū)別主要在于:
支持的服務(wù)數(shù)量。每個(gè) NodePort 會(huì)占用一個(gè)端口 功能差異。Ingress 能提供 Host、灰度、子 Path 路徑等功能 組件數(shù)量。Ingress 需要更多組件支撐 運(yùn)維成本。Ingress 更新時(shí),影響面更大,運(yùn)維成本高 遷移成本。NodePort 可能會(huì)發(fā)生端口沖突
Kubernetes 并不是保證服務(wù) 100% 可用,而是一旦服務(wù)異常時(shí),能夠快速利用空閑資源新建。同時(shí),Kubernetes 還面臨集群升級(jí)、主機(jī)維護(hù)等問題,因此,對(duì)于一些低頻變更、對(duì)穩(wěn)定性要求高的服務(wù),我們采用的是虛擬機(jī)部署。
比如這里的 LB,LB 是一個(gè)影響面很大的應(yīng)用,而且數(shù)量不會(huì)很多,我們通常會(huì)采用高可用的模式,部署在幾臺(tái)虛擬機(jī)上。
4.2 有狀態(tài)應(yīng)用
鏡像倉庫
Harbor 的高可用通常有兩種方式:
多個(gè)獨(dú)立部署的 Harbor 實(shí)時(shí)同步。不同的 Harbor 實(shí)例之間,鏡像可能不一致,有一定時(shí)延。 多個(gè) Harbor 共享一個(gè)存儲(chǔ)后端。多個(gè) Harbor 實(shí)例,共享一個(gè)存儲(chǔ)后端,數(shù)據(jù)一致性有保障了,但對(duì)存儲(chǔ)后端的分布式要求更高。
這里采用的是 Harbor 共享存儲(chǔ)高可用 + dragonFly 的方式。在非主要流量機(jī)房,部署高可用的 Harbor,通過 dragonFly 分發(fā)鏡像到各個(gè)機(jī)房,機(jī)房中的主機(jī)通過 dfget 配置 mirror 拉取鏡像。如下圖:

使用 dragonFly 分發(fā)鏡像,能減少同一個(gè)鏡像,多副本應(yīng)用實(shí)例部署時(shí)的拉取次數(shù),節(jié)省專線的帶寬。
MySQL 多機(jī)房 MHA 高可用

相較于國外使用 PostgreSQL,國內(nèi)使用 MySQL 特別多。MHA(Master High Availability)是一套成熟的 MySQL 解決方案。在 MySQL 發(fā)生故障時(shí),MHA 能在 30 秒以內(nèi)完成數(shù)據(jù)庫的故障切換操作,同時(shí)最大程度的保障數(shù)據(jù)一致性。
Redis 多機(jī)房集群模式

Redis 集群通過分片來實(shí)現(xiàn)數(shù)據(jù)共享,并提供復(fù)制和故障轉(zhuǎn)移。相較于哨兵模式只有一個(gè) master,集群模式有多個(gè) master,具有高的可用性。
5. 總結(jié)
本篇主要是簡單總結(jié)了一下兩地三中心的架構(gòu)。所寫即所見的抽象,并不能完全盡述細(xì)節(jié)。主要內(nèi)容如下:
兩地三中心的要點(diǎn),是要構(gòu)建一個(gè)環(huán)形的互聯(lián)互通機(jī)房網(wǎng)絡(luò) 有狀態(tài)應(yīng)用采用虛擬機(jī)部署,無狀態(tài)應(yīng)用采用 Kubernetes 部署 訪問流量,先通過 DNS 切分到機(jī)房,在機(jī)房中再通過 LB 切分到各個(gè)集群
