MongoDB自動刪除過期資料 TTL索引

2021-10-24 11:55:58 字數 3417 閱讀 8190

ttl索引是一些特殊的索引,mongodb可以在一段時間後使用它自動從集合中刪除文件。這對於某些型別的資訊比如機器生成的事件資料,日誌和會話資訊是合適的,因為這些資訊只需要在有限的時間內保留在資料庫中。

官方文件:

目前ttl索引只能在單字段上建立,並且字段型別必須是date型別或者包含有date型別的陣列(如果陣列中包含多個date型別字段,則取最早時間為過期時間)

當你在集合中某乙個字段建立ttl索引後,後台會有乙個單執行緒,通過不斷查詢(預設60s一次)索引的值來判斷document是否有過期,

並且刪除文件的動作還依據mongod例項的負載情況,如果負載很高,可能會稍微延後一段時間再刪除。

還有乙個需要注意的地方,在複製集成員中,ttl後台執行緒只刪除primary的過期資料,如果此例項變為secondary角色,則後台執行緒閒置

1、如果欄位是乙個陣列,並有多個日期值時,mongodb使用最低(即最早)日期值來計算失效閾值。

2、如果字段不是日期型別也不是乙個包含日期的陣列型別那麼文件就永遠不會過期。

3、如果乙個文件不包含索引字段,該文件也不會到期。

ttl索引有兩種使用方式

在指定的秒數後刪除該文件

在特定時間過期刪除文件

熱身一下:

建立示例   

db.collection.createindex(keys, options)

options:

expireafterseconds 指定多少秒或者包含日期值的陣列

建立示例

db.eventlog.createindex( , ,)

lastmodifieddate: 建立的索引字段,1 代表公升序,-1 代表降序

expireafterseconds: 過期時間

background: 後台運營,不 block 其他程序

sparse: 是否是稀疏索引,加上它只是在索引字段存在的時候 才會有新增索引的動作,節省資源,使用場景: 專案後期追加的字段 新增索引的時候特別有用, 避免搞掛你的mongo,被你同事打

db.log_events.createindex( ,  )

db.log_events.insert( )

建立索引的方式和其餘的差不多,只是多了個字段 – expireafterseconds

createdat:索引字段,1 代表公升序,-1 代表降序

expireafterseconds:顧名思義,過期時間,時間為秒,可以 3600,也可以 60 * 60

db.log_events.createindex( ,  )

db.log_events.insert( )

注意:expireafterseconds 需要設定為 0

注:如果想更改過期時間expireafterseconds,可以使用collmod方法,要不然你只能只用dropindex(),createindex(),getindexes()方法重建索引了,我想這樣的方法在億級資料量下是很頭疼的

db.runcommand( ,     ---createtime為具有ttl索引的欄位名

expireafterseconds: 7200 ---修改後的過期時間(秒)

}})

雖然已經實現了晚上集中自動刪除的功能,但是還是擔心刪除過大數量時負荷問題,隨進行了簡單測試,一檢視ttl索引在億級別集合中刪除140萬過期資料的消耗

測試配置:

os:vm虛擬機器

cpu: 4

記憶體:8

集合資料量:

\> db.t1.count()

104273617

因為我製造測試資料時,_id是順序增加的,所以我直接檢視_id=1500000的那筆資料的createtime,然後自己計算一下此createtime和當前時間的時間差,

隨後根據這個時間差來更改expireafterseconds的值,以讓這150萬資料5分鐘後過期並刪除。

在修改完expireafterseconds後,就嚴密延時「 vmstat 1 」 命令的輸出資料;

我的測試結果:

刪除操作整個過程在90秒左右完成;

cpu最高占用90%,平均在50%

記憶體占用3g

這個也是特別準確的模擬情況,只是粗略的了解一下ttl索引的資源消耗,以決定是不是需要這樣的方式來實現刪除過期資料

一 簡介:本文介紹建立自動刪除資料的ttl索引

二 目的 定時刪除資料

三 建立方法

db.collection.createindex(keys, options)

options:

expireafterseconds 指定多少秒或者包含日期值的陣列

建立示例

db.eventlog.createindex( , ,)

lastmodifieddate: 建立的索引字段,1 代表公升序,-1 代表降序

expireafterseconds: 過期時間

background: 後台運營,不 block 其他程序

sparse: 是否是稀疏索引,加上它只是在索引字段存在的時候 才會有新增索引的動作,節省資源,使用場景: 專案後期追加的字段 新增索引的時候特別有用, 避免搞掛你的mongo,被你同事打

四 何時失效

1 在指定的時間達到後失效,也即是索引欄位的值加上乙個特定的秒數之後

2 如果索引欄位是乙個陣列,即索引欄位上存在著多個日期值,此時mongodb取最小值加上失效時間(lowest())

3 對於非日期欄位或不包含日期陣列的索引字段,文件不會失效

4 對於不包含索引欄位的文件,文件不會失效

五 刪除操作

1 mongod的乙個後台執行緒會讀取索引的值並將失效的文件從集合移除

2 當ttl執行緒被啟用後,可以從db.currentop()或者從profile觀察到刪除操作

六 何時刪除

1 當基於後台方式建立索引時,ttl執行緒能夠在索引建立期間開始刪除失效文件

2 當基於前台方式建立索引時,ttl執行緒在索引建立完成後開始刪除失效文件

3 ttl索引的刪除不能完全保證失效期後一定刪除,存在一定延遲(取決於mongod的工作負載)

4 ttl刪除文件後台執行緒每60s移除失效文件(因此可能存在已過失效期,文件還在的情形)

5 在副本集環境中,ttl後台執行緒僅僅在主副本上工作,輔助副本上由複製操作實現

6 在使用ttl索引查詢時,與使用非ttl索引一樣

七 一些限制

1 不能基於已經存在索引的字段建立ttl索引以及非日期字段建立ttl索引,文件不會失效

2 ttl索引不支援基於多個欄位的復合索引

3 不支援定長集合

參考:

mongodb刪除過期資料

通常,你往某乙個mongo庫中插資料,然後按日輪詢,最終這個資料會越來越多,對於不用的資料需要進行清理。這篇文章主要將如何清理過期資料。舉個例子 你只需要最近2個月的資料,比如今天是20170829,那麼60天之前的資料都可以清理掉。你可以寫乙個crontab任務,然後匯入指令碼,每天執行一次,將6...

elasticsearch清除過期資料

版本 elasticsearch 7.3.2 指令碼內容如下 root access server elasticsearch 7.3.2 cat clear data.py coding utf 8 import requests import json es host 127.0.0.1 ela...

Redis過期資料和刪除策略

因為記憶體有限,有些資料不需要一直在記憶體中,可以設定一些規則,將一些資料設定過期,在記憶體中刪除,當然也不是隨便刪除,也要考慮到cpu的繁忙與空閒,以免出現redis各種命令執行很多,但是正好出現大量過期資料,已造成伺服器宕機 是在記憶體占用與cpu占用之間尋找一種平衡,顧此失彼都會造成redis...