MongoDB oplog是一个capped collection,创建capped collection时,createCollection可以设置size(最大字节数)和max(最大文档数)的参数,当这个集合的『总大小超过size』或者『总文档数超过max』时,在新插入文档时就会自动删除一些集合内最先插入的文档,相当于一片环形的存储空间。

oplog(local.oplog.rs集合)默认情况下配置为可用磁盘空间的5%,当oplog写满时,就会开始删除最先写入的oplog,一次正常的insert操作包含如下步骤:

  1. 将文档写入指定的集合
  2. 将写入操作记录到oplog
  3. 如果oplog满了,删除最先写入的oplog

优化策略

MongoDB 3.2为了提升写入性能,使用wiredtiger引擎时,针对local.oplog.rs这个集合的删除策略进行了优化,主要改进:

  1. 将删除动作从用户的写入路径移除,放到后台线程执行
  2. 批量删除,并不是oplog一满就立马触发删除,而是一次删除一批

实施方案

monogd启动时,会根据oplog的最大字节数将整个集合分为10-100个Stone(可以理解为oplog的一段数据,包含多个文档,Stone的具体个数oplogSizeMB的配置相关)。


WiredTigerRecordStore::OplogStones::OplogStones(OperationContext* txn, WiredTigerRecordStore* rs)
: _rs(rs) {
//...
unsigned long long maxSize = rs->cappedMaxSize(); const unsigned long long kMinStonesToKeep = 10ULL;
const unsigned long long kMaxStonesToKeep = 100ULL; unsigned long long numStones = maxSize / BSONObjMaxInternalSize;
_numStonesToKeep = std::min(kMaxStonesToKeep, std::max(kMinStonesToKeep, numStones));
_minBytesPerStone = maxSize / _numStonesToKeep;
// ...
}

其中_numStonesToKeep为oplog应该保持的Stone个数,而_minBytesPerStone代表每个Stone的最小字节数。

接下来,会根据oplog当前的大小以及_minBytesPerStone来估算下,当前的oplog大致包含的Stone数量,并通过采样的方式来获取每个Stone的起始位置(不能保证每个Stone的大小跟预期完全一样),然后将所有的Stone按顺序存储到一个队列中。

mongod在服务写请求的过程中,每次都会记录下新产生oplog的大小,当新产生的oplog的总量超过_minBytesPerStones时,就会产生一个新的Stone加入到队列中。

void WiredTigerRecordStore::OplogStones::createNewStoneIfNeeded(RecordId lastRecord) {

    if (_currentBytes.load() < _minBytesPerStone) {
// Must have raced to create a new stone, someone else already triggered it.
return;
} // ... OplogStones::Stone stone = {_currentRecords.swap(0), _currentBytes.swap(0), lastRecord};
_stones.push_back(stone); _pokeReclaimThreadIfNeeded(); // 唤醒后台回收oplog空间的线程
}

当队列中的Stone数量超过_numStonesToKeep,后台线程就会删除最老的Stone里的数据,来回收oplog的存储空间。

参考资料

转载自:https://yq.aliyun.com/articles/50138

MongoDB-3.2 oplog删除策略优化的更多相关文章

  1. Redis淘汰删除策略

    Redis淘汰删除策略 Redis淘汰删除策略6种淘汰Key策略3种删除过期键策略定时删除惰性删除定期删除其他模块的淘汰处理RDB 快照持久化创建载入AOF 只追加持久化写入重写主从复模式下对过期键的 ...

  2. MongoDB 索引的使用, 管理 和优化

    MongoDB 索引的使用, 管理 和优化 2014-03-25 17:12 6479人阅读 评论(0) 收藏 举报  分类: MongoDB(9)  [使用explain和hint] 前面讲高级查询 ...

  3. Redis生存时间、删除策略和排序

    生存时间 设置命令 expire key long:设置数据在long秒后过期. pexpire key long:设置数据在long毫秒后过期. ttl key:查询数据剩余的生存时间.如果数据已过 ...

  4. TODO:MongoDB的查询更新删除总结

    TODO:MongoDB的查询更新删除总结 常用查询,条件操作符查询,< .<=.>.>=.!= 对应 MongoDB的查询操作符是$lt.$lte.$gt.$gte.$ne ...

  5. oss文件删除策略

    当你想删除oss服务中某个bucket下的文件夹时,文件夹中又包含了太多文件,递归删除太过耗时,又必须删除时,此时就要用oss的文件删除策略,如下所示: OSSClient client = new ...

  6. Redis 过期键删除策略

    Redis 中数据库键的过期时间都保存在过期字典中,当一个键过期了,Redis 存在三种不同的删除策略:定时删除.惰性删除和定期删除 定时删除 定义 在设置键的过期时间的同时创建一个计时器,让定时器在 ...

  7. redis中key的过期键删除策略

    Redis过期键删除策略 Redis key过期的方式有三种: 被动删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key 主动删除:由于惰性删除策略无法保证冷数据被及时删 ...

  8. RMAN正确地删除Archivelog以及设置有备库的归档删除策略

    原文链接:http://blog.sina.com.cn/s/blog_64e166580100xks5.html 如何正确地删除Archivelog: Archivelog并不能直接得从OS层直接物 ...

  9. 伯克利、OpenAI等提出基于模型的元策略优化强化学习

    基于模型的强化学习方法数据效率高,前景可观.本文提出了一种基于模型的元策略强化学习方法,实践证明,该方法比以前基于模型的方法更能够应对模型缺陷,还能取得与无模型方法相近的性能. 引言 强化学习领域近期 ...

随机推荐

  1. 题解 CF1216D 【Swords】

    大水题,感觉比C题水多了...(证明倒是挺难) 题目大意:额,这个(实在总结不出) 还是题目描述吧:仓库里有$n$种相同数量($x$把)的剑(但你不知道有多少),一天有$y$人闯进了仓库,每人拿了$z ...

  2. Go语言学习笔记(8)——包和结构体

    包 —— 每个可执行的应用程序必须包含一个主函数,它是执行的入口点.主函数应该存在main包中. 结构体: 通过 . 操作符访问结构体的各个成员! 1. 定义结构体类型person: type per ...

  3. QuartzNet 任务管理系统

    最近有面试!都有问道Quartz方面的问题,之前的项目有使用过,也知道怎么用,但面试时要说出它的原理,一时半会还真说不来!查阅了一些资料先记录下来吧 Quartz.NET官网地址:https://ww ...

  4. Linux mount/unmount 挂载和卸载指令

    对于Linux用户来讲,不论有几个分区,分别分给哪一个目录使用,它总归就是一个根目录.一个独立且唯一的文件结构 Linux中每个分区都是用来组成整个文件系统的一部分,她在用一种叫做“挂载”的处理方法, ...

  5. interface Part1(接口详解)

    1. 在日常生活中,手机.笔记本电脑.平板电脑等电子产品提供了不同类型的接口用于充电或者连接不同的设备. 不同类型接口的标准不一样,例如电压.尺寸等. 2. 在C#语言中,接口也会定义一种标准,如果需 ...

  6. JavaScript 入门与进阶

    JavaScript 介绍 javascript 是运行在浏览器端的脚本语言,javascript 主要解决的是前端与用户交互的问题,包括使用交互 和 数据交互,javascript 是浏览器解释执行 ...

  7. react-native——tab配置及跳转

    在 App 中 tab 是常见的页面类型,在 RN 里使用 react-navigation 可快速地进行 tab 配置. 假设应用有4个页面,两个是tab页面,两个是详情页面. App.js //应 ...

  8. hashmap,hashtable,concurrenthashmap多线程下的比较(持续更新)

    1.hashMap 多线程下put会造成死循环,主要是扩容时transfer方法会造成死循环. http://blog.csdn.net/zhuqiuhui/article/details/51849 ...

  9. C#为什么要装箱和拆箱

    来自论坛4楼的回答非常棒,地址:https://bbs.csdn.net/topics/390624164?page=1 内容如下: 道理很简单,按理说C#被设计成一种完全面向对象的语言.因此,包括数 ...

  10. django操作mysql

    连接mysql 1.安装pymysql 操作指令 : pymsql: pip install pymysql 2.导入库 在项目目录下的__init__.py文件中导入pymysql模块 加入以下两行 ...