侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

MongoDB自动删除过期数据的方法(TTL索引)

数据库  /  管理员 发布于 5年前   200

前序:

最近由于公司业务需求,对于3个月前的过期数据需要进行删除动作,以释放空间和方便维护

本来想的是使用crontab写个脚本定时执行,但是看到Mongo本身就有自动删除过期数据的功能,所以还是用一下吧

这个方法就是使用TTL索引,后续我再写一个脚本定时删除的任务,关于TTL索引的更多使用实例,大家可以参考学习这篇文章:https:///article/126810.htm

介绍:

TTL索引是MongoDB中一种特殊的索引, 可以支持文档在一定时间之后自动过期删除,目前TTL索引只能在单字段上建立,并且字段类型必须是date类型或者包含有date类型的数组(如果数组中包含多个date类型字段,则取最早时间为过期时间)

官网介绍链接:https://docs.mongodb.com/v3.2/core/index-ttl/

机制:

当你在集合中某一个字段建立TTL索引后,后台会有一个单线程,通过不断查询(默认60s一次)索引的值来判断document是否有过期,并且删除文档的动作还依据mongod实例的负载情况,如果负载很高,可能会稍微延后一段时间再删除。

还有一个需要注意的地方,在复制集成员中,TTL后台线程只删除primary的过期数据,如果此实例变为secondary角色,则后台线程闲置

创建TTL索引方法:

和普通索引的创建方法一样,只是会多加一个属性而已

例:在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  ---修改后的过期时间(秒)   }})

虽然上面的方法可以实现自动过期删除,但是如果白天业务很忙,频繁的删除数据势必会增加负载,所以我想着晚上定时删除过期数据(如果晚上业务量少的话)

方法如下:

增加一个expireTime字段(用于指定过期时间),expireAfterSeconds属性值设置为0,

注:上面的createTime字段就不需要再有TTL索引了,这个expireTime的时间就需要在插入时指定上

>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,并且也会忽略expireAfterSeconds属性

②在_id 主键上不能建立TTL索引

③在capped collection中不能建立TTL索引,因为MongoDB不能从capped collection中删除文档

④你不能使用createIndex()去更改已经存在的TTL索引的expireAfterSeconds值,如果想更改expireAfterSeconds,可以使用collMod命令,否则你只能删除索引,然后重建了

⑤你不能在已有索引的字段上再创建TTL索引了,如果你想把非TTL索引改为TTL索引,那就只能删除重建索引了

验证:

虽然已经实现了晚上集中自动删除的功能,但是还是担心删除过大数量时负荷问题,随进行了简单测试,一查看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索引的资源消耗,以决定是不是需要这样的方式来实现删除过期数据

          监控vmstat的截图:

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对AIDI的支持。


  • 上一条:
    MongoDB添加仲裁节点报错:replica set IDs do not match的解决方法
    下一条:
    MongoDb的"not master and slaveok=false"错误及解决方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 分库分表的目的、优缺点及具体实现方式介绍(0个评论)
    • DevDB - 在 VS 代码中直接访问数据库(0个评论)
    • 在ubuntu系统中实现mysql数据存储目录迁移流程步骤(0个评论)
    • 在mysql中使用存储过程批量新增测试数据流程步骤(0个评论)
    • php+mysql数据库批量根据条件快速更新、连表更新sql实现(0个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客