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. Hi3531a海思logo加载的实现流程

    海思篇之开机logo的加载(Hi3531a命令版) 2019-02-02 11:31:51 Wilburn0 阅读数 479更多 分类专栏: 海思开发   版权声明:本文为博主原创文章,遵循CC 4. ...

  2. 怎样通过正则匹配IP地址

    Ipv4的地址是0.0.0.0 到 255.255.255.255, 匹配这个字段需要判断三种情况: 1. 如果第一位是0或1, 则第二位和第三位可以是0-9的任意数值: [01]\d\d 2. 如果 ...

  3. 【转发】Java split()用法

    特殊情况有 * ^ : | . \ 一.单个符号作为分隔符  String address="上海\上海市|闵行区\吴中路"; String[] splitAddress=addr ...

  4. 区块链公链分片技术(sharding)方案思维导图

  5. 编写Postgres扩展之五:代码组织和版本控制

    原文:http://big-elephants.com/2015-11/writing-postgres-extensions-part-v/ 编译:Tacey Wong 在关于编写Postgres扩 ...

  6. redis连接数高居不下,怎么破?。。。。这么破

    最近项目一直在使用redis,首次用redis,随便从网上找了例子就用了,一开始用的还挺正常,后来发现,当客户端访问量一上来,redis的连接数居高不下,一开始以为是客户端没有关闭,开始怀疑redis ...

  7. [Docker][ansible-playbook]3 持续集成环境之分布式部署

    预计阅读时间: 30分钟 本期解决痛点如下:1. 代码版本的多样性,编译环境的多样性如何解决?答案是使用docker,将不同的编译环境images统统打包到私有仓库上,根据需求进行下载,从宿主机上挂载 ...

  8. SUSE CaaS Platform 4 - 使用 NFS 作为持久存储

    SUSE CaaS Platform 4 - 持久存储使用 NFS

  9. HTML主体标签

    HTML标签 在HTML结构代码中可以看到非常多的<>,这就是html的标签.整块html代码几乎就是由各种各样的标签与标签内容构成,每一个标签对应一个网页上的一个小模块,如一段文字1,一 ...

  10. MySQL 数据库的高可用性分析

    MySQL数据库是目前开源应用最大的关系型数据库,有海量的应用将数据存储在MySQL数据库中.存储数据的安全性和可靠性是生产数据库的关注重点.本文分析了目前采用较多的保障MySQL可用性方案. MyS ...