文章目录

  • 单主复制、多主复制和无主复制介绍
  • 单主复制的问题与解决方案
    • 读己之写
    • 单调读
    • 一致前缀读(因果倒置)
  • 多主复制和无主复制并发写入与因果写入
    • 并发写入与因果写入
    • 因果关系倒置解决方案
    • 并发写入冲突解决方案
  • 多主复制和无主复制的问题和解决方案
    • 多主复制并发写入冲突
    • 多主复制因果写入倒置
    • 无主复制的并发写入冲突
    • 无主复制的因果写入倒置
  • 总结

单主复制、多主复制和无主复制介绍

https://vonng.gitbooks.io/ddia-cn/content/ch5.html
https://zhuanlan.zhihu.com/p/105384140
https://zhuanlan.zhihu.com/p/100166494

单主复制的问题与解决方案

基于主库的复制要求所有写入都由单个节点处理,但只读查询可以由任何副本处理。所以对于读多写少的场景(Web上的常见模式),一个有吸引力的选择是创建很多从库,并将读请求分散到所有的从库上去。这样能减小主库的负载,并允许向最近的副本发送读请求。
在这种伸缩体系结构中,只需添加更多的追随者,就可以提高只读请求的服务容量。但是,这种方法实际上只适用于异步复制——如果尝试同步复制到所有追随者,则单个节点故障或网络中断将使整个系统无法写入。而且越多的节点越有可能会被关闭,所以完全同步的配置是非常不可靠的。
不幸的是,当应用程序从异步从库读取时,如果从库落后,它可能会看到过时的信息。这会导致数据库中出现明显的不一致:同时对主库和从库执行相同的查询,可能得到不同的结果,因为并非所有的写入都反映在从库中。这种不一致只是一个暂时的状态——如果停止写入数据库并等待一段时间,从库最终会赶上并与主库保持一致。出于这个原因,这种效应被称为 最终一致性(eventually consistency)
“最终”一词故意含糊不清:总的来说,副本落后的程度是没有限制的。在正常的操作中,复制延迟(replication lag),即写入主库到反映至从库之间的延迟,可能仅仅是几分之一秒,在实践中并不显眼。但如果系统在接近极限的情况下运行,或网络中存在问题,延迟可以轻而易举地超过几秒,甚至几分钟。

因为滞后时间太长引入的不一致性会导致一些问题:

读己之写

现象:用户先提交的数据,再查询却消失不见。
原因:数据写入主库时,并没有复制到所有从库。查询时正好访问到还未复制数据的从库。
解决方案

  • 读用户可能已经修改过的内容时,都从主库读。这就要求有一些方法,不用实际查询就可以知道用户是否修改了某些东西。举个例子,社交网络上的用户个人资料信息通常只能由用户本人编辑,而不能由其他人编辑。因此一个简单的规则是:从主库读取用户自己的档案,在从库读取其他用户的档案。
  • 如果应用中的大部分内容都可能被用户编辑,那这种方法就没用了,因为大部分内容都必须从主库读取(扩容读就没效果了)。在这种情况下可以使用其他标准来决定是否从主库读取。例如可以跟踪上次更新的时间,在上次更新后的一分钟内,从主库读。还可以监控从库的复制延迟,防止对任意比主库滞后超过一分钟的从库发出查询。
  • 客户端可以记住最近一次写入的时间戳,系统需要确保从库为该用户提供任何查询时,该时间戳前的变更都已经传播到了本从库中。如果当前从库不够新,则可以从另一个从库读,或者等待从库追赶上来。
  • 如果同一个用户从多个设备请求服务,例如桌面浏览器和移动APP。这种情况下可能就需要提供跨设备的写后读一致性:1.记住用户上次更新时间戳的方法变得更加困难,因为一台设备上运行的程序不知道另一台设备上发生了什么。元数据需要一个中心存储。2. 如果副本分布在不同的数据中心,很难保证来自不同设备的连接会路由到同一数据中心。 (例如,用户的台式计算机使用家庭宽带连接,而移动设备使用蜂窝数据网络,则设备的网络路线可能完全不同)。如果你的方法需要读主库,可能首先需要把来自同一用户的请求路由到同一个数据中心。

单调读

现象:用户两次查询数据,第一次查询的结果比第二次查询的结果更新。
原因:数据写入主库时,并没有复制到所有从库。第一次查询访问已经复制数据的从库,第二次查询访问还未复制数据的从库。
解决方法:确保每个用户总是从同一个副本进行读取(不同的用户可以从不同的副本读取)。例如,可以基于用户ID的散列来选择副本,而不是随机选择副本。但是,如果该副本失败,用户的查询将需要重新路由到另一个副本。

一致前缀读(因果倒置)

现象:用户先看到果,后看到因。
原因:在分区数据库中,因先写入分区主库,但是并未复制到所有分区从库。果后写入零一分区主库,且并未复制到所有分区从库。用户监听因分区从库和果分区从库,但是由于网络原因,果分区从库先成功复制数据,因分区从库后复制数据。所以用户先看到果,后看到因。
解决方法: 这是分区(partitioned)数据库中的一个特殊问题,解决方法未确保任何因果相关的写入都写入相同的分区。此做法等价于因果写入无分区的单主复制的分布式数据库,主库的因果写入的有序性和TCP传输的有序性,会保证从库的写入也是按照因果顺序。所以对于无分区的单主复制不会出现因果倒置的问题,但是在多主复制和无主复制中都是很常见的问题,所以多主复制和无主复制要解决因果排序问题。

多主复制和无主复制并发写入与因果写入

并发写入与因果写入

如果两个操作 “同时”发生,似乎应该称为并发——但事实上,它们在字面时间上重叠与否并不重要。由于分布式系统中的时钟无法完全同步的问题,分布式系统中是很难判断两个事件是否同时发生的。
在分布式系统中,为了定义并发性,确切的时间并不重要:如果AB两个操作都意识不到对方的存在,就称这AB两个操作并发。如果B的操作建立在A的操作上,则A和B不是并发,也可以说B是因果依赖(causally dependent)于A。因此,只要有两个操作A和B,就有三种可能性:A在B之前发生,或者B在A之前发生,或者A和B并发。

比如下图中因为Client B递增的值是Client A插入的值,所以B因果依赖于A。

下图当每个客户端启动操作时,它不知道另一个客户端也正在执行操作同样的Key。因此,操作之间不存在因果关系。

因果关系倒置解决方案

版本向量(向量时钟)
https://blog.csdn.net/qq_41775852/article/details/104933728
针对数据库中同一个key的记录的具有因果关系的写入,果写入可以覆盖因写入。因为果写入建立在因写入之上,不会存在冲突问题。

并发写入冲突解决方案

不具有因果关系的写入就是并发写入。由于并发写入是针对于同一个key的记录的独立的修改,所以会引起冲突。所以需要合并冲突,一般有以下方法:

  1. 给每个写入一个唯一的ID(例如,一个时间戳,一个长的随机数,一个UUID或者一个键和值的哈希),挑选最高ID的写入作为胜利者,并丢弃其他写入。如果使用时间戳,这种技术被称为最后写入胜利(LWW, last write wins)。虽然这种方法很流行,但是会造成数据丢失。比如多个用户同时更新一个账户存款,在原有的存款上增加100,两用户并发修改导致账户本来应该增加200,却只有一个修改生效增加100(这是并发写入,因为两个修改操作基于原始数据,而不依赖对方修改后的数据)。这在单主数据库中可以使用悲观锁或者乐观锁解决,但是在多主数据库中加锁需要与所有主库通信,这就失去了多主数据库读取写入的性能优势,多主也就失去了意义(文档协同编辑是一种特殊的多主数据复制,是利用悲观锁锁住各用户编辑的单元格,因为其更强调一致性而不是高可用。)。
  2. 以某种方式将这些值合并在一起。比如:多个值连接变成一个值或者多个值均存储下来(提供给用户自行选择)或者自定义冲突解决逻辑。

合并冲突的解决方案决定了数据的并发写入的一致性保证的强弱。

多主复制和无主复制的问题和解决方案

多主复制并发写入冲突

原因:两个客户端同时独立无因果依赖的更新同一条记录,但是访问的是不同的主库。当主库把数据复制到其他主库时,发现此条记录出现冲突。
解决方案:合并冲突,如上

多主复制因果写入倒置

现象:客户端A向主库1的表中插入一行,客户端B在主库3上更新该行。然而,主库2可以以不同的顺序接收写入:它可以首先接收更新(其中,从它的角度来看,是对数据库中不存在的行的更新),并且仅在稍后接收到相应的插入(其应该在更新之前)。
解决方法:利用版本向量,捕获两个写入操作的因果性,果写入覆盖因写入。

无主复制的并发写入冲突

原因:与多主复制类似,两个客户端同时独立无因果依赖的更新同一个记录,但是访问的是不同副本(无主复制中没有主库、从库,所有的都是副本)。
解决方法:合并冲突,如上

无主复制的因果写入倒置

原因:与多主复制类似,客户端A更新副本1中的记录,副本1同步数据到副本3。客户端B读取副本3的数据,再次更新该数据。两次更新同步到副本2上时,出现因果倒置。
解决方案:版本向量,果写入覆盖因写入。

总结

对于单主复制的数据库不存在并发写入冲突以及因果写入倒置的问题,因为所有的数据写入都通过同一个leader进行排序,TCP传输也保证了数据写入按照顺序复制给所有副本。对于多主复制以及无主复制的数据库,因为数据可以通过不同的主库或者副本写入,所以或造成并发写入冲突以及因果写入倒置。并发写入冲突的解决方案是按照一定方法合并冲突,因果写入倒置的解决方案是利用版本向量为因果写入排序,果写入覆盖因写入。
数据复制还分为同步复制和异步复制,同步复制保证强一致性,但是可用性较差,异步复制保证高可用性,但是一致性较弱。最佳的多副本复制方案应该是使用Paxos/Raft,可实现较高可用性+较强一致性。

参考:《设计数据密集型应用》

分布式系统多副本复制的问题与解决方案相关推荐

  1. 分布式系统中的复制问题

    文章目录 分布式系统中的复制 主从复制 主从复制工作原理 新增从库 处理节点宕机 从库失效:追赶恢复 主库失效:故障切换 复制日志的实现 基于语句的复制 传输预写式日志(WAL) 逻辑日志复制(基于行 ...

  2. 图文了解 Kafka 的副本复制机制

    让分布式系统的操作变得简单,在某种程度上是一种艺术,通常这种实现都是从大量的实践中总结得到的.Apache Kafka 的受欢迎程度在很大程度上归功于其设计和操作简单性.随着社区添加更多功能,开发者们 ...

  3. 谈谈分布式系统中的复制

    谈谈分布式系统中的复制 数据极客  2016-04-01 23:16 复制几乎是构成分布式系统,尤其是分布式存储和分布式数据库的关键所在,那么本文就来综合谈论下复制技术. 简单说复制本身可以分为同步复 ...

  4. 更新KB915597补丁后导致“您的windows副本不是正版”的解决方案

    更新KB915597补丁后导致"您的windows副本不是正版"的解决方案 解决方法: 运行cw.exe(https://pan.lanzou.com/i05ya8h),直至提示成 ...

  5. 人工智能及其体系结构_一些复制体系结构错误及其解决方案

    人工智能及其体系结构 背景 (Background) From time to time, I've run into replication issues in inherited environm ...

  6. 主机和虚拟机复制粘贴失效的解决方案

    主机和虚拟机复制粘贴失效的解决方案 参考文章: (1)主机和虚拟机复制粘贴失效的解决方案 (2)https://www.cnblogs.com/__tudou__/p/12070052.html 备忘 ...

  7. 此 Windows 副本不是正版的解决方案

    当您的计算机右下角出现"此 Windows 副本不是正版"时,可能还伴随的有计算机背景黑屏等问题.不要害怕,这并不是什么大问题,这是由于您使用的 Windows 过期造成的,您可以 ...

  8. HDFS的写入流程及副本复制策略

    步骤补充     1.向namenode发送请求上传文件 然后在namenode里会进行检查是否存在该文件,权限问题 通过则给一个输出流对象     2.建立好pipeline管道后,客户端先把文件写 ...

  9. 分布式系统(数据复制与一致性)

    文章目录 Replication CAP Conjecture Data-centric Consistency Models Sequential Consistency Causal Consis ...

最新文章

  1. android 本地图片uri格式不一致,Android本地相册图片URI转换绝对路径
  2. JRE和JDK的区别分别代表什么
  3. C# 添加xml节点多了xmlns属性问题
  4. 第04讲: 基础探究,Session 与 Cookies
  5. 迟到的tkinter---学校选课刷屏器
  6. 工信部:2019年全国继续加大网络提速降费力度
  7. 数据库连接池php-cp介绍
  8. linux 邮件服务器 并给外网发送邮件,Linux下判断公网IP是否改变,并发送邮件通知...
  9. 很少人用的下载者方法
  10. STM32F103 用CS1237 /HX711 芯片制作电子秤
  11. Python程序员面试技巧
  12. win7计算机锁频图片怎么设置,Win7电脑锁屏壁纸怎么设置?Win7系统设置锁屏壁纸的方法...
  13. 蓝牙键盘常用快捷键记录
  14. linux命名空间(namespace)学习(一)
  15. 硬件设备的软件测试,智能设备的软硬件测试都要测什么?
  16. Classic Shell:找回 Windows 8 / Windows Server 2012 的经典的开始按钮和开始菜单
  17. Paper reading (七十九):A subset of the core rumen microbiome dictates cow productivity and emissions
  18. myeclipse2017 for Mac 破解版本
  19. 使用钉钉Api 向企业群发送文件 python
  20. 文件随机或顺序读写原理深入浅出

热门文章

  1. [论文阅读] (30)李沐老师视频学习——3.研究的艺术·讲好故事和论点
  2. 程序员们注意了,警惕JS代码复制陷阱
  3. React Native之二维码扫描
  4. 计算机如何连接网络扫描仪,Win7系统怎么连接扫描仪 win7连接扫描仪的方法
  5. 用Mathematica解两个圆柱面相贯的交线及其投影的问题
  6. AAAI2020/风格迁移:Ultrafast Photorealistic Style Transfer via Neural Architecture基于神经结构搜索的超快逼真风格转移
  7. java判断时间是否在时间区间里(适用格式HH:mm)
  8. 【Dplayer视频播放器】一款好用的视频播放器
  9. 面向对象的第三条主线:关键字
  10. 【转载】不管嫁给谁,都得过这三道关