MONGODB TTL 索引,過期數據的killer

  • 2020 年 2 月 21 日
  • 筆記

過期數據的清理問題,一直是資料庫界的一個問題,處理的方式很多,大部分都是通過存儲過程,或者定期使用第三方工具來進行處理。MONGODB 處理過期數據的方面,可以使用類似REDIS expired key 的概念,創建TTL index 來通過時間的方式處理過期數據。

這樣處理的方式的好處

1 簡單方便

2 通過資料庫系統本身的方式來處理,高效安全

3 資料庫會根據自身的性能以及資料庫狀態來自動判斷是否開始清理數據,而不是和存儲過程,或其他的方式,到時間就去處理,不管資料庫當前的情況野蠻操作。

TTL 索引本身是一種特殊的單欄位索引,通過普通創建索引的方式輔助expiredAfterSecond 選項就可以創建一個欄位,欄位的值需要為日期型,或者帶有日期類型的數組。

那我們先的理解什麼是日期型數據,在MONGODB是怎麼體現的

1 由於mongodb本身是分散式資料庫,在設計之初時間的概念是UTC的概念所以mongodb的時間類型的 isodate ,以世界的0時區作為統一的時間的表達,並沒有時區的概念,所以看到的時間應該在你自己的時區進行 增加或減少對應的時間。

2 MONGODB 中可以返回時間的函數(以目前最新的版本 4.2)有兩個 Date(), new Date() , 前一個返回的是字元類型的值,後一個返回的是UTC的時間。具體如何調整new Date() 返回的時間值,可以參看文檔。

下面是自動生成的測試數據

測試數據中只有creationDate是ISODATE類型,也只有這個欄位可以作為判斷數據是否過期的唯一標準欄位。添加索引需要在保存BSON日期類型的值或者對象數組的欄位上創建TTL 索引,並且在expireAfterSeconds指定一個非負的非零值。當欄位中的秒數超過其索引指定的時間後,文檔會過期,然後開始清理。

從測試來看,刪除文檔的速度比較快。

下面有幾點是TTL 索引需要知道的

1 TTL 索引不保證在生成索引後,立即開始刪除過期數據

2 不支援聯合索引

3 刪除文檔的調度任務60秒運行一次

4 負載過重的系統,將跳過任務調度,以系統提供正常服務為優先

5 複製集成員的非主成員,不會自動刪除數據,只接受主庫發來的delete指令

6 TTL 索引本身支援查詢使用,

7 在索引建立後,不能改變expireAfterSeconds 的值,需要刪除索引,在重新建立,所以添加數值的時候,一定算好。

8 建立TTL的欄位,不能是其他已有索引的欄位,否則無法添加expired功能

通過 db.serverStatus() 可以查看刪除文檔的數量

當然也可以通過日誌來監控刪除日誌的操作,

默認監控的方式是關閉的,需要使用下面的命令來打開

db.setLogLevel(1,"index")

或者不需要監控,可以通過下面的命令來將監控關掉

db.adminCommand({setParameter:1, ttlMonitorEnabled:false})