淺談數(shù)據(jù)庫(kù)同步和遷移
本文將主要首先聊一聊數(shù)據(jù)庫(kù)同步和遷移兩個(gè)話(huà)題,之后將會(huì)圍繞這 2 個(gè)話(huà)題介紹一下阿里云開(kāi)源的基于 MongoDB 和 Redis 的數(shù)據(jù)同步&遷移工具 MongoShake 和 RedisShake,最后介紹一些用戶(hù)的使用案例。
1. 同步
現(xiàn)在大部分?jǐn)?shù)據(jù)庫(kù)都支持集群版的數(shù)據(jù),也就是說(shuō)一個(gè)邏輯單元中有多個(gè) db 節(jié)點(diǎn),不同節(jié)點(diǎn)之間通常通過(guò)復(fù)制的方式來(lái)實(shí)現(xiàn)數(shù)據(jù)的同步。比如 MySQL 的的基于 Binlog 的主從同步、Redis 的基于 Sync/Psync 機(jī)制的 AOF 主從同步、MongoDB 基于 oplog 的主從同步等等。這些機(jī)制支撐了一個(gè)單元下的數(shù)據(jù)冗余高可用和讀寫(xiě)分離負(fù)載分擔(dān)。
但僅僅一個(gè)邏輯單元內(nèi)的數(shù)據(jù)同步對(duì)于很多業(yè)務(wù)通常不夠用,很多業(yè)務(wù)需要跨邏輯單元的數(shù)據(jù)同步的能力。例如:同城多機(jī)房、異地多數(shù)據(jù)中心同步等。容災(zāi)、多活是最常見(jiàn)的兩種業(yè)務(wù)場(chǎng)景,擴(kuò)展開(kāi)來(lái)還可以有讀寫(xiě)分離,負(fù)載分擔(dān)等多種場(chǎng)景。
現(xiàn)在越來(lái)越多的公司選擇將基礎(chǔ)業(yè)務(wù)部署到云上,那么這些能力都需要云廠商能夠提供,以提高服務(wù)的質(zhì)量,更好的為用戶(hù)的業(yè)務(wù)服務(wù)。另外,最近混合云場(chǎng)景大熱,其原因有多種,既有云廠商的原因,也有用戶(hù)業(yè)務(wù)變化的原因,但這最終要求了從云下到云上,云上到云下,跨云不同云廠商之間的互相同步的能力。
1.1 容災(zāi)
容災(zāi)通常用于數(shù)據(jù)的備份,備份數(shù)據(jù)對(duì)外不提供服務(wù),或者僅提供讀服務(wù)。在機(jī)房發(fā)生故障的時(shí)候,備份數(shù)據(jù)庫(kù)代替原數(shù)據(jù)庫(kù)對(duì)外提供服務(wù)。一般來(lái)說(shuō),業(yè)務(wù)的服務(wù)治理模塊發(fā)現(xiàn)原服務(wù)不可用后,選擇代理層進(jìn)行流量的轉(zhuǎn)發(fā),或者采用 DNS 進(jìn)行切流。其機(jī)制基本類(lèi)似,都是將發(fā)送到原數(shù)據(jù)庫(kù)的流量轉(zhuǎn)發(fā)到備份數(shù)據(jù)庫(kù)。
容災(zāi)系統(tǒng)對(duì) RPO(故障恢復(fù)時(shí)間)和 RTO(恢復(fù)數(shù)據(jù)的時(shí)間點(diǎn))都有要求。比如:故障要求 3 分鐘內(nèi)恢復(fù),恢復(fù)的數(shù)據(jù)最多容忍丟失 1s,這些都需要數(shù)據(jù)同步和服務(wù)治理發(fā)現(xiàn)配合完成。如果 RPO 和 RTO 的要求很高,那么全量備份通常不可取。因?yàn)槿總浞萃ǔJ嵌ㄆ诘模热缫惶煲淮?,假如故障的時(shí)間恰好發(fā)生在全量備份之前,這意味著這接近一天的數(shù)據(jù)丟失了。數(shù)據(jù)只能恢復(fù)到一天之前。所以這就要求了具有一個(gè)實(shí)時(shí)增量的熱備份能力。
因?yàn)閿?shù)據(jù)的全量和增量不斷同步,例如:Redis 的 RDB 文件和 AOF 文件,如果 Redis 發(fā)生不可服務(wù),這些 RDB + AOF 文件可以恢復(fù)成一個(gè)數(shù)據(jù)庫(kù)繼續(xù)提供服務(wù)。再譬如:MongoDB 的全量 Snapshot + Oplog 增量,也可以恢復(fù)成一個(gè)完整的數(shù)據(jù)庫(kù)。
另外,備份還可以分為邏輯備份和物理備份。邏輯備份通常指的是數(shù)據(jù)庫(kù)的邏輯層面通過(guò)全量文件 + Binlog 文件來(lái)實(shí)現(xiàn),而物理備份通常指引擎層面來(lái)進(jìn)行備份。
以上提到了關(guān)于備份,有很多劃分種類(lèi)。比如:冷熱備份、冷熱恢復(fù)、物理、邏輯備份、全量、增量備份等等,關(guān)于這些概念如果不清晰可以自行搜索一下。此外,我們?cè)诒拘」?jié)的開(kāi)頭提到,備份還可以提供一個(gè)讀服務(wù),那對(duì)于這種場(chǎng)景來(lái)說(shuō),備份數(shù)據(jù)不能單單是一些文件,例如:RDB 文件,AOF 文件等,而需要是一個(gè)完整可服務(wù)的數(shù)據(jù)庫(kù),所以這種場(chǎng)景下,通常也需要是一個(gè)實(shí)時(shí)增量的熱備份。
1.2 多活
多活對(duì)于數(shù)據(jù)庫(kù)層面來(lái)說(shuō),指的是跨邏輯單元的多個(gè)數(shù)據(jù)庫(kù)同時(shí)對(duì)外提供服務(wù),這些不同單元的數(shù)據(jù)庫(kù)具有部分相同或者全部相同的數(shù)據(jù)。這通常用于解決因地域網(wǎng)絡(luò)傳輸層面帶來(lái)的問(wèn)題,也就是異地多活。比如:業(yè)務(wù)層面在北京機(jī)房寫(xiě)入一條數(shù)據(jù),要求在上海機(jī)房也能讀到這條數(shù)據(jù);同樣反過(guò)來(lái)也可以,在上海機(jī)房寫(xiě)入的數(shù)據(jù),在北京也能讀到。
多活的模式看起來(lái)很好,能解決很多業(yè)務(wù)層面的問(wèn)題,但同時(shí)有很多問(wèn)題和挑戰(zhàn):
如何解決雙向復(fù)制的問(wèn)題?
兩個(gè)數(shù)據(jù)庫(kù)互相同步數(shù)據(jù),那難免數(shù)據(jù)會(huì)成環(huán)導(dǎo)致風(fēng)暴。
舉個(gè)例子:假如 A 數(shù)據(jù)庫(kù)和 B 數(shù)據(jù)庫(kù)互相同步,我在 A 數(shù)據(jù)庫(kù)插入一條數(shù)據(jù):insert x。那么這條數(shù)據(jù)通過(guò)同步鏈路會(huì)被同步到 B 數(shù)據(jù)庫(kù),這時(shí)候 B 數(shù)據(jù)庫(kù)也插入了這條數(shù)據(jù):insert x。又由于反向同步鏈路的存在,這條數(shù)據(jù)又會(huì)被同步回 A 數(shù)據(jù)庫(kù): insert x。長(zhǎng)此往復(fù),數(shù)據(jù)就成環(huán)了。
該怎么辦呢?答案就是,這種雙向復(fù)制如果僅依賴(lài)通道層面來(lái)解決基本不可行。通常需要配合數(shù)據(jù)庫(kù)內(nèi)核或者業(yè)務(wù)層面來(lái)解決,比如:數(shù)據(jù)庫(kù)內(nèi)核增加全局唯一字段,標(biāo)識(shí)數(shù)據(jù)產(chǎn)生地,而通道在拉取數(shù)據(jù)時(shí),只拉取數(shù)據(jù)的產(chǎn)生地 id=當(dāng)前數(shù)據(jù)庫(kù) id 的數(shù)據(jù),打破成環(huán)。亦或者在鏈路層面增加過(guò)濾,比如從源庫(kù)只拉取 db=a,b 的數(shù)據(jù),從目的庫(kù)只拉取 db=c 的數(shù)據(jù)。
這樣數(shù)據(jù)保證不會(huì)成環(huán),而源和目的兩個(gè)庫(kù)都有全套的db=a, b, c 三個(gè)數(shù)據(jù)庫(kù)的數(shù)據(jù)。然后通過(guò)業(yè)務(wù)層面配合,將 db=a, b 庫(kù)的寫(xiě)數(shù)據(jù)分發(fā)到源庫(kù),db=c 庫(kù)的寫(xiě)數(shù)據(jù)分發(fā)到目的庫(kù)來(lái)實(shí)現(xiàn)。對(duì)于開(kāi)源數(shù)據(jù)庫(kù)模式下,第二種模式也是最常見(jiàn)的模式,在后面介紹 MongoShake 和 RedisShake 我們會(huì)詳細(xì)介紹這種模式。
如何解決數(shù)據(jù)雙寫(xiě)的問(wèn)題?
也就是說(shuō),如何保證在兩個(gè)數(shù)據(jù)庫(kù)同時(shí)對(duì)一條數(shù)據(jù)進(jìn)行操作,而結(jié)果是正確的。
同樣舉個(gè)例子,假設(shè)在源數(shù)據(jù)庫(kù) A 和目的數(shù)據(jù)庫(kù) B 有一條數(shù)據(jù) x=1,我先在 A 庫(kù)操作了 set x=2,而后在B庫(kù)操作了 set x=3,那么能保證最后2個(gè)庫(kù)的結(jié)果都是 3 嗎?
答案是否定的,因?yàn)閿?shù)據(jù)同步是最終一致性,而最終一致性勢(shì)必是有時(shí)間窗口的。在 B 庫(kù)操作 set x=3 的時(shí)候,可能 A 庫(kù)之前的 set x=2 語(yǔ)句還沒(méi)有完成同步,那么先 set x=3,后同步 set x=2,結(jié)果目的端就變成了 2,而源端同步了set x=3 結(jié)果變成了3,這樣數(shù)據(jù)就變成了不一致。
當(dāng)然我這里只是隨便舉個(gè)例子,還有很多不一致的情況。那么解決這種問(wèn)題同樣也需要兩種手段,其一就是內(nèi)核層面,其二就是業(yè)務(wù)配合。內(nèi)核層面解決的比如 CRDT,其基于一個(gè)向量時(shí)鐘來(lái)處理消息的分發(fā),那么向量時(shí)鐘也會(huì)帶來(lái)沖突,對(duì)于沖突的處理需要借助一些手段,比如 last write win、客戶(hù)端解決等等。而很多數(shù)據(jù)庫(kù)本身對(duì) CRDT 的支持很不夠,所以這種方案有比較大的局限性。其二就是類(lèi)似我在如何解決雙向復(fù)制的問(wèn)題里面講到的,對(duì)業(yè)務(wù)流量進(jìn)行分流解決,由業(yè)務(wù)保證不會(huì)在同步通道的兩側(cè)同時(shí)對(duì)一條數(shù)據(jù)進(jìn)行操作。
現(xiàn)在數(shù)據(jù)庫(kù)層面的多活,大部分都是一種偽多活,通常都需要業(yè)務(wù)層面配合分流來(lái)解決。下面我在 MongoShake 和 RedisShake 章節(jié),會(huì)對(duì)這種業(yè)務(wù)配合的方式進(jìn)行展開(kāi)討論。
2. 遷移
從廣義來(lái)說(shuō),遷移應(yīng)該算是同步的一種模式。同步側(cè)重于增量,而遷移側(cè)重于全量。遷移通常說(shuō)的是數(shù)據(jù)庫(kù)的搬遷,將源數(shù)據(jù)庫(kù)搬遷到目的數(shù)據(jù)庫(kù),搬遷之后目的數(shù)據(jù)庫(kù)代替源數(shù)據(jù)庫(kù)繼續(xù)提供服務(wù),源數(shù)據(jù)庫(kù)可以選擇下線或者繼續(xù)提供服務(wù)。
遷移有多種場(chǎng)景,比如:同種數(shù)據(jù)庫(kù)下異構(gòu)模式遷移。例如:Redis 的主從版遷移到集群版;可以是數(shù)據(jù)庫(kù)的升級(jí)遷移,比如:MongoDB 從 3.0 升級(jí)到 4.0;也可以是上云遷移,比如:云下的數(shù)據(jù)庫(kù)遷移到云上,或者云上的遷移到云下等等。
遷移的同時(shí),源數(shù)據(jù)庫(kù)可寫(xiě)可不寫(xiě),不寫(xiě)的話(huà)稍微簡(jiǎn)單一些。遷移往往不需要遷移增量,只需要做全量遷移即可,但這通常需要業(yè)務(wù)停寫(xiě),很多業(yè)務(wù)難以接受。可寫(xiě)的話(huà)比較符合大部分業(yè)務(wù)場(chǎng)景,但對(duì)遷移的鏈路就需要有個(gè)全量+增量遷移的能力。等遷移完畢,用戶(hù)可以對(duì)遷移后的數(shù)據(jù)進(jìn)行校驗(yàn),發(fā)現(xiàn)沒(méi)問(wèn)題了,等待一個(gè)業(yè)務(wù)時(shí)間點(diǎn)進(jìn)行一次閃斷切流,將流量分發(fā)到目的端,數(shù)據(jù)就完成了遷移,源數(shù)據(jù)庫(kù)就可以下線了。
上述我提到了,遷移可以用于云下到云上,云上到云下這種混合云場(chǎng)景的遷移。但現(xiàn)在對(duì)于很多云廠商來(lái)說(shuō),從云上到云下的遷移可能比云下到云上的遷移困難一些,因?yàn)樵粕系皆葡碌耐叫枰軌驈脑粕侠?shù)據(jù)。對(duì)于一些數(shù)據(jù)庫(kù)來(lái)說(shuō),這些拉取的權(quán)限很可能沒(méi)有開(kāi)放。例如:Redis 的Sync 遷移,需要源端開(kāi)放 Sync/Psync 權(quán)限,而很多云廠商出于安全角度考慮是不支持的。這就對(duì)遷移工具提出了另一個(gè)挑戰(zhàn),而應(yīng)對(duì)這個(gè)挑戰(zhàn)的方式要么就是云廠商支持這種模式,要么就是換一種其他遷移方式。對(duì)于阿里云來(lái)說(shuō),已經(jīng)開(kāi)放了用戶(hù)的復(fù)制權(quán)限,使得用戶(hù)可以通過(guò) Sync/Psync 進(jìn)行數(shù)據(jù)的拉取。另外,RedisShake 本身也支持了其他繞過(guò) Sync/Psync 的同步遷移方式,后續(xù)我都會(huì)介紹。
3. MongoShake & RedisShake同步遷移工具
阿里云開(kāi)源了 MongoShake 和 RedisShake,可以用于 MongoDB 和 Redis 的同步和遷移,進(jìn)一步實(shí)現(xiàn)用戶(hù)對(duì)災(zāi)備和多活的需求。
3.1 MongoShake
MongoShake 的同步是基于 Oplog 實(shí)現(xiàn)的,v1.5 版本開(kāi)始支持全量同步。其內(nèi)部具體實(shí)現(xiàn)細(xì)節(jié)可以參考我在云棲社區(qū)上寫(xiě)的文章,本小節(jié)主要從功能和應(yīng)用場(chǎng)景來(lái)進(jìn)行介紹。
項(xiàng)目地址:http://t.cn/AiTChwoV
首先介紹一下主要的功能:
- 全量同步:從源端拉取全量數(shù)據(jù)寫(xiě)入到目的端。
- 增量同步:拉取源端的增量數(shù)據(jù),寫(xiě)入到目的端。作為同步遷移工具,MongoShake 最主要的功能肯定是數(shù)據(jù)的同步,全量加增量就是實(shí)現(xiàn)數(shù)據(jù)同步的基礎(chǔ)。上面我們提到的災(zāi)備和多活功能就是基于這兩個(gè)來(lái)實(shí)現(xiàn)的。
- 過(guò)濾:MongoShake 支持對(duì)數(shù)據(jù)按庫(kù)、表過(guò)濾,這樣就能夠?qū)崿F(xiàn)我們?cè)谇懊嫣岬降?,雙向同步的場(chǎng)景。
- 并行復(fù)制:MongoShake 內(nèi)部采用了并行復(fù)制的策略,使得最高的 QPS 可以達(dá)到 40W。
- 壓縮:MongoShake 支持對(duì)數(shù)據(jù)進(jìn)行壓縮,通常用于遠(yuǎn)距離傳輸?shù)膱?chǎng)景。
- HA:MongoShake 可以支持集群 HA 切換,用戶(hù)可以通過(guò)啟動(dòng)多個(gè) MongoShake 來(lái)啟動(dòng)主備集群。
- 斷點(diǎn)續(xù)傳:MongoShake 通過(guò)持久化 checkpoint 信息來(lái)支持同步鏈路斷開(kāi)重連后,數(shù)據(jù)能夠重新接上進(jìn)行傳輸。
- 靈活多通道支持:MongoShake 除了支持將源數(shù)據(jù)寫(xiě)入目的庫(kù)以外,還支持多種通道,比如:TCP/RPC/File/Kafka 等,滿(mǎn)足用戶(hù)不同的需求。例如:MongoShake 可以將數(shù)據(jù)寫(xiě)入 Kafka,用戶(hù)可以從 Kafka 中拉取數(shù)據(jù),然后對(duì)接到流式計(jì)算平臺(tái)滿(mǎn)足實(shí)時(shí)計(jì)算的需求。用戶(hù)甚至可以自定義通道類(lèi)型,滿(mǎn)足特殊的業(yè)務(wù)需求。
下面來(lái)簡(jiǎn)單列舉一下,有了這些功能,我們可以做什么?也就是說(shuō)應(yīng)用場(chǎng)景有哪些?
- MongoDB 集群的異步復(fù)制,減少業(yè)務(wù)雙寫(xiě)的開(kāi)銷(xiāo)。
- MongoDB 集群的災(zāi)備、多活、讀寫(xiě)分離等業(yè)務(wù)部署。
- 基于 MongoDB Oplog 的日志分析平臺(tái)。
- 基于 MongoDB Oplog 的日志訂閱。用戶(hù)可以從例如 Kafka 通道中拉取日志,然后對(duì)感興趣的日志進(jìn)行訂閱。
- MongoDB 集群的數(shù)據(jù)路由。根據(jù)業(yè)務(wù)需求,結(jié)合日志訂閱和過(guò)濾機(jī)制,可以獲取關(guān)注的數(shù)據(jù),達(dá)到數(shù)據(jù)路由的功能。
- 基于日志的集群監(jiān)控。
- Cache 的反向同步??梢酝ㄟ^(guò)日志分析的結(jié)果,知道哪些 Cache 可以被淘汰,哪些 Cache 可以進(jìn)行預(yù)加載,從而反向推動(dòng) Cache 的更新。
以上只是簡(jiǎn)單列舉了幾種應(yīng)用場(chǎng)景,如果你有不同的玩法或者不同的業(yè)務(wù)需求,也歡迎跟我聯(lián)系,MongoShake 產(chǎn)品還在持續(xù)迭代更新中,后續(xù)還會(huì)有很多有用且好玩的特性會(huì)進(jìn)行持續(xù)添加。
3.2 RedisShake
RedisShake 的同步是基于向源 Redis 發(fā)送 Sync/Psync 命令,然后實(shí)現(xiàn)全量+增量拉取并回放來(lái)實(shí)現(xiàn)的。同樣,具體細(xì)節(jié)介紹請(qǐng)參考我在云棲社區(qū)發(fā)表的博客,本文主要從功能角度進(jìn)行介紹。
項(xiàng)目地址:http://t.cn/E6hqgij
RedisShake 目前主要有以下 5 大功能:
- Dump:從源 Redis 將全量 RDB 文件下載下來(lái)。
- Decode:解析指定的 RDB 文件。
- Restore:目的庫(kù)根據(jù)指定的 RDB 進(jìn)行全量恢復(fù)。
- Sync:支持?jǐn)?shù)據(jù)同步,源端可以是單節(jié)點(diǎn) Redis、主從Redis、集群Redis,也支持 Codis,目的端同樣也可以是各種模式的 Redis。
- Rump:支持對(duì)源端進(jìn)行 Key 掃描并全量遷移。這個(gè)主要是應(yīng)對(duì)一些云廠商沒(méi)有開(kāi)放 Sync/Psync 權(quán)限的情況下,進(jìn)行全量遷移的場(chǎng)景。
RedisShake 的 Sync 模式是目前使用最為廣泛的模式,其通過(guò) RDB 全量并發(fā)同步。以及增量異步寫(xiě)入的方式來(lái)提高同步的性能,理論上可以達(dá)到毫秒級(jí)別的同步延遲。此外,用戶(hù)還可以根據(jù) redis-full-check 來(lái)進(jìn)行數(shù)據(jù)同步后的一致性校驗(yàn),保證數(shù)據(jù)的正確性。
RedisShake 的場(chǎng)景以同步為主,如果用戶(hù)有特定的需求,也歡迎告知我們,比如類(lèi)似 MongoShake 的離線計(jì)算等場(chǎng)景。目前 RedisShake 處于剛開(kāi)源階段,功能點(diǎn)迭代比較快,歡迎大家關(guān)注。
4. 使用案例
本節(jié)主要介紹一下用戶(hù)根據(jù)我們的 MongoShake 和 RedisShake 的使用案例
4.1 高德地圖
高德地圖 App 是國(guó)內(nèi)首屈一指的地圖及導(dǎo)航應(yīng)用,阿里云 MongoDB 數(shù)據(jù)庫(kù)服務(wù)為該應(yīng)用提供了部分功能的存儲(chǔ)支撐,存儲(chǔ)億級(jí)別數(shù)據(jù)?,F(xiàn)在高德地圖使用國(guó)內(nèi)雙中心的策略,通過(guò)地理位置等信息路由最近中心提升服務(wù)質(zhì)量,業(yè)務(wù)方(高德地圖)通過(guò)用戶(hù)路由到三個(gè)城市數(shù)據(jù)中心,如下圖所示,機(jī)房數(shù)據(jù)之間無(wú)依賴(lài)計(jì)算。
??
這三個(gè)城市地理上從北到南橫跨了整個(gè)中國(guó) ,這對(duì)多數(shù)據(jù)中心如何做好復(fù)制、容災(zāi)提出了挑戰(zhàn)。如果某個(gè)地域的機(jī)房、網(wǎng)絡(luò)出現(xiàn)問(wèn)題,可以平滑的將流量切換到另一個(gè)地方,做到用戶(hù)幾乎無(wú)感知?
目前我們的策略是,拓?fù)洳捎脵C(jī)房?jī)蓛苫ヂ?lián)方式,每個(gè)機(jī)房的數(shù)據(jù)都將同步到另外兩個(gè)機(jī)房。然后通過(guò)高德的路由層,將用戶(hù)請(qǐng)求路由到不同的數(shù)據(jù)中心,讀寫(xiě)均發(fā)送在同一個(gè)數(shù)據(jù)中心,保證一定的事務(wù)性。然后再通過(guò) MongoShake,雙向異步復(fù)制兩個(gè)數(shù)據(jù)中心的數(shù)據(jù),這樣保證每個(gè)數(shù)據(jù)中心都有全量的數(shù)據(jù)(保證最終一致性) 。如下圖所示:
任意機(jī)房出現(xiàn)問(wèn)題,另兩個(gè)機(jī)房中的一個(gè)可以通過(guò)切換后提供讀寫(xiě)服務(wù)。下圖展示了城市 1 和城市 2 機(jī)房的同步情況。
遇到某個(gè)單元不能訪問(wèn)的問(wèn)題,通過(guò) MongoShake 對(duì)外開(kāi)放的 Restful 管理接口,可以獲得各個(gè)機(jī)房的同步偏移量和時(shí)間戳,通過(guò)判斷采集和寫(xiě)入值即可判斷異步復(fù)制是否在某個(gè)時(shí)間點(diǎn)已經(jīng)完成。再配合業(yè)務(wù)方的 DNS 切流,切走單元流量并保證原有單元的請(qǐng)求在新單元是可以讀寫(xiě)的,如下圖所示。
4.2 某跨境電商
某跨境電商在中國(guó)和海外分別部署了 2 套 MongoDB,其中海外主庫(kù)上提供讀寫(xiě)服務(wù),同時(shí)用戶(hù)希望把海外的數(shù)據(jù)拉到國(guó)內(nèi)進(jìn)行離線計(jì)算,以及承擔(dān)一部分讀流量,以下是該用戶(hù)采用 MongoShake 搭建的鏈路方案:
4.3 某著名游戲廠商
某著名游戲廠商采用了 MongoShake 搭建了異地容災(zāi)鏈路。用戶(hù)在 2 個(gè)機(jī)房分別部署了 2 套應(yīng)用,正常情況下用戶(hù)流量通過(guò)北向的 DNS/SLB 只訪問(wèn)主應(yīng)用,然后再訪問(wèn)到主 MongoDB,數(shù)據(jù)通過(guò) MongoShake 在 2 個(gè)機(jī)房的數(shù)據(jù)庫(kù)之間進(jìn)行同步,一旦機(jī)房 1 不可用,DNS/SLB 將用戶(hù)流量切換到備上,然后繼續(xù)對(duì)外提供讀寫(xiě)服務(wù)。
4.4 采用 Shake 的開(kāi)源多活方案
這里是我們給出的根據(jù) Shake 創(chuàng)建多活的方案,包括 MongoShake 和 RedisShake。
上文我們介紹在開(kāi)源 MongoDB 下,可以根據(jù)控制流量分發(fā)來(lái)達(dá)到多活的需求。比如下面這個(gè)圖,用戶(hù)需要編寫(xiě)一個(gè) Proxy進(jìn)行流量分發(fā)(紅色框)部分流量,比如對(duì) a, b 庫(kù)的寫(xiě)操作分發(fā)到左邊的 DB,對(duì) c 庫(kù)的寫(xiě)操作分發(fā)到右邊的 DB,源庫(kù)到目的庫(kù)的 Shake 鏈路只同步 a, b 庫(kù)( MongoShake 和 RedisShake 均提供按庫(kù)過(guò)濾功能),目的庫(kù)到源庫(kù)的 Shake 鏈路只同步 c 庫(kù)。這樣就解決了環(huán)形復(fù)制的問(wèn)題。
總結(jié)來(lái)說(shuō),也就是寫(xiě)流量通過(guò) Proxy 進(jìn)行固定策略的分發(fā),而讀流量可以隨意分發(fā)到任意 DB。
4.5 采用 Shake 的級(jí)聯(lián)同步方案
這個(gè)是一個(gè)全球的部署的用戶(hù)采用 Shake 搭建的全球混合云級(jí)聯(lián)方案的示例圖。有些數(shù)據(jù)庫(kù)位于云上,有些位于云下,Shake 提供了混合云不同云環(huán)境的同步,還可以直接級(jí)聯(lián)方式的集群同步。
5. 總結(jié)
總結(jié)主要介紹了一下數(shù)據(jù)庫(kù)同步和遷移的場(chǎng)景,然后結(jié)合功能和應(yīng)用場(chǎng)景介紹了下我們開(kāi)源的兩款 Shake 工具。目前,我們的 Shake 工具還在持續(xù)功能迭代中,歡迎關(guān)注我們的 Github,有任何問(wèn)題歡迎在 Github 上進(jìn)行提問(wèn),也歡迎分享你們的使用場(chǎng)景,以幫助我們更好的完善產(chǎn)品。