网站的基本设置,迁安网站建设公司,网站官网建设企业,专业微网站制作分布式技术浅见之复制 前言一、何为复制#xff1f;1.1 主从复制和无主从复制1.2 同步复制与异步复制1.3 来点栗子1.3.1 Redis1.3.2 Mysql1.3.3 Mongo 二、复制是如何实现的#xff1f;2.1 复制的过程2.2 来点栗子2.2.1 Redis2.2.2 Mysql2.2.3 Mongo 2.2 复制的实现方式2.4 举… 分布式技术浅见之复制 前言一、何为复制1.1 主从复制和无主从复制1.2 同步复制与异步复制1.3 来点栗子1.3.1 Redis1.3.2 Mysql1.3.3 Mongo 二、复制是如何实现的2.1 复制的过程2.2 来点栗子2.2.1 Redis2.2.2 Mysql2.2.3 Mongo 2.2 复制的实现方式2.4 举个例子2.4.1 Redis2.4.2 Mysql2.4.3 Mongo 三、复制所带来的一些问题3.1 节点故障和切换3.2 来点栗子3.2.1 Redis3.2.2 Mysql3.2.3 Mongo 3.2 复制滞后问题3.2.1 读自己的写Read own writes3.2.5 读后写Writes follow reads3.2.2 单调读Monotonic reads3.2.4 单调写Monotonic writes 3.3 来点栗子3.3.1 Redis3.3.2 Mysql3.3.3 Mongo 后记参考 前言
最一段时间又较为详细的看了DDIA的几个重点章节对分布式相关技术有了一些新的理解和感悟所以想以博客的形式系统的梳理、总结下来希望可以便人便己。
当前的互联网业务中大都用到了分布式系统。从上层的微服务业务到下层的分布式数据库应该这么说稍微有点量的互联网业务都会使用分布式的相关技术来提升系统整体的性能和可用性。 尤其是分布式数据库作为业务中几乎必不可少的一个组件为了达到高的扩展性和可用性 都会或多或少的采用一些分布式的数据库系统。学习理解这些技术一是可以更好的使用这些组件二是理解分布式的思维方式以分布式的相关思路来解决高并发、高可用的问题。
分布式是一个大系统涉及到包括复制、分片、一致性等诸多内容本篇主要总结讨论分布式主要是分布式数据库中中复制里涉及到的一些内容并简要介绍redis、mongo和mysql这几种具体的数据库系统是如何处理相应细节的。
废话不多说了开整。 一、何为复制
我们现实中的复制主要是为了保存多个相同一致的事物以达到共享或者冗余的目的。分布式中的复制也很类似它主要是通过网络将相同的数据内容复制到多个节点一般就是不同的机器上上我们把这些相同的数据叫做一个一个的副本承载的机器叫做副本节点下文也简称为副本。这么做直观上有两个好处
一是达到冗余的目的当一个副本损坏了包括承载的机器挂了或者数据损坏了其他的副本可以顶上来。二是多个副本可以同时提供服务理论上可以把性能提升N倍当然理想丰满现实骨感。各种各样的限制使之成为不可能
还有一个不那么明显的引申好处是可以把多个副本放在不同的区域放在离用户近的区域这样就会降低不同地域的访问延时。
ok复制那就复制吧拿个U盘把相同的数据拷贝一份行不 如果数据已经完全不变了这种方式或许可行。但实际情况是由于在不断的提供服务数据库中的数据总是在不断的变化停机拷贝的方式虽然在某些备份系统中也略有耳闻但在实际的分布式副本复制用处不大。
因此现在的分布式数据库大都是在接受客户端请求的同时将数据的变化通过网络实时传到其他的副本中以达到各个副本中数据一致。如下图所示。 这里又涉及到2个问题。
以哪个副本节点为主导接收客户端的请求呢还是所有的副本都可以接受客户端的请求呢何时给客户端返回结果呢是所有的副本都达到一致了再给客户端返回还是只要一个节点接收到请求就给客户端返回后续再慢慢复制数据呢
这涉及到两类复制的方式。
1.1 主从复制和无主从复制
第一个问题引申出了单主从复制、多主从复制和无主复制。
所谓单主从复制指的是由一个主节点对对于多分区情况则可能是每个分区一个主节点多个从节点。主节点接收客户端的写请求从节点不断从主节点复制数据。写入是只能从主节点写入但读取时可以从多个从节点读取达到扩展读性能的要。如下图所示 而多主复制指的是接受客户端请求的有多个主节点然后这多个主节点将数据同步至其他的副本节点。下图所示
最后一种放的更开允许所有的副本节点接受客户端的请求所有的节点都是主节点接收到写入请求之后需要同步至其他所有的节点这种方式也叫做去中心化复制。
后两种方式有一个最大的问题就是多个主节点如果需要处理同一个数据或者有关联的数据需要处理数据冲突的问题。而第一种方式在实际中应用的最多本文也主要讲的就是这种单主从方式下文中主从复制也主要讲的就是单主从复制。
1.2 同步复制与异步复制
第二个问题引申出了同步复制和异步复制。 前者表示从节点向主节点返回复制成功时主节点才向客户端返回成功这保持了更高程度的一致性但是可能会由于网络或者从节点异常等情况造成整体的写服务异常 如下图所示。 异步复制就是主节点不管从节点的复制直接向客户端返回。但是可能会有一定程度上的数据不一致如果主节点宕机数据可能会造成一定程度的丢失。
显而易见在客户端看来同步复制的响应时间最长但是数据更稳定可靠性更高。而异步复制客户端得到的响应时间最短但如果后续的异步复制过程出了问题数据会丢失或者各种奇奇怪怪的问题下文会讨论。
除了完全的同步复制和异步复制之外还有一种介于他两之间的半同步复制即数据写入到一部分节点之后将结果返回给客户端算是一种折中的平衡。一般来说写到大多数副本节点中就给客户端返回结果在实际中应用的比较多和选主算法结合。
1.3 来点栗子
1.3.1 Redis
无论是单纯的主从复制复制、哨兵模式还是集群模式redis的复制模式使用的是单节点的主从复制。而且作为一个缓存系统为了提高性能在实际中使用到的redis大都是完全异步模式。毕竟redis本身的定位就是一个缓存性能是其首要的关注点可靠性和一致性的要求相对来说没那么高。
1.3.2 Mysql
对于mysql来说其内建的复制很简单仅仅算是提供了一个备库follow主库的功能让备库可以从主库中同步数据。所以默认情况下它的主从模式是一种异步复制的系统依靠从节点follow主节点的方式来完成各个从节点之间没有啥联系也不会知道其他从节点存在如下图所示。下文对mysql的举例主要指的就是这种方式。 当然在MySQL 5.5 引入了一种半同步复制模式。该模式可以确保至少一个从库接收完主库发送的binlog日志文件并写入到自己的中继日志里(可以简单理解为至少有一个从节点接收到了数据)然后会给主库一个反馈告诉主库已经接收完毕。然后主库才会将结果反馈给客户端。
现在各大厂商也有提供各种MySQL cluster 集群方式 有些已经支持完全同步复制当所有的从库都接收到了主库的复制日志主库才会向客户端返回。
1.3.3 Mongo
mongo的副本复制方式算是一种用户可控的同步。它提供了一个参数writeConcern让上层的使用者来决定在返回给客户端之前要把数据同步到哪些机器上0,1,majority等甚至可以给机器打tag让mongo把数据同步到具有某些tag的节点上。
这种writeConcern其实是属于一种Quorum副本管理机制通过控制读写副本的个数来改变整个系统的一致性和高可用性算是一种可调一致性。mongo直接把这个设置交给了上层使用者这便是让使用者来决定业务是需要一致性更高些还是可用性更高些。
所以如果非要说mongo的副本复制是属于哪种方式我觉得算是一种可调整的半同步复制方式。
二、复制是如何实现的
2.1 复制的过程
如果主节点和从节点是同时启用的ok 好那么主节点接收到的数据会通过变更的方式不断传给从节点从节点和主节点的数据保持相对同步。但如果从节点是“半路”加入的比如说想要扩充副本数量那么就必须先把加入之前数据先获取到。
总结起来大概是这样 一般来说当添加一个从节点时主节点会向从节点传输数据。这主要分为两个过程首先发送T0从节点加入的时刻时刻的一个快照 当从节点将快照中的数据apply完成之后再发送从T0时刻到当前时刻T1所有的数据更改日志一般来说是命令序列。如下图所示。
当然这个过程有些数据库系统是全自动的有些则需要人工介入。
2.2 来点栗子
2.2.1 Redis
redis主从同步中的异步复制就是像上述那样玩的它把这两个过程叫做同步Sync和命令传播Command Propagate。 当从节点slaveof 主节点之后主节点发送一个RDB可以理解为T0时刻的快照然后从节点apply这些RDB文件同步过程结束 之后命令传播过程开始主节点源源不断的向从节点传递之后的命令序列。
2.2.2 Mysql
对于mysql内建的主从复制来说添加一个从节点并不向Redis和Mongo那样自动化。添加一个从节点 默认情况下主节点只会将新的数据变更同步到从节点而不会自动同步主节点已有的那些数据也就是说没有初始化数据的过程。需要人工通过快照或者备份的方式将数据导入到从节点中。
2.2.3 Mongo
mong的复制也分为这两个阶段。当新的节点加入的时候会启动Initial Sync这个过程会扫描源节点不一定是主节点的所有collection除了源节点的local database然后插入到目标节点注意这里用了插入说明这种复制方式是属于逻辑上复制即scan and insert这里要说明的是除了同步具体的数据之外在这个过程还会把数据库的索引也同步到目标节点。
当第一阶段同步完成之后节点会进入SECONDAY阶段。在这个阶段通过复制其他节点的oplog操作日志来同步最近的客户端操作。
这里额外说明两点 第一mongo的第一阶段除了可以使用逻辑上的复制之外还可以使用File Copy Based的方式这种方式是直接复制数据库文件有点类似于快照的形式效率更高但是有一些限制。当然这种高级的复制方式按照官网的说法需要企业版的。
第二点与redis不同的是在这两个阶段中虽然大部分情况下源节点都是主节点。但是mongo提供了一定的配置选项可以选择其他的副本节点作为源节点当然选择这种副本节点要有一定的规则总的原则就是数据更新、网络更好具体的规则细节这里就不讨论了。
2.2 复制的实现方式 这里所说的实现方式指的是上述数据同步的过程中传递的到底是什么
从节点和主节点的数据保持一致笼统一点说大都是通过把日志发送给从节点然后从节点来apply日志达到和主节点一致的状态。但是这种“日志”具体实现是通过什么方式呢也就是说这个“日志”是怎样的目前主要有以下几种方式
基于磁盘同步的方式进行传输。将主节点执行命令之后要写入磁盘的数据打成日志传输给从节点。这种日志携带了类似于传输“在磁盘的某个地址写入某些字 节序列”的相关信息。 显而易见这种方式和底层的存储联系比较紧密如果底层存储格式发生了变更很有可能会有不兼容的情况发生。 当然好处是这种方式执行的较快。
比如说DRBD这种块级同步复制技术它是一个以 Linux模块方式实现的块级别同步复制技术。它通过网卡将主服务器上每个的块设备上复制到另一个服务器的块设备(备用设备)并在主设备提交块之前记录下来。
复制执行语句。这种情况简单来说就是主节点执行的命令让从节点按照顺序执行一遍。很好理解。 但是这里面有一个问题对于某些非确定性的命令比如说一些获取随机数获取当前时间这类命令从节点和主节点执行会得到不同的值。对于这个问题有一种解决方式是让主节点把这种非确定的数据转换成执行后确定的数据 a在再发送给从节点。基于逻辑日志进行传输。 这种方式将复制的日志和具体的存储引擎解耦。传输的大概是执行命令后的值感觉和第一种方式中主节点对待非确定数据那样。在关系数据库中它的逻辑日志一般是描述数据表行级别的写请求。基于应用层的复制。上述几种方式都是数据库来底层实现的。还有一种方式是应用层自己来决定复制哪些数据复制到哪个地方。这种方式利用数据库提供的接口触发器或者存储过程等来注入应用层面的执行逻辑。 当然还有一种更高层、更灵活的的方式应用层接收到请求后自己对不同的数据库地址进行写入比如说双写等。
2.4 举个例子
2.4.1 Redis
对于redis来说其复制是是通过同步和命令传播两个过程实现的。前者是传递一个RDB快照类似于上述的第3种方式而后者是通过传递命令也就是复制执行语句来实现的。如上所述在命令传播时redis也会遇到非确定命令的情况redis 如何处理的呢我从网上没查到具体的资料但是chatGPT告诉我非确定函数的结果是在主节点确定之后再传播给从节点的。 需要注意的是如果是在一个lua脚本中使用了非确定函数我试验过对于redis4.0版本中要打开script effects replication开启单命令复制模式模式否则会报错而redis5.0版本中lua脚本的默认模式就是script effects replication。详情请参见。所以为了更高的兼容性建议不要在lua脚本中执行非确定性函数如获取time()等尤其是在使用分布式redis的情况下。
2.4.2 Mysql
Mysql主从复制主要是采用基于语句的复制和基于行的复制。 前者是前面所述的复制执行语句的方式。这种方式简单紧凑但是有一些缺陷和限制如对于非确定性操作的限制、有些存储过程和触发器在使用这种复制方式时会有问题还有些存储引擎不支持这种方式。 还有一种方式是基于行的复制这相当于前面所述的第3种基于逻辑日志的复制方式。这种方式会将实际的复制数据保存在日志中最大的好处就是避免了非确定操作的问题可以正确的复制每一行。
2.4.3 Mongo
前面说到mongo的复制过程也分为两个阶段。第一个同步阶段复制目前系统已有的数据。mongo提供了两种方式
通过scan and insert 的方式这算是属于上面说的基于应用层的复制使用数据库本身提供的的api接口来进行复制。使用File Copy Based的方式这种方式大概类似于上面说的 基于WAL预写日志进行传输属于比较底层的复制方式。 第二个阶段的增量同步使用的是oplog操作日志。
如下图所示是一条解析出来的oplog日志。
简要解释下上述日志格式Oplog 的日志由 key value 组成。主要字段如下所示
ts 的值 表示该日志的时间戳
op 的值 i 表示 insert u 表示 update, d 表示 delete c 表示的是 db cmd, db 表示声明当前数据库 (其中ns 被设置成为数据库名称 .) n 表示 noop,,即空操作其会定期执行以确保时效性
ns 的值 表示操作所在的数据库和集合。
ui 的值 表示当前登录用户的会话 id 值。
wall 的值: 表示该操作的执行时间utc时间。
o 的值 表示操作的内容如果是插入就会将插入的数据放到该位置。如过时更新则是设置的值如上图所示是在pvtcim.c2c_msg489的collection中更新unique_key的值。这其实就是和redis的同步过程类似通过传递客户端的写入日志来达到同步数据的目的。
三、复制所带来的一些问题
确切的说这里说的是副本机制所带来的一些问题。单个节点的数据库系统独立行事。但是采用了副本机制之后相当于各个副本之间有了一定的联系这个时候就会有了一些问题。
3.1 节点故障和切换 节点故障与恢复是属于高可用性的问题对于主从复制系统来说可以分为从节点故障和主节点故障。从节点故障失效比较简单重启从节点或者建立新的从节点让其按照上面的复制方式同步主节点的数据即可。
但是如果主节点发生了故障问题就复杂些因为我们需要切换新的主节点而且要保证新的主节点上已有的数据尽量是最新的。这个过程简要来说一般包括如下几个步骤
确认旧主节点A失效。这一般通过超时机制来完成。长时间不联系我就认为你挂了选举指定新的主节点B。 这主要是使用协调节点或者各个节点间的共识方式来选举。 我们一般会使B副本的数据尽可能的新。大家共同选举一个新的leader有一个标准就是新的leader对整个业务线最熟悉系统配置使新主节点B生效。告诉系统其他所有的人旧的leader已经下岗了以后新的leader是B有事情要先找B
这种涉及到主节点的切换影响的范围比较广在切换新的主节点过程中可能会出现一些棘手的问题。比如说
如果采用了异步复制的方式当A中的数据并未完全同步至B节点A挂了之后B选举为新节点那么可能存在一定丢数据的可能在客户端看来像是发生了数据的rollback。有些情况下丢数据是不可容忍的可能会造成系统问题。有些故障情况可能会出现“脑裂”整个系统出现了两个或多个自认为是主节点的情况那么系统可能会出现各种莫名其妙的问题。比如说Pold继续喝Pnew都向外提供服务最终的数据可能会错乱。这造成的影响比较大因此要尽量避免脑裂这个问题。还有上面提到的通过超时机制来判断节点失效取长了可能主节点出现故障了系统不可用的时间就长取短了可能会发生误判造成不必要的主从节点切换。
东西有点多是吧 还好上述选举过程中出现的问题大多数分布式数据库通过选举协议都帮我处理好了。
3.2 来点栗子
3.2.1 Redis 对于redis来说节点之间是通过定时的ping-pong来判断对方是否存活的。当主节点A发送给另一个主节点B的ping消息没有在规定的时间内收到回复时A则把B的状态认为是“疑似下线”当半数以上的主节点都认为B是“疑似下线” 则整个集群将B置为下线状态。然后通过广播将B下线的消息传给集群中其他节点。
当主节点B对应的副本节点获取到B下线的消息之后各个副本节点会通过Raft共识算法选举一个新的主节点代替B. 以此来完成故障的切换。
3.2.2 Mysql
默认的mysql主从架构不支持自动的故障切换与恢复主从复制机制只给故障切换提供了一个基础。当mysql主节点挂了之后需要手动进行故障切换。当然也有一些监控mysql主从节点的管理程序和中间件如MMM(Master-Master replication manager for MySQL)、Master High AvailabilityMaster High Availability可以提供故障自动切换功能。
3.2.3 Mongo
对于mongo从大的方面来说它的Failover 过程和其他复制系统来说是很类似的。节点之间也是通过心跳协议来判断存活的状态当超过了某个设置的阈值之后则会将某个节点判断为unavailable。
如果从节点失效, 只要整个复制集群的有效节点数目大于一半则可以正常进行读写。否则整个系统进入不可用状态。 当节点从失效状态恢复之后可以重新加入集群成为正常的副本节点。
如果主节点失效 则会立即发起投票选举出新的主节点。毕竟当家的不在需要另选一个当家人。 在MongoDB r3.2.0以前选举协议是基于Bully算法从r3.2.0开始默认使用基于Raft算法的选举策略。 具体的算法协议这里就不赘述了。 从小的方面来说mongo在这个过程中提供了许多灵活的配置。比如说
判断阶段失效的时间哪些节点参与投票哪些节点不参与哪些节点的权限更重更容易被选做主节点…
由于mongo是采用类似某种半同步的复制方式因此当primary节点发生故障准备进行切换的时候mongo的一些机制可以防止或者说降低数据丢失带来的影响这个过程中的数据丢失由于新的primary节点未同步到所有数据而造成的数据丢失。比如说
在写入操作时时候配置writeConcern 为majority,这样写操作之后同步到大多数节点才会返回给客户端切换的新的primary节点一定具有最新的数据如果切换的新primary节点还未同步原来primary的所有数据比如说未采用writeConcern为majority从客户端看来好像是数据发生了rollback“怎么新写入的数据不见了”, mongo有一种机制可以将rollback 的数据持久化到文件中。这样让用户来判断是否手动恢复这些rollback的数据。
3.2 复制滞后问题
由于复制系统中的从节点需要一定的时间从主节点同步最新的数据在这段时间间隔内如果发生了数据读写可能会出现一些意想不到的情况。 这些意想不到的事儿主要两种一种是复制过程本身的问题比如说复制超时 对于mongo这种不是完全异步复制的系统来说如果客户端发送写入命令却接收到返回error, 并不代表此次操作完全失败有可能primary在复制到其他节点的时候延时比较高导致整个操作超时超过了用户配置的时间最终返回给客户端失败的信息。客户的写入操作有可能会在接下来的时间内顺利完成因此客户端在写入时要考虑到这种情况。
这可能需要上层的业务逻辑多加注意问题还不是很大。
另外一种就是数据的一致性问题。这里以客户端为视角讨论几个常见的数据一致性问题。
3.2.1 读自己的写Read own writes
对于主从复制系统来说我们知道不同的客户端有可能在读写时出现不一致的状况。对于同一个客户端呢 答案是也会出现略显迷惑的不一致。比如说客户端A写入的时候写到了主节点M但是读取的时候是从 从节点S中读取的这个过程中S还没有同步到A写入的数据就会出现迷惑行为“我刚才明明写成功了怎么刷新一下就没了” 当然过一会A再刷新一般就会出现新的数据。
所谓的读写一致性就是对于单个客户端来说要至少保证它能读到自己刚才写入的数据其他人写入的数据可能会有延时。这种不一致对大部分业务场景可能没啥问题顶多就是多刷新几次。但是对于某些苛刻的场景来说“我刚存入的500块钱一刷新我去没了。我就很恼火”是需要保证的。
可以考虑使用下面的方案来达到读写一致性
对于某些要求读写一致性的场景直接从主节点读取。这样读到的数据就一定是新的。客户端请求的时候携带上一次更新的时间戳或者可以记录先后顺序的其他数据服务端在接收到请求时判断上一次更新的时间戳与当前时间是否过小如果比较小的话比如说一分钟之内都把请求路由到主节点中去。如果操作的数据库是持久性数据库如mysql、mongo等在写入主节点之后返回结果之前可以向redis等缓存数据库中写入一份数据一般比异步复制要快查询时先从redis中查这样一般可以读取到最新的数据。当redis中的数据过期之后master节点中的数据一般也已经同步到slave节点了。
3.2.5 读后写Writes follow reads
读后写指的是客户端读到版本n数据后可能是其他客户端写入的随后的写操作必须要在版本号大于等于n的副本上执行。
怎么理解这句话呢简单来说就是一个写入操作是根据先前的读取结果来完成的不同的结果可能会执行不同的操作。用程序代码来表示如下
d read();
if d condition{write1()
}else{write2()
}举个例子去银行账户里取钱只有银行账户的余额balance0 read操作 才可以取出money来write。所以这个操作要保证上面的读后写一致性。 比如说上图所示假设账户余额D1初始值是0Client1充值100块Write1: D1100。 过年了Client2想要提取100元 买年货。 他查看账户发现有余额从Slave1中Read1:D1 100所以执行了提取操作操作W2: D1 D1-100。但是对于Slave2来说W2的写入请求先到达如果没有其他措施的话W2的请求先执行就会有余款D1为负的尴尬情况 (W2:D1 0-100)。
3.2.2 单调读Monotonic reads
还有一种有意思的现象发生在客户端多次读取的场景。 假设主节点有两次或者多次的写入操作比如说第一次写入了Write1(T t1), 第二次又写入了Write2(Tt2); 然后客户端A在读取的时候可能从不同的副本先读到了Tt2时刻写入的数据然后又读到了Tt1时刻写入的数据, 疑惑再次袭来“好好的D1怎么变了呢是莫名其妙的消失了” 上述这种先读到旧数据再读到新数据的状况就是单调读不一致。 针对这种状况要保证的一致性就是单调读一致性也就是说要保证客户端读取的数据不会发生“回滚”。
从上面的描述和图可以看出发生这种“回滚”最主要的原因就是客户端的请求被路由到了不同的副本节点所以最简单也是最常用的一种方式就是把客户端的请求路由到同一个副本节点当然这需要将客户端的请求以某种方式进行标识。
3.2.4 单调写Monotonic writes
单调写指的是对于同一个客户端的两个不同写操作在所有副本上都以他们到达存储系统的相同的顺序执行。如下图所示就不是一个单调写的复制系统。对于副本Slave2来说Write2操作的结果在Write1之前到达如果Slave2闭着眼去apply接收到的数据就会发送单调写不一致的情况。 一致性问题在分布式系统中是个大问题涉及到的内容也相当的多。上述的几种一致性主要是主要是从客户端的角度来观察的因此也叫做以客户端中心Client-centric 一致性模型。除此之外还有以数据为中心Data-centric的一致性模型。基本的一致性模型有如下图所示。 这里就暂且不论述了以后有机会可以单独做一篇总结。
3.3 来点栗子
3.3.1 Redis
对于Redis这种缓存系统来说其为了更高的性能对数据一致性没做怎么处理Redis作为缓存的定位也不需要它对一致性做更高的保证谁会把需要重要的数据需要保持一致性的数据放在Redis中呢 所以它保证的只能算是个基本的最终一致性。
3.3.2 Mysql
简单的主从架构的mysql它提供的基本上就是一个可以从主节点同步数据至从节点的复制机制。同步复制、故障切换等功能需要使用其他的模式或者外部的工具。对于它的一致性不能奢求太多上面讨论的一致性问题mysql的主从架构都存在。如果需要响应程度的一致性保证就要靠上层应用自己来实现了。
3.3.3 Mongo
对于Mongo来说它利用可调一致性中的内容ReadConcern 、WriteConcern和客户端的Causal Consistency Session维护 Server 端返回的一些操作执行的元信息主要是关于操作定序的信息提供了一套因果一致性 Causal Consistency机制。 通过调节ReadConcern和WriteConcern来保证上述不同级别的一致性问题。如下
后记
当有了自动化的复制机制各个副本节点组成一个副本集群来共同维护整个系统的数据这提高了数据库系统的性能读性能和可用性。同时由于副本之间建立了联系也就有了一定的牵绊维护副本间的数据同步和故障时的切换成为了复制系统中两个重要的问题。 对于上层应用来说使用副本机制的数据库可以提高整体的性能但是也同时带来了一致性问题如果下层的数据系统搞不定就需要上层的应用多做琢磨了。 参考
《DDIA》《高性能Mysql》《Redis的设计与实现》Modify Execution of CRUD OperationsReplica Set Data Synchronization分布式系统开发实战数据一致性以客户为中心的一致性模型分布式系统中的一致性模型以及事务MongoDB 一致性模型设计与实现MongoDB · 内核特性 · 一致性模型设计与实现Session Guarantees for Weakly Consistent Replicated Data分布式系统中的一致性模型Consistency model分布式相关技术 《DDIA读书笔记》