MongoDB TTL索引的使用


一、TTL索引介紹

TTL全稱是(Time To Live),TTL索引能對一個單列配置過期屬性來實現對文檔的自動過期刪除,我們可以在對字段創建索引時添加expireAfterSeconds選項將索引轉換為TTL索引,該字段需要是date類型,在以下幾種場景下即使索引設置了expireAfterSeconds屬性也不會生效
- 如果該字段不是date類型,則文檔不會過期
- 如果文檔沒包含索引的這個字段,則文檔不會過期

二、TTL索引運行邏輯

  • MongoDB會開啟一個后台線程讀取該TTL索引的值來判斷文檔是否過期,但不會保證已過期的數據會立馬被刪除,因后台線程每60秒觸發一次刪除任務,且如果刪除的數據量較大,會存在上一次的刪除未完成,而下一次的任務已經開啟的情況,導致過期的數據也會出現超過了數據保留時間60秒以上的現象。
  • 對於副本集而言,TTL索引的后台進程只會在primary節點開啟,在從節點會始終處於空閑狀態,從節點的數據刪除是由主庫刪除后產生的oplog來做同步。
  • TTL索引除了有expireAfterSeconds屬性外,和普通索引一樣

三、TTL索引的限制

  • 只支持對單個字段創建TTL索引,復合索引不支持expireAfterSeconds選項
  • _id列不支持TTL索引
  • 固定集合(capped collection)不支持TTL索引
  • 不支持用createIndex() 修改expireAfterSeconds屬性,但可以用collMod命令修改,或者重建索引,但重建對於大集合成本較高,建議用collMod方式
  • 一個列只能創建普通索引或TTL索引,不能同時對一個列創建這2種類型索引(實際TTL索引本身就是普通索引,只是多了一個過期屬性)
  • 如果一個列已經存在索引,則需要先將該索引drop后才能重建為TTL索引,不能直接轉換

四、TTL索引的使用場景

1. 指定具體的過期時間屬性

該場景是在創建索引時明確指定一個expireAfterSeconds時間作為文檔的過期時間

// 對log_events集合的createdAt字段創建TTL索引且設置expireAfterSeconds過期時間為3600秒(1小時)
onepiece:PRIMARY> db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

// 對文檔插入數據,包含createdAt字段,則該文檔會在1小時候字段刪除
onepiece:PRIMARY> db.log_events.insert( {
   "createdAt": new Date(),
   "logEvent": 2,
   "logMessage": "Success!"
} )

2. 插入一個具體的過期時間

該場景是在創建索引時將expireAfterSeconds設置為0,在這種情況下由插入到字段的數據來控制文檔何時過期,這種場景更加精細化,可靈活的控制文檔的過期時間及控制在業務低峰期觸發文檔過期

// 對log_events集合的expireAt創建TTL索引,並設置expireAfterSeconds屬性為0
onepiece:PRIMARY> db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )

// 對文檔插入數據,包含expireAt字段,該文檔過期時間就是expireAt字段記錄的時間
onepiece:PRIMARY> db.log_events.insert( {
   "expireAt": new Date('Jan 16, 2020 14:00:00'),
   "logEvent": 2,
   "logMessage": "Success!"
} )

3. TTL屬性的修改(collMod)

對於TTL索引的expireAfterSeconds的屬性,可以用collMod方式進行修改

// 創建TTL索引設置1小時過期屬性
onepiece:PRIMARY> db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
{
	"createdCollectionAutomatically" : true,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}

// 查看索引定義
onepiece:PRIMARY> db.log_events.getIndexes()
[
	{
		"v" : 2,
		"key" : {
			"_id" : 1
		},
		"name" : "_id_",
		"ns" : "test.log_events"
	},
	{
		"v" : 2,
		"key" : {
			"createdAt" : 1
		},
		"name" : "createdAt_1",
		"ns" : "test.log_events",
		"expireAfterSeconds" : 3600
	}
]

// 修改索引定義,將一小時文檔過期改為60秒
onepiece:PRIMARY> db.runCommand( { collMod: "log_events",
			index: { keyPattern: { createdAt: 1 },
			expireAfterSeconds: 60
			}
})

// 返回值: { "expireAfterSeconds_old" : 3600, "expireAfterSeconds_new" : 60, "ok" : 1 }

五、Date類型

  • Date() method which returns the current date as a string.
  • new Date() constructor which returns a Date object using the ISODate() wrapper.
  • ISODate() constructor which returns a Date object using the ISODate() wrapper.
onepiece:PRIMARY> Date()
Thu Jan 16 2020 14:48:40 GMT+0800 (CST)

onepiece:PRIMARY> new Date()
ISODate("2020-01-16T06:48:48.655Z")

onepiece:PRIMARY> ISODate()
ISODate("2020-01-16T06:48:53.673Z")

六、參考文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM