本文介绍了如何利用MongoDB的TTL索引来自动删除过期数据,包括TTL索引的生效机制、创建与修改方法、使用限制条件以及性能测试。在亿级数据量下,通过调整expireAfterSeconds属性,实现在业务低峰期动态删除过期记录,以减少维护成本。测试结果显示,删除操作在90秒内完成,CPU峰值90%,平均50%,内存占用3GB。 摘要由CSDN通过智能技术生成

由于公司业务需求,对于1个月前的过期数据需要进行删除,以释放空间和方便维护。
本来想使用crontab写个脚本定时执行删除操作,但是看到Mongo本身就有自动删除过期数据的功能,就是使用TTL索引。决定使用TTL自动索引,这样就不用再写一个脚本以完成定时删除的任务。


二、TTL索引介绍

TTL索引是MongoDB中一种特殊的索引, 可以支持文档在一定时间之后自动过期删除。 目前, TTL索引只能在单字段上建立,并且字段类型必须是date类型或者包含有date类型的数组 (如果数组中包含多个date类型字段,则取最早时间为过期时间)。
官网介绍链接:https://docs.mongodb.com/v3.2/core/index-ttl/


三、TTL索引生效机制

当你在集合中某一个字段建立TTL索引后,后台会有一个单线程,通过不断查询(默认60s一次)索引的值来判断document是否有过期,并且删除文档的动作还依据mongod实例的负载情况,如果负载很高,可能会稍微延后一段时间再删除。
还有一个需要注意的地方:在复制集成员中,TTL后台线程只删除primary实例的过期数据;如果此实例变为secondary角色,则后台线程闲置。

四、创建TTL索引

和普通索引的创建方法一样,只是会多加一个expireAfterSeconds属性而已。
例:在log_events的集合中,createTime 字段上建立“一小时后过期的TTL索引”。

>db.log_events.createIndex( { "createTime": 1 },     ---字段名称 
          { expireAfterSeconds: 60*60 } )     ---过期时间(单位秒)
>db.log_events.getIndexes()     ---查看索引
                "v" : 1,
                "key" : {
                        "_id" : 1
                "name" : "_id_",
                "ns" : "tt.t1"
                "v" : 1,
                "key" : {
                        "createTime" : 1
                "name" : "createTime_1",
                "ns" : "tt.t1",
                "expireAfterSeconds" : 3600

五、修改TTL索引的expireAfterSeconds属性值

如果想更改过期时间expireAfterSeconds,可以使用collMod方法;否则,只能使用dropIndex()和createIndex()方法重建索引,这种方法在亿级数据量下可能会有性能问题。

db.runCommand( { collMod: "log_events",     ---集合名
   index: { keyPattern: { createTime: 1 },  ---createTime为具有TTL索引的字段名
   expireAfterSeconds: 7200   ---修改后的过期时间(秒)

虽然上面的方法可以实现自动过期删除,但是频繁删除数据势必会增加负载,所以必须在业务量少的时段,定时删除过期数据和修改超时属性值。

六、动态指定TTL索引的过期时间

增加一个expireTime字段(用于指定过期时间),expireAfterSeconds属性值设置为0。在插入文档时,需要指定expireTime的值。这样,上面的createTime字段就不需要再有TTL索引了。

>db.log_events.createIndex( { "expireTime": 1 },  ---字段名称
        { expireAfterSeconds: 0 } )     ---过期时间(单位秒)
>db.log_events.insert( {
  "expireTime": new Date('Jan 22, 2016 23:00:00'), ---此文档将在2016-1-22的23点自动删除
  "logEvent": 2,
  "logMessage": "Success!"} )

如上,我们就实现了指定过期时间自动删除文档。

七、TTL索引使用限制条件

以下几种情况无法使用TTL索引:
① TTL索引是单字段索引,混合索引不支持TTL,并且也会忽略expireAfterSeconds属性。
② 在_id 主键上不能建立TTL索引。
③ 在capped collection中不能建立TTL索引,因为MongoDB不能从capped collection中删除文档。
④ 不能使用createIndex()去更改已经存在的TTL索引的expireAfterSeconds值。如果想更改expireAfterSeconds,可以使用collMod命令;否则,只能删除索引,然后重建。
⑤ 不能在已有索引的字段上再创建TTL索引了。如果想把非TTL索引改为TTL索引,那就只能先删除非TTL索引,然后新建TTL索引。

八、验证TTL索引功能

虽然已经实现了“动态指定过期时间自动删除数据”的功能,但是还是担心大量删除过期数据可能导致mongo服务器负荷问题。于是,进行了简单测试,查看TTL索引在亿级别集合中删除140万过期数据的消耗。
测试机器的配置:
     OS:Vm虚拟机
     CPU: 4
     内存:8
集合数据量:

> db.t1.count()

共有104675629条文档记录。
在制造测试数据时指定_id是顺序增加的,验证步骤:

第1步,直接查看_id=1500000那条数据的createTime;

第2步,计算一下此createTime和当前时间的时间差;

第3步:根据这个时间差,更改expireAfterSeconds的值,以让这150万数据在5分钟后过期;

第4步:在修改完expireAfterSeconds后,等待“ vmstat 1 ” 命令的输出数据。

我的测试结果:
整个删除操作过程在90秒左右完成;
CPU最高占用90%,平均在50%;
内存占用3G。
这个不是特别准确的线上测试,只是粗略了解一下TTL索引的资源消耗,以决定是不是需要使用这种方式来实现删除过期数据
          监控vmstat的截图:

最近由于公司业务需求,对于3个月前的过期数据需要进行删除动作,以释放空间和方便维护 本来想的是使用crontab写个脚本定时执行,但是看到Mongo本身就有自动删除过期数据的功能,所以还是用一下吧 这个方法就是使用TTL索引,后续我再写一个脚本定时删除的任务,关于TTL索引的更多使用实例,大家可以参考学习这篇文章:https://www.jb51.net/article/126810.htm TTL索引MongoDB中一种特殊的索引, 可以支持文档在一定时间之后自动过期删除,目前TTL索引只能在单字段上建立,并且字段类型必须是date类型或者包含有date类型的数组
MongoDB查询 TTL 过期时间 在使用 MongoDB 存储数据时,有时候我们希望某些数据在一定时间后自动过期,这时就可以使用 TTL(Time-To-Live)机制来设置数据的过期时间。通过设置 TTL 索引,可以让 MongoDB 在指定的时间后自动删除过期的数据,从而节省数据库空间和提高性能。 TTL 索引
1.今天要做一个验证码一样的东西,让用户通过校验。 下面这段是设置以createTime为过期时间的索引,意思就是一条数据以其中createTime的字段时间为准,超过该字段时间将这条数据删除。 {expireAfterSeconds:0} 设置为0 时间一到立马删除。 { expireAfterSeconds: 60*2 } 设置延时秒,以设置的延时秒为准,到时间以设置的延时为基准删除数...
由于公司业务需求,对于3个月前的过期数据需要进行删除动作,以释放空间和方便维护 本来想的是使用crontab写个脚本定时执行,但是看到Mongo本身就有自动删除过期数据的功能,所以还是用一下吧 这个方法就是使用TTL索引,后续我再写一个脚本定时删除的任务 TTL索引MongoDB中一种特殊的索引, 可以支持文档在一定时间之后自动过期删除,目前TTL索引只能在单字段上建立
固定集合是具**有固定大小**的循环集合,遵循插入顺序,以支持高性能的创建、读取和删除操作。通过循环,当分配给集合的固定大小用完时,它将删除集合中最旧的文档,而不提供任何显式命令。 TTL 索引是特殊的单字段索引MongoDB 可以使用它在一定时间或特定时钟时间后自动从集合中删除文档。
Mongodb设置自动删除过期数据 db.log_events.createIndex( { "Time": 1 }, { expireAfterSeconds: 0 } ) (单位秒) Time 字段名,expireAfterSeconds 单位:秒
TTL集合支持mongodb对存储的数据进行失效时间设置,经过指定的时间段后、或在指定的时间点过期,集合自动被mongod清除。这一特性有利于对一些只需要保存一定时间的数据信息进行存储,比如机器产生的事件数据、日志、会话信息等。 Mongodb使用TTL索引特性来实现TTL集合。TTL通过一个后台线程读取索引中数据类型的值,然后清除过期的集合。 集合中的文档超过expireAfterSecon...
在 Egg.js 中连接 MongoDB删除数据的步骤如下: 1. 首先,在 config 文件夹下的 config.default.js 中配置 MongoDB 连接信息: ```javascript exports.mongoose = { client: { url: 'mongodb://localhost:27017/test', options: {}, 其中,url 为 MongoDB 数据库的连接地址,test 为数据库名。 2. 在 controller 中编写删除数据的代码,示例代码如下: ```javascript async delete() { const { ctx } = this; const { id } = ctx.params; const result = await ctx.model.User.deleteOne({ _id: id }); ctx.body = result; 其中,UserMongoDB 中的集合名,_id 为 MongoDB 自动生成的唯一标识符,id 为前端传递的删除数据的唯一标识符。 3. 最后,在 router 中编写路由,示例代码如下: ```javascript router.delete('/api/user/:id', controller.user.delete); 其中,/api/user/:id 表示删除数据的接口地址,:id 表示删除数据的唯一标识符。
Maven 构建错误 Cannot resolve plugin org.apache.maven.plugins:maven-clean-plugin:3.1.0 Singelloly: 不是在<properties>标签下哦,应该放在根标签<project>下面,否则pom文件会报错 Maven 构建错误 Cannot resolve plugin org.apache.maven.plugins:maven-clean-plugin:3.1.0 哈莉奎茵: 太感谢lQAQ.好几个月了,终于解决这个问题了QAQ,太感谢了QAQ