MongoDB學習【五】Change Streams

Change Streams

一、Change Stream是什麼?

Change Stream是MongoDB從3.6開始支持的新特性。

Change Stream即變更流,是MongoDB嚮應用發佈數據變更的一種方式。即當數據庫中有任何數據發生變化,應用端都可以得到通知。我們可以將其理解爲在應用中執行的觸發器。至於應用想得到什麼數據,以什麼形式得到數據,則可以通過聚合框架加以過濾和轉換。

參考地址:https://mongoing.com/change-stream

官方文檔地址:https://docs.mongodb.com/manual/changeStreams/

二、Change Stream的原理

我們先來看一下MongoDB複製集大致是如何工作的:

  1. 應用通過驅動向數據庫發起寫入請求;
  2. 在同一個事務中,MongoDB完成oplog和集合的修改;
  3. oplog被其他從節點拉走;
  4. 從節點應用得到的oplog,同樣在一個事務中完成對oplog和集合的修改;

至此,複製集同步完成。可以發現,整個同步過程是依賴於oplog來進行的。如果觀測oplog的變化,就能夠得到所有變更的數據。change stream正是基於這個原理實現的。

三、Change Stream的使用

啓動複製集,打開一個shell,訂閱你需要關注的集合,並在這個shell中不斷遍歷這個遊標以獲取新數據:

rs_test:SECONDARY> var cursor = db.score.watch()
rs_test:SECONDARY> while(true){if(cursor.hasNext()){print(JSON.stringify(cursor.next()))}}

接下來打開另一個shell做CRUD的基本操作,以測試不同的Change Events輸出的變更內容:

1、insert Event

rs_test:PRIMARY> db.score.insert({uid:"uid20001",grade:5,class:1,subject:"math",score:90,createTime:Date()})

插入數據時,輸出變更數據如下:

{
    "_id":{
        "_data":"825F02F125000000012B022C0100296E5A10044B22BC6860404A9C96301E8CEC60899E46645F696400645F02F125E7BA0AAA65B2E6F90004"
    },
    "operationType":"insert",
    "clusterTime":{
        "$timestamp":{
            "t":1594028325,
            "i":1
        }
    },
    "fullDocument":{
        "_id":{
            "$oid":"5f02f125e7ba0aaa65b2e6f9"
        },
        "uid":"uid20001",
        "grade":5,
        "class":1,
        "subject":"math",
        "score":90,
        "createTime":"Mon Jul 06 2020 17:38:45 GMT+0800"
    },
    "ns":{
        "db":"aggtest",
        "coll":"score"
    },
    "documentKey":{
        "_id":{
            "$oid":"5f02f125e7ba0aaa65b2e6f9"
        }
    }
}

2、update Event

rs_test:PRIMARY> db.score.update({uid:"uid20001"},{$set:{class:3,updateTime:Date()}})

更新數據時,輸出變更數據如下:

{
    "_id":{
        "_data":"825F02F615000000012B022C0100296E5A10044B22BC6860404A9C96301E8CEC60899E46645F696400645F02F125E7BA0AAA65B2E6F90004"
    },
    "operationType":"update",
    "clusterTime":{
        "$timestamp":{
            "t":1594029589,
            "i":1
        }
    },
    "ns":{
        "db":"aggtest",
        "coll":"score"
    },
    "documentKey":{
        "_id":{
            "$oid":"5f02f125e7ba0aaa65b2e6f9"
        }
    },
    "updateDescription":{
        "updatedFields":{
            "class":3,
            "updateTime":"Mon Jul 06 2020 17:59:49 GMT+0800"
        },
        "removedFields":[
        ]
    }
}

3、replace Event

rs_test:PRIMARY> db.score.replaceOne({uid:"uid20001"},{uid:"uid20002",grade:6,class:6,subject:"chinese",score:98,createTime:Date(),updateTime:Date()})

替換文檔時,輸出變更數據如下:

{
    "_id":{
        "_data":"825F02F828000000012B022C0100296E5A10044B22BC6860404A9C96301E8CEC60899E46645F696400645F02F125E7BA0AAA65B2E6F90004"
    },
    "operationType":"replace",
    "clusterTime":{
        "$timestamp":{
            "t":1594030120,
            "i":1
        }
    },
    "fullDocument":{
        "_id":{
            "$oid":"5f02f125e7ba0aaa65b2e6f9"
        },
        "uid":"uid20002",
        "grade":6,
        "class":6,
        "subject":"chinese",
        "score":98,
        "createTime":"Mon Jul 06 2020 18:08:40 GMT+0800",
        "updateTime":"Mon Jul 06 2020 18:08:40 GMT+0800"
    },
    "ns":{
        "db":"aggtest",
        "coll":"score"
    },
    "documentKey":{
        "_id":{
            "$oid":"5f02f125e7ba0aaa65b2e6f9"
        }
    }
}

4、delete Event

rs_test:PRIMARY> db.score.deleteOne({uid:"uid20002"})

刪除文檔時,輸出變更數據如下:

{
    "_id":{
        "_data":"825F02F8EB000000012B022C0100296E5A10044B22BC6860404A9C96301E8CEC60899E46645F696400645F02F125E7BA0AAA65B2E6F90004"
    },
    "operationType":"delete",
    "clusterTime":{
        "$timestamp":{
            "t":1594030315,
            "i":1
        }
    },
    "ns":{
        "db":"aggtest",
        "coll":"score"
    },
    "documentKey":{
        "_id":{
            "$oid":"5f02f125e7ba0aaa65b2e6f9"
        }
    }
}

5、drop Event

rs_test:PRIMARY> db.score.drop()

刪除集合時,輸出變更數據如下:

{
    "_id":{
        "_data":"825F02FA07000000012B022C0100296E5A10044B22BC6860404A9C96301E8CEC60899E04"
    },
    "operationType":"drop",
    "clusterTime":{
        "$timestamp":{
            "t":1594030599,
            "i":1
        }
    },
    "ns":{
        "db":"aggtest",
        "coll":"score"
    }
}


//invalidate Event
{
    "_id":{
        "_data":"825F02FA07000000012B022C0100296F5A10044B22BC6860404A9C96301E8CEC60899E04"
    },
    "operationType":"invalidate",
    "clusterTime":{
        "$timestamp":{
            "t":1594030599,
            "i":1
        }
    }
}

6、rename Event

rs_test:PRIMARY> db.score.renameCollection("score_new")

集合重命名時,輸出變更數據如下:

{
    "to":{
        "db":"aggtest",
        "coll":"score_new"
    },
    "_id":{
        "_data":"825F02FC74000000012B022C0100296E5A1004377F141A69914F99ACDDFB9D89863EAE04"
    },
    "operationType":"rename",
    "clusterTime":{
        "$timestamp":{
            "t":1594031220,
            "i":1
        }
    },
    "ns":{
        "db":"aggtest",
        "coll":"score"
    }
}


//invalidate Event
{
    "_id":{
        "_data":"825F02FC74000000012B022C0100296F5A1004377F141A69914F99ACDDFB9D89863EAE04"
    },
    "operationType":"invalidate",
    "clusterTime":{
        "$timestamp":{
            "t":1594031220,
            "i":1
        }
    }
}

7、dropDatabase Event

rs_test:PRIMARY> db.dropDatabase()

刪除當前數據庫時,輸出變更數據如下:

{
    "_id":{
        "_data":"825F02FE76000000012B022C0100296E5A1004377F141A69914F99ACDDFB9D89863EAE04"
    },
    "operationType":"drop",
    "clusterTime":{
        "$timestamp":{
            "t":1594031734,
            "i":1
        }
    },
    "ns":{
        "db":"aggtest",
        "coll":"score_new"
    }
}


//invalidate Event
{
    "_id":{
        "_data":"825F02FE76000000012B022C0100296F5A1004377F141A69914F99ACDDFB9D89863EAE04"
    },
    "operationType":"invalidate",
    "clusterTime":{
        "$timestamp":{
            "t":1594031734,
            "i":1
        }
    }
}

8、invalidate Event

對於針對集合打開的變更流,影響監視的集合的 drop eventrename event 或者 dropDatabase event 將導致  invalidate event 

對於針對數據庫打開的變更流,影響監視數據庫的 dropDatabase event 將導致  invalidate event 

invalidate event 將關閉更改流遊標 。

resumeAfter在 invalidate event (例如,集合刪除或重命名)關閉流之後,不能用來恢復更改流。從MongoDB 4.2開始,您可以使用 startAfter 在 invalidate event 之後啓動新的更改流 。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章