咱們在去年開源了MongoShake,能夠用於MongoDB的數據同步,知足用戶多種需求,總體介紹文檔參考這裏。今天,我來主要介紹一下MongoShake的最佳實踐,主要涵蓋如下幾部分:linux
MongoShake的下載路徑咱們提供在了github上,點擊能夠下載不一樣版本的mongoshake:mongo-shake-x.y.z.tar.gz
。目前MongoShake提供了配置文件啓動的方式,啓動的命令行:./collector.linux -conf=collector.conf
,不一樣的平臺請選擇不一樣的二進制文件,如windows下是collector.windows。git
全部的參數都列在了配置文件裏面,目前配置文件較多,用戶可能比較困惑,正常狀況下用戶默認就行,修改的參數只有少部分。
MongoShake支持MongoDB副本集和集羣版的互相同步,還能夠同步到kafka模式,下面列出了幾種常見的同步模式。github
假設源端是三副本:10.1.1.1:1001, 10.2.2.2:2002, 10.3.3.3:3003,目的端也是三副本:10.5.5.5:5005, 10.6.6.6:6006, 10.7.7.7:7007。同步模式是全量+增量同步。
則用戶須要修改如下幾個參數:golang
mongo_urls = mongodb://username:password@10.1.1.1:1001,10.2.2.2:2002,10.3.3.3:3003 #源端鏈接串信息,逗號分隔不一樣的mongod sync_mode = all # all 表示全量+增量,document表示僅全量,oplog表示僅增量 tunnel.address = mongodb://username:password@10.5.5.5:5005, 10.6.6.6:6006, 10.7.7.7:7007 #目的端鏈接串信息,逗號分隔不一樣的mongod
假設源一樣是三副本:10.1.1.1:1001, 10.2.2.2:2002, 10.3.3.3:3003,目的端是sharding,有多個mongos:20.1.1.1:2021, 20.2.2.2:2022, 20.3.3.3:3033。mongodb
mongo_urls = mongodb://username:password@10.1.1.1:1001,10.2.2.2:2002,10.3.3.3:3003 #源端鏈接串信息,逗號分隔不一樣的mongod sync_mode = all # all 表示全量+增量,document表示僅全量,oplog表示僅增量 tunnel.address = mongodb://username:password@20.1.1.1:2021;20.2.2.2:2022;20.3.3.3:3033 #目的端鏈接串信息,分號分割不一樣的mongos。也能夠只配置部分,配置多個mongos能夠作負載均衡寫入。
假設源是2節點:節點1是10.1.1.1:1001, 10.1.1.2:2002, 10.1.1.3:3003;節點2是10.2.2.1:1001, 10.2.2.2:2002, 10.2.2.3:3003。目的端是sharding,有多個mongos:20.1.1.1:2021, 20.2.2.2:2022, 20.3.3.3:3033。數據庫
mongo_urls = mongodb://username1:password1@10.1.1.1:1001,10.1.1.2:2002,10.1.1.3:3003;mongodb://username2:password2@10.2.2.1:1001,10.2.2.2:2002,10.2.2.3:3003 #源端鏈接串信息,逗號分隔同一個shard不一樣的mongod,分號分隔不一樣的shard。 sync_mode = all # all 表示全量+增量,document表示僅全量,oplog表示僅增量 tunnel.address = mongodb://username:password@20.1.1.1:2021;20.2.2.2:2022;20.3.3.3:3033 #目的端鏈接串信息,分號分割不一樣的mongos。也能夠只配置部分,配置多個mongos能夠作負載均衡寫入。 context.storage.url = mongodb://username1:password1@10.5.5.5:5555,10.5.5.6:5556 # 若是源端是sharding,此處須要配置源端sharding的cs的地址
假設源一樣是三副本:10.1.1.1:1001, 10.2.2.2:2002, 10.3.3.3:3003,目的kafka是50.1.1.1:6379,topic是test。windows
mongo_urls = mongodb://username:password@10.1.1.1:1001,10.2.2.2:2002,10.3.3.3:3003 #源端鏈接串信息,逗號分隔不一樣的mongod sync_mode = oplog # 若是目的端不是mongodb,僅支持增量同步模式 tunnel.type = kafka tunnel.address = test@50.1.1.1:6379
雲上副本集的雙向同步能夠參考副本集的單向同步,可是須要注意的有如下幾點,假設A和B之間雙向同步:api
具體請查看配置文件的註釋,此處只作簡單解釋restful
此處記載幾個常見的問題:網絡
A: 不會同步。若是用戶必定要把admin的庫同步到別的,那麼能夠經過命名轉換功能(配置transform.namespace)把admin庫同步到別的數據庫,同時配置filter.pass.special.db參數:
A: 用戶能夠下降全量同步配置replayer的相關參數,以下降目的端壓力。
A: 用戶能夠定位一下看看目的慢的緣由是什麼,正常狀況下能夠提升全量配置replayer的相關參數,以提升全量同步的性能。但也有可能,問題的瓶頸是源端/網絡端/通道cpu,內存等壓力太高,都是有可能的。
A: checkpoint是記錄增量同步的位點狀況,mongoshake的啓動就是根據這個位點來進行的,好比咱們已經同步到10點鐘了,那麼這個時候掛掉了,若是沒有位點,那麼只能從頭開始拉,位點的意義就是在於斷點續傳。在mongoshake中,位點信息是以64位時間戳來標記的(ts字段,準確的說是32位時間戳+計數),若是發生掛掉重啓,那麼會從源庫的oplog表中尋找這個位點,並今後開始日後進行同步。
到這裏,用戶可能會問,那麼mongoshake裏面位點是存儲在哪裏的?存儲的位置就是取決於用戶context的相關配置,以副本集爲例,checkpoint是存儲於源庫的mongoshake庫的ckpt_default表,其大概內容長這個樣子:
rszz-4.0-2:PRIMARY> use mongoshake switched to db mongoshake rszz-4.0-2:PRIMARY> show collections ckpt_default rszz-4.0-2:PRIMARY> db.ckpt_default.find() { "_id" : ObjectId("3d75e8b872d91278c3be0cc9"), "name" : "rszz-4.0-2", "ckpt" : Timestamp(1566556865, 196096) }
其中ckpt對應的field就是checkpoint。
用戶可能還會問,那麼mongoshake的checkpoint是怎麼存儲的,何時會存儲?答案是,checkpoint是按期存儲的,若是有數據同步,那麼checkpoint的更新會很頻繁(秒級別);若是沒有數據同步,好比這個時候用戶源端就是沒有寫入,那麼默認是分鐘級別更新一次心跳checkpoint。假設mongoshake數據位點記錄是10:00:00,可是數據已經同步到10:00:10,這個時候mongoshake掛掉了,下次會從10:00:00從新開始同步,因爲DML自己具備冪等性,數據的重複回放是OK的。那麼用戶可能會問,DDL怎麼辦?參考下面問題。
A: 設置replayer.dml_only = false
能夠同步DDL。DDL不能保證冪等性。在mongoshake裏面,若是發現是DDL語句,會卡一個全局的barrier,讓當前DDL語句同步,而後再卡一個全局barrier,等當前DDL語句同步完成,再接着併發同步接下來的oplog,barrier的卡鎖伴隨着checkpoint的強制刷新。可是因爲DDL同步和checkpoint的刷新並非一個院子操做,若是用戶剛好在同步DDL完成和checkpoint刷新之間,進程掛掉了,那麼沒有辦法,重啓之後確定會持續報錯,用戶須要手動運維解決,好比跳過這個DDL,或者目的端近些一個反向操做(原來DDL是建庫,須要進行刪除庫;原來是建索引,須要進行刪索引操做)。可是,這個機率很低。
A: 不會,會持續報錯,用戶須要關注日誌的運行狀況。
A: mongoshake有提供restful接口,能夠監控mongoshake的內部同步狀況,參考wiki: How to monitor the MongoShake,正常狀況下lsn_ckpt.time會一直增加,若是這個數值不增加了,那麼就表示同步出現問題了。
A: 會同步索引,顯示全量同步,全量同步完畢後會同步索引,接着是增量同步。
A: 顯示全量同步,全量同步完畢會寫入checkpoint,而後進行增量同步,增量同步階段會不斷更新checkpoint。對於mongoshake來講,是否進行全量同步取決於checkpoint,若是checkpoint存在且合法,那麼只會進入增量同步;不然,會先進行全量同步,而後是增量。那麼checkpoint怎麼知道是存在的,就是context裏面的參數的位置決定;那麼怎麼知道checkpoint是合法的?若是最老的oplog的時間位點小於checkpoint,那麼就是合法的,證實增量能接上。
A: 最須要注意的就是,全量同步完畢,增量可否接上。mongoshake是根據oplog的位點來決定全量結束是否要進行增量,若是全量花了2天,可是oplog表只能存儲1天,那麼全量同步完畢之後mongoshake就會報錯退出,這是由於增量的位點丟失了。因此若是全量很大,同步時間勢必好久,那麼就須要放大oplog的表的大小以維持增量oplog。
其餘還須要注意的就是壓力問題,如何選取適當的參數應對對於源端/目的端的壓力,減小對業務的影響。用戶也能夠決定從一個hidden結點,護着一個獨立的secondary結點進行拉取。
A: 這個我在github的wiki基本都有總結,能夠先看下github的faq。若是裏面沒有提到的,能夠提交issue進行反饋。
A: 目前script下面有個comparison.py的全量校驗腳本校驗數據的一致性。那麼如何進行增量的校驗呢?目前尚未,敬請期待。
A: 若是源端是sharding,那麼目前須要關閉balancer,在v2.1非穩定版本里面,咱們支持了不關閉balancer,用戶能夠進行試用,可是目前這個是非穩定版本。此外源端若是是sharding,DDL的同步(replayer.dml_only = false)不能開啓。
A: 請先看下wiki: https://github.com/alibaba/MongoShake/wiki/FAQ#q-how-to-connect-to-different-tunnel-except-direct。
kafka通道中的數據是有控制信息在裏面的,用戶很差直接剝離,能夠用receiver進行對接。目前receiver對接後全部oplog都打印到控制檯,用戶也能夠本身修改receiver代碼,對接下游服務。固然,這個須要用戶懂golang語言,這可能有一些學習成本在裏面。後面咱們會看看如何以更好的形式對接給用戶。
A: 目前全量階段因爲是掃表等操做,會對源端產生一些影響。增量階段,正常狀況影響很小,由於目前oplog找對應ts是二分模式。
A: 能夠,須要啓動多個mongoshake。對於不一樣的mongoshake,能夠修改寫入不一樣地方的checkpoint便可(好比表名修改一下),或者直接修改不一樣的collector.id。此外,須要注意的是,同一個目錄下啓動多個mongoshake,若是collector.id相同,是沒法啓動成功的。參考:https://github.com/alibaba/MongoShake/wiki/FAQ#q-how-to-sync-data-from-one-mongodb-to-several-target-mongodb
本文爲雲棲社區原創內容,未經容許不得轉載。