ReadConcern与WriteConcern

太阳1年前技术文章596

一、ReadConcern

1、ReadConcern vs ReadPreference

ReadPreference 主要控制从副本集哪个节点来读取数据,该参数可以实现读写分离、就近读取的功能

primary:            只从主节点读取数据(默认值)
primaryPreference:  优先从主节点读取数据,主节点不可用时从备份节点读取数据
secondary:          只从备份节点读取数据
secondaryPreference:优先从备份节点读取数据,没有备份节点的时候从主节点读取数据
nearest:            根据网络距离就近读取

ReadConcern 决定读取数据时,读取到的是什么样的数据

local:      能够读取到任意数据           
majority:   只能读取到【成功写入到大多数的数据】

使用:

readConcern: { level: <"majority"|"local"|"linearizable"> }


2、ReadConcern可以解决什么问题

ReadConcern可以避免[脏读]

    存在一种情况时,当parimary节点写入数据,该记录并没有同步到secodary节点。此时parimary节点挂掉了,重新恢复后parimary节点因故障未同步到大多数的记录就会被回滚掉,导致用户在故障前查询的记录为[脏数据]。

    当ReadConcern为majority模式时,保证客户端读取到的数据是[写入到大多数的数据],这时及时parimary节点挂掉了,该记录也不会被回滚掉,就避免掉了[脏读]。

3、ReadConcern实现原理

    ReadConcern要使用majority模式必须打开replication.enableMajorityReadConcern参数,开启该参数后secondary节点会启动一个snapshot线程,该线程会周期性的对当前的数据集进行snapshot(初始状态都为uncommited),并记录snapshot时最新oplog的时间戳,得到一个映射表。只有确保oplog已经同步到大多数节点时,snapshot的状态才会变更为commited。

4、MongoDB如何确定oplog已经写入大多数?

Parimary节点:

    secondary节点oplog在发生变化时,会通过replSetUpdatePosition命令将oplog的进度同步给parimary节点,而且心跳检测信息中也包含了oplog的信息。所以parimary节点可以很快或缺到secondary节点的oplog的信息,当达到[大多数]原则后,parimary节点更新snapshot的状态为comminted状态。期间无效的snapshot会做删除处理。

Secondary节点:

    secondary节点在拉取parimary节点的oplog信息时,parimary会将[最新一条oplog已经同步到大多数节点]的信息同步给secondary节点,secondary节点会根据这个信息来更新自己的snapshot的状态。

5、注意事项

1.ReadConcern只能保证客户端在读取数据时,该记录在大多数节点上已经更新,但是不能保证读取到的数据是已经更新了的最新记录
2.ReadPreference可以限定客户端读取到的数据规则
3.目前readConcern主要用于跟mongos与config server的交互上,参考 https://yq.aliyun.com/articles/58689?spm=a2c4e.11153940.blogcont60553.8.2a0e2e23TDmv68
4.使用readConcern需要配置replication.enableMajorityReadConcern选项
5.只有支持 readCommited 隔离级别的存储引擎才能支持 readConcern,比如 wiredtiger 引擎,而 mmapv1引擎则不能支持。(!)

二、WriteConcern

WriteConcern主要控制客户端写入策略。

1、WriteConcern选项

1.w:<number> 数据写入number个节点才向客户端确认
    {w:0}:         对客户端的写入不需要发送任何确认,适用于性能要求高,但是不关注正确性的场景
    {w:1}:         默认值,数据写入parimary节点就向客户端发送确定
    {w:majority}:  数据写入大多数后向客户端发送确认,适用于数据安全性要求比较高的场景

2.j:<boolean> 写入操作的journal持久化后再向客户端确认  
    {j:false}       默认false,如果要求parimary节点的journal日志持久化后再向客户端发送确认的化需要将该参数改为true。

3.wtimeout:<milseconds> 写入超时时间,大于1有效

2、{w:majority}理解

    1)Client向Primary发起请求,指定writeConcern为{w: "majority"},Primary收到请求,本地写入并记录写请求到oplog,然后等待大多数节点都同步了这条/批oplog(Secondary应用完oplog会向主报告最新进度)。

    2)Secondary拉取到Primary上新写入的oplog,本地重放并记录oplog。为了让Secondary能在第一时间内拉取到主上的oplog,find命令支持一个awaitData的选项,当find没有任何符合条件的文档时,并不立即返回,而是等待最多maxTimeMS(默认为2s)时间看是否有新的符合条件的数据,如果有就返回;所以当新写入oplog时,备立马能获取到新的oplog。

    3)Secondary上有单独的线程,当oplog的最新时间戳发生更新时,就会向Primary发送replSetUpdatePosition命令更新自己的oplog时间戳。

    4)当Primary发现有足够多的节点oplog时间戳已经满足条件了,向客户端发送确认。

相关文章

开源大数据集群部署(九)Ranger审计日志集成(solr)

开源大数据集群部署(九)Ranger审计日志集成(solr)

1、下载solr安装包并解压包tar -xzvf solr-8.11.2.gzcd solr-8.11.2执行安装脚本./bin/install_solr_service.sh /opt/solr-8...

Redis 持久化机制 AOF

Redis 持久化机制 AOF

前言Redis 有两种持久化机制,分别是 RDB 与 AOF 本篇文章将介绍 AOF 的执行过程与应用。1. AOF 简介AOF (Append only file) 持久化是以独立日志的方式记录每次...

Grafana简介

Grafana简介

一、Grafana介绍Grafana 是非常强大的可视化项目,它最早从 kibana 生成出来,渐渐也已经形成了自己的生态了。研究完 grafana 生态之后,只有一句话:可视化,grafana 就够...

K3S部署和使用

K3S部署和使用

k3s介绍k3s是一个高可用的、经过CNCF认证的Kubernetes发行版,专为无人值守、资源受限、偏远地区或物联网设备内部的生产工作负载而设计。k3s安装参考文件使用配置文件安装k3s为了保证k3...

Linux解锁线程基本概念和线程控制,步入多线程学习的大门(2)

Linux解锁线程基本概念和线程控制,步入多线程学习的大门(2)

2.4.线程等待:为什么需要线程等待?已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。不然也会造成内存泄露问题!创建新的线程不会复用刚才退出线程的地址空间。主线程退出 == 进程退出 ==...

MySQL运维实战之备份和恢复(8.9)xtrabackup备份指定表

备份部分表如果实例设置了参数innodb_file_per_table,xtrabackup可以备份部分表。通过--tables,--tables-file,--databases,--databas...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。