基于Go的MongoDB實時同步工具及 Docker 化實踐

內容來源:2017年2月25日,訊聯數據高級軟件工程師馬艷云在“New version, New vision”進行《基于Go的MongoDB實時同步工具及Docker化實踐》演講分享。IT 大咖說(ID:itdakashuo)作為獨家視頻合作方,經主辦方和講者審閱授權發布。

閱讀字數:1772?| 4分鐘閱讀

獲取嘉賓演講視頻回放及PPT,請點擊:http://t.cn/E7JofKR

摘要

訊聯數據高級軟件工程師馬艷云分享了基于Go的MongoDB實時同步工具Magisync及 Docker化實踐。

Magisync是什么

Magisync是用Go語言開發的MongoDB到MongoDB或其他多種數據庫之間的實時同步工具。

為什么選擇 Go

在我們的生產應用當中,對Go語言有比較成熟的應用。我們的核心交易系統就是 Go 語言開發的。從開發到運行,Go 語言相對來說語法比較簡單,使用方便。還有一個原因就是在 GitHub 上有一個用 Go 語言開發的同步的程序可以供我們參考。

為什么開發 Magisync

交易量日益增多,從2015年8月到2016年8月,我們的交易量整整增長了100倍,原有的系統架構不能滿足業務需求。我們要通過數據庫拆分實現冷熱數據分離,災備系統的搭建要跨機房同步,這一系列需求導致我們需要找到一個工具能夠支持MongoDB的數據,而當時市面上并沒有適合我們的MongoDB實時同步工具。

于是我們不得不自己開發這樣一款工具,但當時對于我們來說這也是非常具有挑戰性的一件事,因為我們做金融支付對數據的實時一致性要求非常高。

Magisync 同步特性

支持從特定時間點開始同步,支持選擇同步特定表的特定類型的操作,支持斷點續傳式同步,QPS目前在3000左右,支持限流。

Magisync 同步原理

簡單來說,Magisync一直監聽MongoDB的日志集合oplog ,如果源數據庫有新的操作產生,oplog集合中會生成有新的記錄,這時,Magisync會立刻拿到oplog中新的日志記錄,并將其實時的同步至目標數據庫。Magisync同步的核心就是oplog。

Oplog

Oplog是MongoDB的復制集存儲寫操作的一個日志,它的存儲位置是在local庫的oplog.rs表中。這張表是Capped Collection類型,是MongoDB特有的一種類型,可以用類似于Unix中的tail -f命令來獲取oplog。

Oplog 的格式

不同版本的 oplog 的格式稍有不同,我們生產環境使用的 MongoDB的版本是3.0.3, oplog 示例如下:

{

"ts" : Timestamp(1477194593, 1),

"t" : NumberLong(12),

"h" : NumberLong(8657529515144482533),

"v" : NumberInt(2),

"op" : "i",

"ns" : "caroldb.user",

"o" : {

"_id" : ObjectId("580c333e7afa56085f89a00d"),

"name" : "mike",

"age" : NumberInt(20)

}

}

Magisync 特性說明

1、Magisync如果重啟,如何知道該從哪個時間點同步?

Magisync各個協程去往目標數據同步之后,會將同步的狀態寫入oplogMonitor表中,每個協程在oplogMonitor表中都有一條對應的記錄。等到Magisync重啟時,則會讀取oplogMonitor中最小的ts ,然后去源數據庫拉取oplog。

2、Magisync用多協程去執行oplog,如何保證oplog執行不會錯序?

主線程讀取到oplog后,會解析出ObjectId,取模后將其放入各個worker對應的chan中。同一條數據,插入,更新等操作會進去到同一個worker中。

3、Magisync的故障處理機制?

如果讀取oplog失敗,Magisync會重連,重新讀取oplog ; 如果操作目標數據庫失敗,Magisync會根據情況判斷是否需要重連,或者重試。

4、Magisync如何限流?

限流采用的是令牌桶的算法,會有一個協程定時的(比如每秒)向一個桶里放一定數量的令牌。主線程每讀取一條oplog,計算oplog的大小,從桶里消費對應的令牌數,然后對比桶里剩下的令牌數,如果小于0,則阻塞,直到下一秒桶里被放入令牌,阻塞解除。

Docker化實踐

我們為什么要使用Docker?首先是因為它真的很火,很多大型互聯網公司都支持Docker,比如騰訊、京東、美團等等。并且Docker可以快速構建應用環境,可移植性高。

Magisync 代碼示例

1、讀取oplog代碼

2、向目標數據庫寫數據

我今天的分享就到這里,謝謝大家!

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容