MongoDB分布式原理以及read-preference和readConcern解决读写一致性问题
MongoDB词汇表:
https://docs.mongodb.com/manual/reference/glossary/#term-replica-set
MongoDB分布式原理
primary
In a replica set, the primary is the member that receives all write operations. See Primary.
在副本集中,主库是接收所有写操作的节点。
secondary
A replica set member that replicates the contents of the master database. Secondary members may handle read requests, but only the primary members can handle write operations. See Secondaries.
一个副本集,其复制所述主数据库中的内容。次节点:读请求。主库:写操作。
复制
允许多个数据库服务器共享相同数据的功能,从而确保冗余并促进负载平衡。请参见复制。
https://docs.mongodb.com/manual/replication/#replication-auto-failover
复制提供冗余并提高 数据可用性。使用不同数据库服务器上的多个数据副本,复制可提供一定程度的容错能力,以防止丢失单个数据库服务器。
在某些情况下,复制可以提供更大的读取容量,因为客户端可以将读取操作发送到不同的服务器。在不同数据中心中维护数据副本可以提高数据本地性和分布式应用程序的可用性。您还可以维护其他副本以用于专用目的,例如灾难恢复,报告或备份。
异步复制
辅助节点复制主节点的操作日志,并将操作异步应用于其数据集。通过使次要节点的数据集反映主要节点的数据集,即使一个或多个成员失败,副本集也可以继续运行。
故障转移
在发生故障时允许副本集的辅助成员成为主库成的过程。请参阅自动故障转移。
如果主要节点不可用,则符合条件的次要节点将进行选举以自行选举新的主要节点。
自动故障转移
时机:当主节点与集合中的其他成员的通信electionTimeoutMillis时间超过配置的时间段(默认为10秒)时。
由于突发的网络延迟等因素,群集可能会频繁选举,即使该主节点处于健康状态也是如此。
方式:合格的辅助节点将要求选举以提名自己为新的主节点。群集尝试完成新主数据库的选择并恢复正常操作。
副本集无法处理写入操作,直到选举成功完成。
如果将副本集配置为在主副本处于脱机状态时在次副本上运行,则副本集可以继续提供读取查询 。
应用程序连接逻辑应包括对自动故障转移和后续选举的容忍度。
从MongoDB 3.6开始,MongoDB驱动程序客户端可以检测到主数据库的丢失,并一次自动 重试某些写入操作,从而提供了自动故障转移和选择的其他内置处理。
https://docs.mongodb.com/manual/core/retryable-writes/#retryable-writes
选举
副本集的成员在启动时和发生故障时选择主库的过程。请参阅 副本集选择。
https://docs.mongodb.com/manual/core/replica-set-elections/#replica-set-elections
最终一致性
分布式系统的属性,允许对系统的更改逐渐传播。在数据库系统中,这意味着不需要可读成员始终反映最新的写入。
====================
readPreference和readConcern配合使用
readPreference 主要控制客户端 Driver 从复制集的哪个节点读取数据,这个特性可方便的实现读写分离、就近读取等策略。
primary
只从 primary 节点读数据,这个是默认设置primaryPreferred
优先从 primary 读取,primary 不可服务,从 secondary 读secondary
只从 scondary 节点读数据secondaryPreferred
优先从 secondary 读取,没有 secondary 成员时,从 primary 读取nearest
根据网络距离就近读取
readConcern 决定到某个读取数据时,能读到什么样的数据。
local
能读取任意数据,这个是默认设置majority
只能读取到『成功写入到大多数节点的数据』
========================
read-preference
官网地址:https://docs.mongodb.com/manual/core/read-preference/
读取首选项描述了MongoDB客户端如何将读取操作路由到副本集的成员。
默认情况下,应用程序将其读取操作定向到副本集中的 主要成员(即读取首选项模式“主要”)。但是,客户端可以指定读取首选项,以将读取操作发送到辅助对象。
读取首选项模式 | 描述 |
---|---|
primary | 默认模式。所有操作均从当前副本集primary读取 。 包含读取操作的多文档事务必须使用读取首选项 |
primaryPreferred | 在大多数情况下,操作从主服务器读取,但如果不可用,则从辅助 成员读取操作。 |
secondary | 所有操作均从副本集的辅助成员读取。 |
secondaryPreferred | 在大多数情况下,操作会从辅助 成员读取,但如果没有辅助成员可用,则操作会从primary读取。 |
nearest | 从副本集的成员读取的操作具有最小的网络延迟,而与成员的类型无关。 |
==================
readConcern
官网地址:https://docs.mongodb.com/manual/reference/read-concern/
该readConcern选项使您可以控制从副本集和副本集分片读取的数据的一致性和隔离性。
通过有效使用写入关注点和读取关注点,您可以适当地调整一致性和可用性保证的级别,例如等待更强的一致性保证,或者放宽一致性要求以提供更高的可用性。
为MongoDB 3.2或更高版本更新的MongoDB驱动程序支持指定读取关注。
readConcern 的是为了在于解决脏读问题,用户从 MongoDB 的 primary 上读的数据并没有同步到大多数节点,然后 primary 宕机恢复, primary节点会将未同步到大多数节点的数据回滚,导致用户读到了脏数据。
当指定 readConcern 级别为majority ,能保证用户读到的数据已经写入到大多数节点,而这样的数据肯定不会发生回滚,避免了脏读的问题。
需要注意的是,readConcern 只是保证读到的数据不会发生回滚,但并不能保证读到的数据最新。
参考官网:
误区: majority并非从多节点读取,依然是单节点读取。
readConcern 原理
snapshot 0,1,2,3......N的状态是committed/uncommitted
同步到大多数节点时,对应的snapshot会标记为commmited。
用户读取:读最新的 commited 状态的 snapshot,这样就保证了读到的数据是已经同步到大多数节点。
secondary节点在自身oplog发生变化会同步信息到primary。
primary节点统计超过半数的节点的同步信息就修改该snapshot为uncommitted->commited。
同时secondary拉取oplog的同时从primary节点得到最新一条已经同步到大多数节点的oplog,更新自身的 snapshot 状态。
参考:
https://yq.aliyun.com/articles/60553
https://yq.aliyun.com/articles/663931
readConcern 主要用于跟 mongos 与 config server 的交互上
当写入新文档时,mongos 从config server 上获取集合的路由表本地,如写入shardX的文档,则请求被路由到shardX上写入。
mongos 从 config server 上获取到路由表后,会缓存在本地内存,避免每次写入/查询都去 config server 上取表。
mongos 在写入时,会带上自身缓存的路由表版本,当请求到达 shard后,shard 发现 mongos 的路由表版本比自己的低,则说明路由表已经发生过更新,这时 mongos 会重新到 config server 上取最新的路由表,然后按新的路由表来写入。
https://yq.aliyun.com/articles/58689
Mongos本身并不持久化数据,Sharded cluster所有的元数据都会存储到Config Server,而用户的数据则会分散存储到各个shard。Mongos启动后,会从config server加载元数据,开始提供服务,将用户的请求正确路由到对应的Shard。
https://yq.aliyun.com/articles/32434
================
Read Concern "majority"
https://docs.mongodb.com/manual/reference/read-concern-majority/index.html
考虑以下写入三个成员副本集的操作Write0的时间轴:
注意 为了简化,该示例假定:
Write0之前的所有写操作已成功复制到所有成员。
Writeprev是Write0之前的上一次写入。
Write0之后未发生其他写操作。
然后,下表总结了在时间T具有“多数”读取关注的读取操作将看到的数据状态。
最新数据不在大部分机器:
脏数据:
相关文章:

Lua(Codea) 中 table.insert 越界错误原因分析
2019独角兽企业重金招聘Python工程师标准>>> Lua(Codea) 中 table.insert(touches, touch.id, touch) 越界错误原因分析 背景介绍 在 Codea 上运行其他人以前写的代码时, 发现某段处理 touch 事件的代码总是报错, 开始报浮点数没有整型的表示, 修改代码增加类型转换…

【MATLAB】符号数学计算(六):符号函数的操作
一、复合函数的操作 compose(f,g):返回复合函数f(g(y)),此处ff(x),gg(y);compose(f,g,x,z):返回自变量是z的复合函数f(g(z)) >> syms x y >> fsym(xx^-1); >> gsym(sin(x)); >> h(1y^2); >…

java中如何应对读改写场景
前言 volatile可以确保数据及时刷新到主存,但是对于读改写场景还是无能为力 举个例子 public class ConcurrentHashMapExample {public static void main(String[] args) throws InterruptedException {Map<String, Long> ordersMap new ConcurrentHashMap&l…

Apache Hudi的写时复制和读时合并
Apache Hudi http://hudi.apache.org/ http://hudi.apache.org/docs/quick-start-guide.html Hudi是什么 Hudi将流处理带到大数据,提供新数据,同时比传统批处理效率高一个数量级。 Hudi可以帮助你构建高效的数据湖,解决一些最复杂的底层…

顶尖程序员不同于常人的 5 个区别
2019独角兽企业重金招聘Python工程师标准>>> 《The Effective Engineer》的作者在写书的过程中,为了了解那些顶级程序员和普通程序员的区别,采访了很多硅谷顶级科技公司的顶尖软件工程师。他发现这些给世界带来巨大影响的的工程师们至少有以下…
【MATLAB】符号数学计算(七):符号微积分、符号微分方程求解、符号代数方程求解
一、符号表达式的极限 limit(F,x,a):求当时,符号表达式F的极限。limit(F,a):符号表达式F采用默认自变量(可由函数findsym求得),该函数求F的自变量趋于a时的极限值。limit(F):符号表达式采用默认…

Qt运行时中文乱码的解决办法
QT5的解决办法,在类之前添加: #pragma execution_character_set("utf-8")QT4解决办法: QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());转载于:https://www.cnblogs.com/bjxingch/articles/9992998.html

更换yum的源为阿里云或者网易
1.备份原本的yum源: #mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 2.下载阿里云的yum源: CentOS6,CentOS7,CentOS8下对应的即可 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Ce…

socket编程:多路复用I/O服务端客户端之poll
一. 关于poll对于IO复用模型,其优点无疑是免去了对一个个IO事件就绪的等待,转而代之的是同时对多个IO数据的检测,当检测等待的事件中至少有一个就绪的时候,就会返回告诉用户进程“已经有数据准备好了,快看看是哪个赶紧…
【MATLAB】符号数学计算(八):符号分析可视化
一、funtool分析界面 在命令行窗口中输入: funtool 这里就说一下第四排: Insert:把当前激活窗的函数写入列表Cycle:依次循环显示fxlist中的函数Delete:从fxlist列表中删除激活窗的函数Reset:使计算器恢复…

java 根据实体对象生成 增删改的SQL语句 ModelToSQL
2019独角兽企业重金招聘Python工程师标准>>> java 根据实体对象生成 增删改的SQL语句 ModelToSQL 转载于:https://my.oschina.net/miaojiangmin/blog/2907010

深入浅出SpringBoot源码分析
Spring源码非常多,不要迷失在源码的汪洋大海里,抓住主要脉络,有需要再研究即可。 Bean的初始化 1.发现所有的bean ComponentScanAnnotationParser.parse()调用doScan()扫包 这里只是扫用户定义的bean,系统的自然不用扫 ClassPathBeanDefinitionScanner.doScan protected…

HBase基本知识
为什么80%的码农都做不了架构师?>>> 概述 HBase 特性: 强一致性读写: HBase 不是 "最终一致性(eventually consistent)" 数据存储. 这让它很适合高速计数聚合类任务。自动分片(Automatic sharding): HBase 表通过region分布在集群…

【编程题】猜年龄
题目标题: 猜年龄 美国数学家维纳(N.Wiener) 智力早熟,11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。 一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,他回答说: “我年龄的立方是个…

XenServer和VMware vSphere技术比较
此次将Citrix XenServer7.1和VMware ESXi 6.5从技术角度进行比较,并从企业角度对企业关心的项进行比较。主要包含市场地位、服务器虚拟化底层稳定性、管理架构、兼容性上进行分析。 市场地位 VMware在虚拟化的地位类似于大型存储中的EMC、小型机中IBM、网络中的思科…

阿里巴巴开源的缓存框架JetCache创建缓存
官网:https://github.com/alibaba/jetcache/wiki/CacheAPI_CN ======================= 多层嵌套缓存无效的问题: https://github.com/alibaba/jetcache/issues/424 某个service的方法加缓存注解,然后引用同一个类的另一个加缓存注解service的方法,这样必须在类里面注入…

【Python】百度翻译的爬虫实现(前篇)
该程序只能实现中文到英文的翻译 import requestsimport jsonurl "http://fanyi.baidu.com/basetrans"query_str input("请输入要翻译成英文的内容:")data{ "query": query_str,"from": "zh","to"…

github每次推送都要输入用户名和密码
/****************************************************************************** github每次推送都要输入用户名和密码* 说明:* 今天开始使用github管理一些东西,但是每次提交都出现要输入用户名和密码,* 这简直让人…

ELASTIC SEARCH 性能调优
ELASTICSEARCH 性能调优建议 创建索引调优 1.在创建索引的使用使用批量的方式导入到ES。 2.使用多线程的方式导入数据库。 3.增加默认刷新时间。 默认的刷新时间是1秒钟,这样会产生太多小的SEGMENT,导致未来的合并压力,如果调整这个大小&…

Android开源中国客户端学习 (自定义View)左右滑动控件ScrollLayout
左右滑动的控件我们使用的也是非常多了,但是基本上都是使用的viewpager 等 android基础的控件,那么我们有么有考虑过查看他的源码进行定制呢?当然,如果你自我感觉非常好的话可以自己定制一个,osc的ScrollLayout就是自己定义的View 和Viewpager的区别还是不小的 代码不是很多不…
【Python】有道翻译的爬虫实现(前篇)
import requestsimport jsonurl "http://fanyi.youdao.com/translate_o?smartresultdict&smartresultrule"data {"i": "我喜欢学习", "from": "AUTO", "to": "AUTO", "smartresult":&q…

自动生成纯文本表格的工具
https://tableconvert.com/?outputtext 有时候需要写文档的时候生成这种纯文本表格,这个工具真的很方便,贴上数据就可以了。

《Java编程思想》笔记13.字符串
点击进入我的博客 字符串操作是计算机程序设计中最常见的行为 13.1 不可变String String底层是由char[]实现的,是不可变的。看起来会改变String的方法,实际上都是创建了一个新的String对象,任何指向它的引用都不可能改变它本身的值。 13.2 重…
【Python】有道翻译的爬虫实现(后篇)
前面说到,有道翻译和百度翻译不同 (百度翻译是模拟iPhone手机,可能百度翻译用Pc端也会有类似的问题,有道翻译的User—Agent是Pc端) 每一次的salt和sign都不一样,这是什么原因产生的呢? 一、每…

Redis客户端JetCache的单机版和集群版的配置
jetcache基础应用参考这个:阿里巴巴开源的缓存框架JetCache创建缓存 1.JetCache的jedis配置 https://github.com/alibaba/jetcache/wiki/Config_CN jedis配置:apollo版 jetcache.remote.default.type = redis jetcache.remote.default.keyConvertor = fastjson jetcache.r…

5 分钟一次理解 Spring IOC !
今天我们分析一下 spring 的 IOC,梳理一下 IOC 和 DI 的概念与原理。在网上看到开涛有篇文章写的不错,提取其中一部分精华内容并做一些解读。 1.1.IOC是什么? Ioc—Inversion of Control,即“控制反转”,不是什么技术&…

工作两年的编程感想
2019独角兽企业重金招聘Python工程师标准>>> 工作已有两年了,两年不长也不短了,程序员的辛酸苦乐也都体验了一些,故写此博客既为留念,也为接下来的两年留下一个参考点。 首先需要声明的是,本人的工作是Java…

微服务重构心得
现在都在做微服务,看起来就是做服务拆分比较简单,但是实际上真正重构起来又遇到许许多多的问题。 微服务重构常见问题 1.领域驱动模型的困扰 比如听到很多理论比如领域驱动,那么到底需要不需要学习或者使用领域驱动呢? 2.系统的复杂性 重构的时候发现系统之间调用非常…

【Python】百度翻译的爬虫实现(后篇)
这个程序可以实现中英文的自动识别然后进行翻译 看着程序就很好理解。 import requestsimport jsonclass Translation():翻译def __init__(self,content):self.content contentself.url "http://fanyi.baidu.com/basetrans"self.headers {"User-Agent"…

美团即时物流的分布式系统架构设计
背景 美团外卖已经发展了五年,即时物流探索也经历了3年多的时间,业务从零孵化到初具规模,在整个过程中积累了一些分布式高并发系统的建设经验。最主要的收获包括两点: 即时物流业务对故障和高延迟的容忍度极低,在业务复…