最近需要進行MongoDB中數據遷移,之前使用過阿里系的redisShake感覺不錯, 這次打算使用mongoShake來進行同步
github: https://github.com/alibaba/MongoShake
前提條件:
遠端mongo示例需要開通oplog
將mongo-shake安裝到目的端
1. mongo開啟oplog
a) 修改配置文件 /data/mongo/mongod.conf
新增配置項
replSet=single # 這個名稱可以隨意, 最后可以做到辨識的目的
b)重啟mongo
systemctl restart mongod
首次登錄會出現報錯:
show dbs; E QUERY [thread1] Error: listDatabases failed:{undefined "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk" }
解決:
需要執行初始化命令
rs.initiate({ _id: "副本集名稱", members: [{_id:0,host:"服務器的IP:Mongo的端口號"}]}) 例如(對應上述配置): rs.initiate({ _id: "single", members: [{_id:0,host:"192.168.144.249:27017"}]}) 執行完成后提示,代表執行成功: { "ok" : 1 }
初始完副本集中唯一的節點,可能短時間顯示為SECONDARY或OTHER。一般而言,稍等一會,就會自然恢復為primary,無需人工干預。
rs:OTHER>
rs:PRIMARY>
rs:PRIMARY>
#驗證是否生成了oplog.rs表:
2.安裝mongoshake
a)下載並解壓
wget -c https://github.com/alibaba/MongoShake/archive/refs/tags/release-v2.6.5-20210723-1.tar.gz 直接下載二進制包, 免除編譯部分
wget https://github.com/alibaba/MongoShake/releases/download/release-v2.6.6-20220323/mongo-shake-v2.6.6.tar.gz
mongo-shake-v2.6.6.tar.gz tar -zxvf mongo-share-v2.6.4-20210723-1.tar.gz cd mongoshake
b)修改配置文件
#源端mongo地址 mongo_urls = mongodb://root:密碼@192.168.144.251:27017 注意,mongo的密碼不能包含@等特殊字符。 #目標端mongo地址 tunnel.address = mongodb://root:密碼@192.168.144.252:27017 sync_mode = all filter.ddl_enable = true
更多參數說明:https://github.com/alibaba/MongoShake/wiki/%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E
3. 啟動mongoshake
./collector.linux -conf /opt/tools/mongo-shake-v2.6.5/collector.conf -verbose 2
查看進程
ps -ef |grep collector | grep -v 'grep'
如果成功的時候, 源端會自動創建一個mongoshake庫
會發現源端自動創建了一個mongoshake庫: single:PRIMARY> use mongoshake; switched to db mongoshake #有一個檢查點的表 single:PRIMARY> show tables; ckpt_default
如果想同步部分的表,可以設置白名單
filter.namespace.white=aa.t1,bb,t1,cc 表示同步aa庫匯總t1表數據,bb庫t1表數據,cc庫所有數據
重點配置參數:
mongo_urls = mongodb://username:passwd@xx.xx.xx.xxx:27017 tunnel.address = mongodb://username:passwd@127.0.0.1:2701 filter.namespace.white = log_4.1000003920220228
filter.pass.special.db = admin 有些內置庫正常不會遷移, 除非指定
filter.ddl_enable = true 是否開啟DDL同步
如果想要配置同步的參數也可以修改:
full_sync.reader.collection_parallel = 6 # the number of document writer thread in each collection. # 同一個表內並發寫的線程數,例如,8表示對於同一個表,將會有8個寫線程進行並發寫入。 full_sync.reader.write_document_parallel = 8 # number of documents in a batch insert in a document concurrence # 目的端寫入的batch大小,例如,128表示一個線程將會一次聚合128個文檔然后再寫入。 full_sync.reader.document_batch_size = 128 # max number of fetching thread per table. default is 1 # 單個表最大拉取的線程數,默認是單線程拉取。需要具備splitVector權限。 # 注意:對單個表來說,僅支持索引對應的value是同種類型,如果有不同類型請勿啟用該配置項! full_sync.reader.parallel_thread = 1 # the parallel query index if set full_sync.reader.parallel_thread. index should only has # 1 field. # 如果設置了full_sync.reader.parallel_thread,還需要設置該參數,並行拉取所掃描的index,value # 必須是同種類型。對於副本集,建議設置_id;對於集群版,建議設置shard_key。key只能有1個field。 full_sync.reader.parallel_index = _id # drop the same name of collection in dest mongodb in full synchronization # 同步時如果目的庫存在,是否先刪除目的庫再進行同步,true表示先刪除再同步,false表示不刪除。 full_sync.collection_exist_drop = true
還有更多參數可以參考文檔
常見錯誤:
1.同步的時候發生了終端, 查看mongo日志, 發現會出現 報錯 Too many open files問題
這是因為連接數不夠用導致, 需要調大該值,
1、cat /etc/redhat-release CentOS release 6.8 (Final) 2、修改當前交互終端的limit值 ulimit -n 655350.此時系統的文件句柄數為655350. 3、永久修改limit值 vim /etc/security/limits.conf mongod soft nofile 655360 mongod hard nofile 655360 4、centos6還有的limit限制,/etc/security/limits.conf限制實際取決於/etc/security/limits.d/90-nproc.conf的配置,也就是說哪怕/etc/security/limits.conf設置最大打開數是65535,而/etc/security/limits.d/20-nproc.conf里配的是4096,那最終結果還是用戶最大只能打開4096個文件句柄,所以還要再修改20-nproc.conf (如果是centos7,則是/etc/security/limits.d/90-nproc.conf) vim /etc/security/limits.d/90-nproc.conf * soft nproc 655360 root soft nproc unlimited 5、OS其他地方可能影響文件最大打開句柄都做設置 vim /proc/sys/fs/file-max 655360 vim /etc/rc.d/rc.local fs.file-max=655360 vim /etc/sysctl.conf fs.file-max=655360
我這邊的進程管理工具是systemctl, 也同時增加限制條件
[Unit] Description=High-performance, schema-free document-oriented database After=network.target [Service] Type=forking ExecStart=/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/conf/mongodb.conf LimitFSIZE=infinity LimitCPU=infinity LimitAS=infinity LimitNOFILE=640000 LimitNPROC=640000 [Install] WantedBy=multi-user.target
同時增大最大連接數:
# 數據存儲目錄 dbpath=/data/mongodb/data # 日志存儲目錄 logpath=/data/mongodb/logs/mongodb.log # 進程文件 pidfilepath=/data/mongodb/mongodb.pid # 日志追加方式存儲 logappend=true # 開啟日志文件,默認開啟 journal=false #quiet=true port=27017 # 是否以守護進程方式運行 fork=true #fork=false # 不給你定IP bind_ip=0.0.0.0 # 開啟認證(安全模式) #auth=false auth=true storageEngine=wiredTiger wiredTigerCacheSizeGB=20 # 這里設置mongo最大使用的內存, 防止出現占用內存過多 maxConns=20000 # 副本集的名稱 #replSet=mongo45 # 復制操作日志大小(MB) #oplogSize=10240
如果發現buffer/cache較高, 也可以清理
手動清理: > sync > echo 1 > /proc/sys/vm/drop_caches > echo 2 > /proc/sys/vm/drop_caches > echo 3 > /proc/sys/vm/drop_caches sync:將所有未寫的系統緩沖區寫到磁盤中,包含已修改的i-node、已延遲的塊I/O和讀寫映射文件 echo 1 > /proc/sys/vm/drop_caches:清除page cache echo 2 > /proc/sys/vm/drop_caches:清除回收slab分配器中的對象(包括目錄項緩存和inode緩存)。slab分配器是內核中管理內存的一種機制,其中很多緩存數據實現都是用的pagecache。 echo 3 > /proc/sys/vm/drop_caches:清除pagecache和slab分配器中的緩存對象。 /proc/sys/vm/drop_caches的值,默認為0
定時清理:
> vim clean.sh #!/bin/bash#每兩小時清除一次緩存 echo "開始清除緩存" sync;sync;sync #寫入硬盤,防止數據丟失 sleep 20#延遲20秒 echo 1 > /proc/sys/vm/drop_caches echo 2 > /proc/sys/vm/drop_caches echo 3 > /proc/sys/vm/drop_caches > chmod +x clean.sh > crontab -e # 每兩小時執行一次 0 */2 * * * /opt/clean.sh