db.log_events.find()                                     # 查找log_events里的所有数据
 
db.log_events.createIndex( { "LogDT": 1 }, { expireAfterSeconds: 3600 } )                              #设置log_events里的TTL过期索引清理时间为3600秒
 
db.runCommand( { collMod: "log_events",index: { keyPattern: { LogDT: 1 },expireAfterSeconds: 10800 }})       #修改过期索引时间,建议最好还是先drop在新建
 
db.log_events.getIndexes()                 #查找log_events里的所有索引
 
 
 
TTL索引是MongoDB中一种特殊的索引, 可以支持文档在一定时间之后自动过期删除,目前TTL索引只能在单字段上建立,
并且字段类型必须是date类型或者包含有date类型的数组(如果数组中包含多个date类型字段,则取最早时间为过期时间)
 
当你在集合中某一个字段建立TTL索引后,后台会有一个单线程,通过不断查询(默认60s一次)索引的值来判断document是否有过期,
并且删除文档的动作还依据mongod实例的负载情况,如果负载很高,可能会稍微延后一段时间再删除。
还有一个需要注意的地方,在复制集成员中,TTL后台线程只删除primary的过期数据,如果此实例变为secondary角色,则后台线程闲置
 
限制条件:
有一下集中情况是无法使用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的截图:
创建TTL索引方法:
和普通索引的创建方法一样,只是会多加一个属性而已
例:在log_events的集合中,createTime 字段上建立一小时后过期的TTL索引

  1. >db.log_events.createIndex( { "createTime": 1 },     ---字段名称
  2. { expireAfterSeconds: 60*60 } )     ---过期时间(单位秒)
  3. >db.log_events.getIndexes()     ---查看索引
  4. [
  5. {
  6. "v" : 1,
  7. "key" : {
  8. "_id" : 1
  9. },
  10. "name" : "_id_",
  11. "ns" : "tt.t1"
  12. },
  13. {
  14. "v" : 1,
  15. "key" : {
  16. "createTime" : 1
  17. },
  18. "name" : "createTime_1",
  19. "ns" : "tt.t1",
  20. "expireAfterSeconds" : 3600
  21. }
  22. ]

修改TTL索引的expireAfterSeconds属性值:

注:如果想更改过期时间expireAfterSeconds,可以使用collMod方法,要不然你只能只用dropIndex(),createIndex()方法重建索引了,我想这样的方法在亿级数据量下是很头疼的
  1. db.runCommand( { collMod: "log_events",     ---集合名
  2. index: { keyPattern: { createTime: 1 },     ---createTime为具有TTL索引的字段名
  3. expireAfterSeconds: 7200          ---修改后的过期时间(秒)
  4. }})

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

方法如下:
增加一个expireTime字段(用于指定过期时间),expireAfterSeconds属性值设置为0,
注:上面的createTime字段就不需要再有TTL索引了,这个expireTime的时间就需要在插入时指定上
  1. >db.log_events.createIndex( { "expireTime": 1 },     ---字段名称
  2. { expireAfterSeconds: 0 } )     ---过期时间(单位秒)
  3. >db.log_events.insert( {
  4. "expireTime": new Date('Jan 22, 2016 23:00:00'),     ---此文档将在2016-1-22的23点自动删除
  5. "logEvent": 2,
  6. "logMessage": "Success!"} )
这样我们就实现了,指定时间自动删除的动作了

一、TTL索引

  1. 创建方法
  2. db.collection.createIndex(keys, options)
  3. options:
  4. expireAfterSeconds 指定多少秒或者包含日期值的数组
  5. 创建示例
  6. db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
  7. 何时失效
  8. 在指定的时间达到后失效,也即是索引字段的值加上一个特定的秒数之后
  9. 如果索引字段是一个数组,即索引字段上存在着多个日期值,此时MongoDB取最小值加上失效时间(lowest())
  10. 对于非日期字段或不包含日期数组的索引字段,文档不会失效
  11. 对于不包含索引字段的文档,文档不会失效
  12. 删除操作
  13. mongod的一个后台线程会读取索引的值并将失效的文档从集合移除
  14. TTL线程被激活后,可以从db.currentOp()或者从profile观察到删除操作
  15. 何时删除
  16. 当基于后台方式创建索引时,TTL线程能够在索引创建期间开始删除失效文档
  17. 当基于前台方式创建索引时,TTL线程在索引创建完成后开始删除失效文档
  18. TTL索引的删除不能完全保证失效期后一定删除,存在一定延迟(取决于mongod的工作负载)
  19. TTL删除文档后台线程每60s移除失效文档(因此可能存在已过失效期,文档还在的情形)
  20. 在副本集环境中,TTL后台线程仅仅在主副本上工作,辅助副本上由复制操作实现
  21. 在使用TTL索引查询时,与使用非TTL索引一样
  22. 一些限制
  23. 不能基于已经存在索引的字段创建TTL索引以及非日期字段创建TTL索引,文档不会失效
  24. TTL索引不支持基于多个字段的复合索引
  25. 不支持定长集合

二、TTL索引示例

  1. # mongo --shell localhost:27000 TTLData.js
  2. MongoDB shell version: 3.2.11
  3. connecting to: localhost:27000/test
  4. repSetTest:PRIMARY> addTTLTestData() //添加集合数据
  5. Create three records in database each with a create time that is 1 minute apart
  6. Created three test documents, oldest being 4 mins old
  7. Now create a TTL index with expiry of 5 mins on the createDate field as follows
  8. db.ttlTest.ensureIndex({createDate:1}, {expireAfterSeconds:300})
  9. repSetTest:PRIMARY> db.ttlTest.find() //当前向集合里插入了3个文档
  10. { "_id" : 1, "createDate" : ISODate("2017-03-10T03:23:01.169Z") }
  11. { "_id" : 2, "createDate" : ISODate("2017-03-10T03:24:01.169Z") }
  12. { "_id" : 3, "createDate" : ISODate("2017-03-10T03:25:01.169Z") }
  13. //下面为测试集合上的文档添加索引,即5分钟后索引失效
  14. repSetTest:PRIMARY> db.ttlTest.createIndex({createDate:1}, {expireAfterSeconds:300})
  15. {
  16. "createdCollectionAutomatically" : false,
  17. "numIndexesBefore" : 1, // Author : Leshami
  18. "numIndexesAfter" : 2, // Blog : http://blog.csdn.net/leshami
  19. "ok" : 1
  20. }
  21. //查找文档
  22. repSetTest:PRIMARY> db.ttlTest.find()
  23. { "_id" : 1, "createDate" : ISODate("2017-03-10T03:23:01.169Z") }
  24. { "_id" : 2, "createDate" : ISODate("2017-03-10T03:24:01.169Z") }
  25. { "_id" : 3, "createDate" : ISODate("2017-03-10T03:25:01.169Z") }
  26. //当指定时间到期后,文档被删除,如下,查询不到任何文档
  27. repSetTest:PRIMARY> db.ttlTest.find()
  1.  

mongo ttl索引的更多相关文章

  1. MongoDB自动删除过期数据--TTL索引

      前序: 由于公司业务需求,对于3个月前的过期数据需要进行删除动作,以释放空间和方便维护 本来想的是使用crontab写个脚本定时执行,但是看到Mongo本身就有自动删除过期数据的功能,所以还是用一 ...

  2. mongodb的TTL索引介绍(超时索引)

    TTL索引是mongodb新支持的用于延时自动删除记录的一种索引.它仅包含一个字段,该字段值需要是Date()类型,并且不支持复合索引.可以指定某条记录在延时固定时间后自动删除.数据自动超时删除主要用 ...

  3. MongoDB 学习笔记之 TTL索引,部分索引和文本索引

    TTL索引: TTL集合支持mongodb对存储的数据进行失效时间设置,经过指定的时间段后.或在指定的时间点过期,集合自动被mongod清除.这一特性有利于对一些只需要保存一定时间的数据信息进行存储, ...

  4. MongoDB TTL索引的使用

    目录 一.TTL索引介绍 二.TTL索引运行逻辑 三.TTL索引的限制 四.TTL索引的使用场景 1. 指定具体的过期时间属性 2. 插入一个具体的过期时间 3. TTL属性的修改(collMod) ...

  5. mongo学习-TTL索引 过期数据

    在mongo中我们可以设置文档的过期时间,超过时间,文档会自动删除.(2.x版本中  固定结合也支持,但是到了3.x中 固定集合这个索引不好用) 用法: 1.创建一个db:db.createColle ...

  6. Mongo基础 索引的使用

    MongoDB中的索引和其他数据库索引类似,也是使用B-Tree结构.mongodb的索引是在collection级别上的,并且支持在任何列或者集合内的文档的子列中创建索引. 所有的MongoDB集合 ...

  7. Mongo组合索引优化

    包含了等值测试.排序及范围过滤查询的索引建立方法: 1. 等值测试 在索引中加入所有需要做等值测试的字段,任意顺序. 2. 排序字段(多排序字段的升/降序问题 ) 根据查询的顺序有序的向索引中添加字段 ...

  8. 我叫Mongo,干了「索引探索篇」提升我的效率,值得您拥有

    这是mongo第四篇"索引探索",后续会连续更新4篇 mongodb的文章总结上会有一系列的文章,顺序是先学会怎么用,在学会怎么用好,戒急戒躁,循序渐进,跟着我一起来探索交流.通过 ...

  9. 第28章:MongoDB-索引--过期索引(TTL)

    ①过期索引(TTL) TTL索引是让文档的某个日期时间满足条件的时候自动删除文档,这是一种特殊的索引,这种索引不是为了提高查询速度的,TTL索引类似于缓存,缓存时间到了就过期了,就要被删除了 ②范例: ...

随机推荐

  1. Date 类的使用

    package com.Date.Math; import java.text.ParseException; import java.text.SimpleDateFormat; import ja ...

  2. Teamwork(The fourth day of the team)

    在这天我们已经开始去做自己手上的的任务.由于我们都忙于手头上的工作,所以这天我们就没有过多的交流,有的可能就是网上说一下实现到了哪里.

  3. 团队作业4--第一次项目冲刺2(Alpha版本)

    1.会议 第二次会议: ①:总结第一天任务出现的问题 ②:安排下面两天的任务 2任务安排 3.任务分解图 4.燃尽图 5.适当的项目程序/模块的最新(运行)截图 6.心得 因为做前端的同学并不擅长这方 ...

  4. iOS-UICollectionViewLayout方法介绍

    注意:UICollectionView的自定义功能就是自己去实现UICollectionViewLayout的子类,然后重写相应的方法来实现Cell的布局 1.当布局首次被加载时会调用prepareL ...

  5. 深入理解JAVA集合系列四:ArrayList源码解读

    在开始本章内容之前,这里先简单介绍下List的相关内容. List的简单介绍 有序的collection,用户可以对列表中每个元素的插入位置进行精确的控制.用户可以根据元素的整数索引(在列表中的位置) ...

  6. ABP ModuleZero后台框架materialize禁止模拟select和checkbox

    使用abp modulezero自带那个后台框架发现一个操蛋的问题,所有的select和checkbox都被改成div模拟的,虽然比原生美观,但有时候真的很难用. 比如说要用select做一个联动菜单 ...

  7. [百度贴吧]10GB 通信线缆

    现在,即使光纤通信能够带来最低延迟的优势,但是许多IT部门依然在10G以太网(10G bE)中使用铜缆布线,来实现交换机和交换机或者和服务器之间的连接.目前主要有两种主要的铜缆布线技术应用在10 Gb ...

  8. Art & Material

    Art(Android runtime)模式伴随Android 4.4发布.相对于Dalvik模式来说,Art模式改善了Android程序的性能. Material Design伴随Android 5 ...

  9. 内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[C++][内存管理][转载]

    http://www.cnblogs.com/JCSU/articles/1051579.html 一. 在c中分为这几个存储区1.栈 - 由编译器自动分配释放2.堆 - 一般由程序员分配释放,若程序 ...

  10. P2151 [SDOI2009]HH去散步

    题目描述 HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢 ...