MongoDB 学习笔记之 WriteConcern
WriteConcern:
转载:MongoDB WriteConcern(写关注)机制
http://www.ywnds.com/?p=3688&viewuser=40
MongoDB部署模式
MongoDB的部署模式有三种:第一种是单机模式(开发测试);第二种是高可用复制集;第三种是可扩展分片集群。如下图所示。

知道了MongoDB几种常用的部署模式之后,接下来我们看看每种部署模式的写操作过程。
MongoDB单点写操作

从上图可以看出,其中primary是MongoDB的一个实例,里面有两个内存区域,一个是Data Buffer(数据缓冲)、一个是Journal Buffer(日志缓冲)。这两个内存区域分别对应物理文件Data File和Journal File。
当数据写入进来时,就会出现如下执行顺序:

1) 客户端的数据进来;
2) 数据操作写入到日志缓冲;
3) 数据写入到数据缓冲;
4) 返回操作结果到客户端(异步);
5) 后台线程进行日志缓冲中的数据刷盘,非常频繁(默认100)毫秒,也可自行设置(30-60);
6) 后台线程进行数据缓冲中的数据刷盘,默认是60秒;
MongoDB复制集写操作

复制集也是MongoDB最常见的一种部署模式,如果启用复制集的话,在内存中会多一个OPLOG区域,是在节点之间进行同步的一个手段,它会把操作日志放到OPLOG中来,然后OPLOG会复制到从节点上。从节点接收并执行OPLOG中的操作日志来达到数据的同步操作。
1) 客户端的数据进来;
2) 数据操作写入到日志缓冲;
3) 数据写入到数据缓冲;
4) 把日志缓冲中的操作日志放到OPLOG中来;
5) 返回操作结果到客户端(异步);
6) 后台线程进行OPLOG复制到从节点,这个频率是非常高的,比日志刷盘频率还要高,从节点会一直监听主节点,OPLOG一有变化就会进行复制操作;
7) 后台线程进行日志缓冲中的数据刷盘,非常频繁(默认100)毫秒,也可自行设置(30-60);
8) 后台线程进行数据缓冲中的数据刷盘,默认是60秒;
恢复日志Journal的作用
1) 用于系统宕机时恢复内存数据(不能像MySQL一样可以用来恢复历史数据)
2) 默认为异步刷盘
3) 刷盘间隔,MMAP引擎为30-100ms,Wiredtiger为100MB or checkpoint
4) 可使用j:1来强制同步刷盘
写关注机制Write Concern的作用
1) 用来指定mongod对写操作的回执行为。
2) 可在connection level或者写操作level指定。
3) Write conern支持以下值。
W: 0 | 1 | N | majority | tag
j:1
wtimeout:millis
1)当w:0为Unacknowledged

测试(会出现的数据丢失情况)

这里写一个循环插入10条数据,插入数据{_id:10,a:i},然后把writeConcern设置为0。根据上图我们可以看到print返回10条插入成功的信息,但是我们db.test.count()查看时只有一条数据,其余9条虽然没有插入成功但是也返回了正确信息(因为第一条数据_id:10为唯一键,再插入同样的数据就无法插入,两个ID不能相同)。就因为{writeConcern:{w:0}}导致出现异常时并没有返回错误信息给客户端。
2)当w:1为Acknowledged

测试(会出现的数据丢失情况)

当w:1时,就解决了w:0出现的问题,从上图可以看出第一条数据插入成功,其余9条数据都会插入失败并返回错误信息给客户端。
但是当w:1时mongodb就会在日志写完之后返回确定信息,虽然解决了w:0出现的数据丢失问题,但是w:1时如果出现系统崩溃也会导致数据丢失,那就是在日志信息还没有刷新到磁盘的那一刻发生系统宕机,此时内存日志的确是写入成功了于是mongodb就会返回确定信息。
我们可以通过w:1然后高速写入数据,然后通过killall -9 mongod来模拟系统崩溃(重启系统时要记住删除数据目录下的mongod.lock文件,不然启动起不来),最后检查程序写入的数据和实际插入的数据(这种情况发生几率不大)。

通过上图可以看出,数据丢失了731条。做上面这个实验时在执行journaldataloss函数时,需要开启另外一个会话用来模拟服务器宕机(killall -9 mongod)
针对w:1出现的服务器宕机时数据丢失的问题可以使用j:1来解决,j:1做到的是日志刷盘之后才会返回确定信息。
|
1
|
> db.test.validate(true)
|
函数脚本
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
function journaldataloss(){
var count=0, start = new Date();
try{
var docs=[];
for(var i=0;i<1000;i++) docs.push({a:i});
while(true){
var res=db.test.insert(docs);
count += res.nInserted;
if(count % 100000 == 0) print("inserted "+ count+"time used: " + (new Date().getTime() - start.getTime()/1000)
+" seconds");
}
}
catch(error){ print("Total doc inserted successfully:"+ count); }
}
|
3)当j:1为Journal

实例(测试会出现的数据丢失情况)

另一种情况

当j:1时可以解决w:1数据丢失的问题,但是随之而来的是Mongodb的性能会下降。虽然解决了服务器宕机时数据丢失问题(会丢失60s左右的数据,就是一次间隔没有刷新到磁盘的数据)。
但是无法解决另外一种情况,无论是w:1还是j:1都无法解决主备置换导致数据丢失的情况。上面我们介绍了MongoDB三种部署模式以及每一种模式的写操作流程。看下面这幅图,

当j:1时可以保证主节点数据的决定安全性,当日志落盘之后返回确定信息给客户端,那么接下来就会复制OPLOG到复制集中的从节点如果此时主节点宕机,OPLOG没有复制到从节点并且当主节点宕机后,Mongodb复制集会重新选举台secondary为primary。当secondary为primary后假设此时原先的primary被恢复了,启动之后成为了secondary节点,此时新的primary发现secondary有x数据而自己没有,那么此时就会出现数据回滚的情况,secondary会把x数据进行回滚到一个磁盘文件上(rollback_db_name),回头需要人工去处理,从用户角度出现这也是一种数据丢失的情况。那么怎么解决这种情况呢?就是下面我们要提到的w:2/N/majority可以解决这个数据丢失的情况,w:2决定了数据必须复制最少到一个从节点上时才会返回确定信息给客户端。
4)当w:2/N/majority replica Acknowledged

显然这种方式虽然保证了数据的一致性,但是无疑会拖慢MongoDB的性能。所以在MongoDB 3.2后官方又给出了一个readconcern机制,具体待研究。
Write concern总结
通过上面几幅图对Write concern的解释可以看出,这是一个对数据安全非常重要的参数,不管是开发还是运维人员都应该对Write concern机制非常了解。对于Write concern来说,级别越高数据越安全,但同时性能就会下降,在数据安全跟性能方面一向如此不能兼得。可根据自己的应用场景来决定Write concern的级别(默认是w:1)。其实j:1到不是特别重要,如果你使用好的复制集同时数据又特别重要的话就可以使用w:majority,因为mongodb中复制集的数据往往比日志跑的更快,也是一种更有效的方法。下图是对wirte concern的基本总结。

MongoDB 学习笔记之 WriteConcern的更多相关文章
- mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网: ...
- MongoDB学习笔记系列
回到占占推荐博客索引 该来的总会来的,Ef,Redis,MVC甚至Sqlserver都有了自己的系列,MongoDB没有理由不去整理一下,这个系列都是平时在项目开发时总结出来的,希望可以为各位一些帮助 ...
- PHP操作MongoDB学习笔记
<?php/*** PHP操作MongoDB学习笔记*///*************************//** 连接MongoDB数据库 **////*************** ...
- MongoDB 学习笔记(原创)
MongoDB 学习笔记 mongodb 数据库 nosql 一.数据库的基本概念及操作 SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数据库 table ...
- MongoDB学习笔记(转)
MongoDB学习笔记(一) MongoDB介绍及安装MongoDB学习笔记(二) 通过samus驱动实现基本数据操作MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB ...
- 【转】MongoDB学习笔记(查询)
原文地址 MongoDB学习笔记(查询) 基本查询: 构造查询数据. > db.test.findOne() { "_id" : ObjectId("4fd58ec ...
- MongoDB学习笔记(六)--复制集+sharding分片 && 总结
复制集+sharding分片 背景 主机 IP 服务及端口 Server A ...
- MongoDB学习笔记(五)--复制集 && sharding分片
主从复制 主从节点开启 主节 ...
- MongoDB学习笔记(四)--索引 && 性能优化
索引 基础索引 ...
随机推荐
- codeforces 816 C. Karen and Game(模拟+思维)
题目链接:http://codeforces.com/contest/816/problem/C 题意:给出一个矩阵,问能否从都是0的情况下只将一整行+1或者一整列+1变形过来,如果可以输出需要步数最 ...
- codeforces 798 C. Mike and gcd problem(贪心+思维+数论)
题目链接:http://codeforces.com/contest/798/problem/C 题意:给出一串数字,问如果这串数字的gcd大于1,如果不是那么有这样的操作,删除ai, ai + 1 ...
- DELPHI GDI + TGPFont UnitPixel 问题解决
查不少资料,在 GPfont := TGPFont.Create(fontFamily, Font.Size , FontStyleRegular,UnitPixel ); 时,显示的字体,并不是按D ...
- 【LeetCode】75-颜色分类
题目描述 给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 分别表示红色.白色 ...
- top_down设计技巧
写在前面的话 之前梦翼师兄和大家一起学习了层次化设计方法,大家应该懂了,哦,原来所谓的层次化设计就是将一个大的系统不断地拆分成一些便于实现的最小逻辑单元.如果大家真的只是这么想的话,那么梦翼师兄真的是 ...
- eclipse使用Gitlab
1.生成SSH key 用的是eclipse自带的生成key的工具,windows->preferences->General->Network Connections->SS ...
- Apache RocketMQ 消息队列部署与可视化界面安装
一.介绍 Apache RocketMQ是一个分布式.队列模型的消息中间件,具有低延迟.高性能和高可靠.万亿级容量和灵活的可扩展性.核心组件由四部分组成:Name Servers,Brokers,Pr ...
- Knative 实战:三步走!基于 Knative Serverless 技术实现一个短网址服务
短网址顾名思义就是使用比较短的网址代替很长的网址.维基百科上面的解释是这样的: 短网址又称网址缩短.缩短网址.URL 缩短等,指的是一种互联网上的技术与服务,此服务可以提供一个非常短小的 URL 以代 ...
- IDEA微服务项目的application.yml没有绿色叶子的解决办法
1.今天在写微服务项目的时候成功入坑,那么问题是啥呢?接下来和我一起走入bug的世界吧,让我们看看究竟是怎么回事. *问题描述 1.application.yml是灰色的小格子 2.实在难看 *需要解 ...
- Day 15 文件打包与压缩
1.什么是文件压缩? 将多个文件或目录合并成为一个特殊的文件.比如: 搬家...脑补画面 img. 2.为什么要对文件进行压缩? 当我们在传输大量的文件时,通常都会选择将该文件进行压缩,然后在进行传输 ...