內容來源:2017年2月25日,訊聯數據高級軟件工程師馬豔雲在「New version, New vision」進行《基於Go的MongoDB實時同步工具及Docker化實踐》演講分享。IT 大咖說(id:itdakashuo)做爲獨家視頻合做方,經主辦方和講者審閱受權發佈。
算法
閱讀字數:1772 | 4分鐘閱讀數據庫
嘉賓演講視頻回顧及PPT:suo.im/2GfNIK
bash
訊聯數據高級軟件工程師馬豔雲分享了基於Go的MongoDB實時同步工具Magisync及 Docker化實踐。架構
Magisync是用Go語言開發的MongoDB到MongoDB或其餘多種數據庫之間的實時同步工具。app
在咱們的生產應用當中,對Go語言有比較成熟的應用。咱們的核心交易系統就是 Go 語言開發的。從開發到運行,Go 語言相對來講語法比較簡單,使用方便。還有一個緣由就是在 GitHub 上有一個用 Go 語言開發的同步的程序能夠供咱們參考。工具
交易量日益增多,從2015年8月到2016年8月,咱們的交易量整整增加了100倍,原有的系統架構不能知足業務需求。咱們要經過數據庫拆分實現冷熱數據分離,災備系統的搭建要跨機房同步,這一系列需求致使咱們須要找到一個工具可以支持MongoDB的數據,而當時市面上並無適合咱們的MongoDB實時同步工具。spa
因而咱們不得不本身開發這樣一款工具,但當時對於咱們來講這也是很是具備挑戰性的一件事,由於咱們作金融支付對數據的實時一致性要求很是高。線程
支持從特定時間點開始同步,支持選擇同步特定表的特定類型的操做,支持斷點續傳式同步,QPS目前在3000左右,支持限流。日誌
簡單來講,Magisync一直監聽MongoDB的日誌集合oplog ,若是源數據庫有新的操做產生,oplog集合中會生成有新的記錄,這時,Magisync會馬上拿到oplog中新的日誌記錄,並將其實時的同步至目標數據庫。Magisync同步的核心就是oplog。code
Oplog是MongoDB的複製集存儲寫操做的一個日誌,它的存儲位置是在local庫的oplog.rs表中。這張表是Capped Collection類型,是MongoDB特有的一種類型,能夠用相似於Unix中的tail -f命令來獲取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各個協程去往目標數據同步以後,會將同步的狀態寫入oplogMonitor表中,每一個協程在oplogMonitor表中都有一條對應的記錄。等到Magisync重啓時,則會讀取oplogMonitor中最小的ts ,而後去源數據庫拉取oplog。
主線程讀取到oplog後,會解析出ObjectId,取模後將其放入各個worker對應的chan中。同一條數據,插入,更新等操做會進去到同一個worker中。
若是讀取oplog失敗,Magisync會重連,從新讀取oplog ; 若是操做目標數據庫失敗,Magisync會根據狀況判斷是否須要重連,或者重試。
限流採用的是令牌桶的算法,會有一個協程定時的(好比每秒)向一個桶裏放必定數量的令牌。主線程每讀取一條oplog,計算oplog的大小,從桶裏消費對應的令牌數,而後對比桶裏剩下的令牌數,若是小於0,則阻塞,直到下一秒桶裏被放入令牌,阻塞解除。
咱們爲何要使用Docker?首先是由於它真的很火,不少大型互聯網公司都支持Docker,好比騰訊、京東、美團等等。而且Docker能夠快速構建應用環境,可移植性高。
一、讀取oplog代碼
二、向目標數據庫寫數據
我今天的分享就到這裏,謝謝你們!