您好,登錄后才能下訂單哦!
充分獲知數據庫的數據變動是從MongoDB向其他數據服務進行數據同步的關鍵點。與直接查詢collection來獲取數據變動相比,通過流式的方式進行監聽會有效并及時的多。這是一種非常強大的“響應式編程”模式。隨著MongoDB的版本更新,流式的獲取方式將變得原來越易用。
讓我們來一同回顧一下。在MongoDB3.6之前,如果我們希望對MongoDB數據庫中的數據變動進行監聽,我們通常是通過 “監聽并回放oplog”(“tail the oplog”)的模式(oplog表將會記錄復制集中的數據變動)。在生產環境中這種方式(“監聽并回放oplog”)通常較為復雜,并且難以保證其穩定與可靠性。
從MongoDB3.6開始支持的 Change Streams打破了這個僵局。 Change Streams使得數據的變動監聽變得簡單易用。以下是一個示例,該示例演示了通過Node.js對“movieDetails”表的變動監聽。
javascript const MongoClient = require("mongodb").MongoClient; const uri = "MONGODBURL"; const client = new MongoClient(uri, { useNewUrlParser: true }); client.connect().then(db => { const changeStream = client.db("video").collection("movieDetails").watch(); changeStream.on("change", next => { console.log(next); }); });
上述代碼首先連接進入了數據實例,并通過watch()函數對“video”庫的“movieDetails”表建立了change stream。而后通過.on(“change”,… 建立了一個事件trigger,該事件將監聽該change stream上的所有變動并調用對應的后續函數。在上述示例中,監聽到變動后將會將變動事件打印出來。下面是我們在 MongoDB Compass中進行對應修改后的輸出示例:
javascript { _id: { _data: '825C51D03F0000000129295A1004E515B4338C574BA2B9603CB1C7FB3B0446645F696400645C0EC4B74B052F9E2EF0C3810004' }, operationType: 'replace', clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1548865599 }, fullDocument: { _id: 5c0ec4b74b052f9e2ef0c381, title: 'PS I Love You', year: 2007, ... awards: { wins: 2, nominations: 4, text: '2 wins & 4 nominations.' }, type: 'movie' }, ns: { db: 'video', coll: 'movieDetails' }, documentKey: { _id: 5c0ec4b74b052f9e2ef0c381 } }
在上述的返回中可以快速的找到此次change stream的重要信息,即通過operationType了解到變動的類型,有關完整的返回說明請參考 [Change Events documentation]。當監聽某一個collection的時候,operationType的值通常是 insert , update , replace , delete 或 invalidate ,前四種的含義通過名字可以清楚的獲知,上述返回的replace類型是我們通過Compass同collection進行replace操作的反饋。
當我們監聽的collection被drop、改名或者其所屬的db被drop的時候,我們將會看到類型為invalidate的operationType。于此同時這也意味著是時候關閉change stream了。上述返回中剩下的部分是變動的詳細信息,變動發生在什么namespace,數據是什么樣的,何時發生的變更。
以上的示例是在MongoDB4.x版本中生成的,相比3.6版本,4.x版本新增了一個_data字段。該字段是一個恢復token(resume token),應用程序能夠在重連后從該點進行繼續監聽。
如果你只需要針對某一個collection進行變動監聽,MongoDB3.6就可以滿足你的需求,但是對于那些此前通過oplog來進行變動監聽的同學,他們的訴求往往是希望監聽數據庫中的所有變動,以此來將變動應用到其他系統中。MongoDB4.0很好的滿足了這個訴求,在4.0版本中我們可以針對若干個數據庫或者整個實例(復制集或者sharding)進行變動監聽。與
watch()
某一個collection不同,4.0中我們可以
watch()
某個數據庫或者整個實例。
javascript const MongoClient = require("mongodb").MongoClient; const uri ="MONGODBURL"; undefined const client = new MongoClient(uri, { useNewUrlParser: true }); client.connect().then(db => { const changeStream = client.watch(); changeStream.on("change", next => { console.log(next); });
上述示例將對于任何數據庫、任何表的任何變動進行輸出,這些也不是我們所捕獲的全部信息。由于我們將監聽范圍放到了最廣,我們也將會看到在刪除collection時候的刪除事件、刪除數據庫的時間以及重命名collection的事件。
我們可以根據實際需要選擇監聽某一個collection的變動、或者某個數據庫中所有collection的變動又或者是整個實例中所有的數據庫與collection的變動。需要注意的是創建新collection、數據庫的變動將不會被直接監聽到,不過我們可以通過變動中的內容間接獲知。
當然,這也不是什么大問題,如果我們希望監聽數據庫或者collection的創建,我們可以通過變動內容中的collection來判斷是否該表為此前未創建的新表這一方法進行。另外,索引的創建由于不是為表數據變動也不會被監聽捕獲。
MongoDB4.0為我們帶來了一個全新且強大的數據變動監聽方式,尤其是該方式可以實時進行變動捕獲。我們十分建議你去嘗試下這個功能。Change Stream的詳細文檔可以參考[Change Streams]。如果你還未安裝MongoDB4.0實例,你也可以在MongoDB Atlas中[注冊]并獲取M0的免費集群節點進行學習和測試。
譯者:周李洋
Teambition運維總監
MongoDB中文社區組委會成員
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。