开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,(共2000人左右 1 + 2 + 3 + 4 +5) 新人奖直接分配到5群,另欢迎 OpenGauss 的技术人员加入。
这里翻译一篇关于 mongodb 数据一致性的白皮书,这是一份有10页的文档。基于数据一致性的部分内容,在其他的传统数据库,缓存数据库都不存在,也是一个让传统DBA 想不明白的部分,所以进行翻译。
继续第一篇:
在上一篇中我们讨论了写入和读取的concern的级别,下面我们将讨论细节,在本文中,我们将在存储引擎层引用一个事务为wiredTiger事务,为提供高可用性,Mongodb 提供了作为复制集运行数据库的功能,复制集合采用基于 leader的一致性协议,类似raft协议,在一个复制集中存在一个primary和众多的secondary,主节点接受客户的数据写入并将其 插入到oplog的日志,oplog是一个逻辑日志,齐总每个条目包含关于如何应对单个数据库操作的信息,每个条目都有自己的时间戳这些时间戳是有序的,这些时间戳在节点日志中是唯一且完全有序的,oplog条目不包含足够的信息来撤销操作,可以看做一个普通的文档的集合,当不在需要的时候,最老的文档将被删除,文档会被重复利用,循环利用,从节点复制OPLOG并应用,通过这个方式来同步数据,基于这样的方式,其他的从及节点也可以从,secondary 上拉去自己还未得到的oplog,一旦受到就应用,不必以事务的方式来应用。
客户端写入必须发送到主节点,而读取可以发送到主节点或从节点,客户通过驱动程序与复制集进行交互,驱动程序是一个客户端的库,实现了与复制集正确通信兵监控其健康状态的标准规范,在内部,驱动程序通过类似RPC的协议与复制集的节点通信,以BSON格式发送数据,为实现水平扩展MongoDB 还提供了分片功能,允许用户将数据分布在多个复制集中,但本文不会讨论分片的详细信息。
MongoDB中的一致性级别,在MongoDB复制集中,一致性级别通过ReadConcern和writeConcern级别想客户暴露,这两个级别是任何读取或写入操作的参数,要理解和读取和写入关注的语义,需要对MongoDB 复制系统中的操作的生命周期有了解,MongoDB复制系统将进入系统的而每个写入操作串行到oplog中,当操作由副本集的主节点处理时,该操作的效果必须被写入数据库,并且该操作的描述也必须写入oplog,MongoDB中的所有操作都发生在wiredTiger 事务中,当操作的事务提交是,我们称为本地提交,一旦他被写入数据库和oplog中,他可以被复制到从节点,当oplog数据传播到足够多的节点的情况下,我们称之为大多数提交,这意味着它在复制集中是永久持久性。
writeConcern可以被指定为数值,或majority,在任何写入语句中,w:1写操作的客户端将在该写入在服务器的主节点后,立即受到确认,当你将语句中带入 w:N 完成的时候,写操作至少会写入N个服务器后才在本地将事务提交,当你写入 w:majority的时候,写操作客户端在写入操作被大多数提交之前不会受到事务的确认信息。
这意味着,写入将对复制级中任意一组节点的临时或永久性来说是具有弹性的,这也是Mongodb 在事务的一致性上,能做到其他数据库无法达到的弹性。假设你希望你写入的数据在操作系统层面或硬件层面不存在丢失的可能性,则 w:大多数,可以向你的写入的客户端保证数据不丢失。
写关注还可以接受一个布尔值,"j"参数,该参数确定数据在想客户端确认之前是否在复制节点上被日志记录,甚至你可以指定数据必须写到你指定的那个节点上,本文不再详细讨论j 或 tag set选项,指定写入关注客户端操作可能会收到服务器不同类型的相应,这些写入关注相应可分为两类,满足和不满足,满足的写入关注意味着必须以满足必要条件,如在w:2的情况下,客户端会保证已经有两个数据库服务器节点写入了数据后才能反馈写入任务完成,对于不满足的写入关注,这并不一定意味着写入失败,写入只是为达到预期的写入节点数量的需求,稍等写入达到节点的数量要求就会进行反馈。
readConcern 确定从服务器返回的数据的持久性和在某些情况下的一致性,在readConcern级别"local"执行读取操作的时候,返回的数据将反应查询执行在副本集合中的部分节点的局部情况,**(这里不是翻译,是我个人的理解,传统DBA可以理解为脏读,但仅仅是类似并不是概念的完全对齐,只是方便快速理解),**这里并没有保证返回的数据是大多数提交的,他只反应特定节点所知道的最新的数据情况,存在读取的数据。在他读取任何本地提交的数据,使用readConcern级别"majority"进行读取操作,保证只返回大多数提交的数据,对于大多数读取,返回的数据的是否是最新的并不重要,而是已经确认一定会commit的数据。
同时MongoDB还提供了可线性化的readConcern,当w:majority写操作结合时提供最强的一致性保证,使用readConcern 级别"线性化"进行读取的操作保证返回在读取操作开始前返回的结果如上提出的在大多数Mongodb 已经落盘。在操作中这是自动判断的,在读取的某个瞬间来判断返回的数据是否在大多数节点应用。
MongoDB提供可用和快照读取的级别,支持因果一致性读取的能力,同时MongoDB 本身虽然是文档数据库,但具有MVCC的能力,提供快照隔离,由可用"读取"关注提供的一些特定的细节在本文中,不做讨论。