我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:2019年全年资料内部公开36码 > 强一致性 >

数据一致性-分区可用性-性能——多副本强同步数据库系统实现之我

归档日期:08-15       文本归类:强一致性      文章编辑:爱尚语录

  最近,@阿里正祥(阳老师)发了上面的一条微博,谁知一石激起千层浪,国内各路数据库领域的朋友在此条微博上发散出无数新的话题,争吵有之,激辩有之,抨击有之,不一而足。总体来说,大家重点关注其中的一点:

  在不使用共享存储的情况下,传统RDBMS(例如:Oracle/MySQL/PostgreSQL等),能否做到在主库出问题时的数据零丢失。

  这个话题被引爆之后,我们团队内部也经过了激烈的辩论,多方各执一词。辩论的过程中,差点就重现了乌克兰议会时场景…

  这篇博客文章接下来的部分,将跳出任何一种数据库,从原理的角度上来分析下面的几个问题:

  答:我的答案,是No。哪怕不用共享存储,任何数据库,也都可以做到主备数据的强一致。Oracle如此,MySQL如此,PostgreSQL如此,OceanBase也如此。

  如何实现主备强一致?大家都知道数据库中最重要的一个技术:WAL(Write-Ahead-Logging)。更新操作写日志(Oracle Redo Log,MySQL Binlog等),事务提交时,保证将事务产生的日志先刷到磁盘上,保证整个事务的更新操作数据不丢失。那实现数据库主备数据强一致的方法也很简单:

  上图所示,由于事务提交操作返回给应用时,事务产生的日志在主备两个数据库上都已经存在了,强同步。因此,此时主库Crash的话,备库提供服务,其数据与主库是一致的,没有任何事务的数据丢失问题。主备数据强一致实现。用过Oracle的朋友,应该都知道Oracle的Data Guard,可工作在最大性能,最大可用,最大保护三种模式下,其中第三种 最大保护 模式,采用的就是上图中的基本思路。

  实现数据的强同步实现之后,接下来到了考虑可用性问题。现在已经有主备两个数据完全一致的数据库,备库存在的主要意义,就是在主库出故障时,能够接管应用的请求,确保整个数据库能够持续的提供服务:主库Crash,备库提升为主库,对外提供服务。此时,又涉及到一个决策的问题,主备切换这个操作谁来做?人当然可以做,接收到主库崩溃的报警,手动将备库切换为主库。但是,手动的效率是低下的,更别提数据库可能会随时崩溃,全部让人来处理,也不够厚道。一个HA(High Availability)检测工具应运而生:HA工具一般部署在第三台服务器上,同时连接主备,当其检测到主库无法连接,就切换备库,很简单的处理逻辑,如下图所示:

  HA软件与主备同时连接,并且有定时的心跳检测。主库Crash后,HA探测到,发起一个将备库提升为主库的操作(修改备库的VIP或者是DNS,可能还需要将备库激活等一系列操作),新的主库提供对外服务。此时,由于主备的数据是通过日志强同步的,因此并没有数据丢失,数据一致性得到了保障。

  有了基于日志的数据强同步,有了主备自动切换的HA软件,是不是就一切万事大吉了?我很想说是,确实这个架构已经能够解决90%以上的问题,但是这个架构在某些情况下,也埋下了几个比较大的问题。

  首先,一个一目了然的问题,主库Crash,备库提升为主库之后,此时的数据库是一个单点,原主库重启的这段时间,单点问题一直存在。如果这个时候,新的存储再次Crash,整个系统就处于不可用状态。此问题,可以通过增加更多副本,更多备库的方式解决,例如3副本(一主两备),此处略过不表。

  其次,在主备环境下,处理主库挂的问题,算是比较简单的,决策简单:主库Crash,切换备库。但是,如果不是主库Crash,而是网络发生了一些问题,如下图所示:

  若Master与Slave之间的网络出现问题,例如:断网,网络抖动等。此时数据库应该怎么办?Master继续提供服务?Slave没有同步日志,会数据丢失。Master不提供服务?应用不可用。在Oracle中,如果设置为 最大可用 模式,则此时仍旧提供服务,允许数据不一致;如果设置为 最大保护 模式,则Master不提供服务。因此,在Oracle中,如果设置为 最大保护 模式,一般建议设置两个或以上的Slave,任何一个Slave日志同步成功,Master就继续提供服务,提供系统的可用性。

  网络问题不仅仅出现在Master和Slave之间,同样也可能出现在HA与Master,HA与Slave之间。考虑下面的这种情况:

  最后,数据库会出现问题,数据库之间的网络会出现问题,那么再考虑一层,HA软件本身也有可能出现问题。如下图所示:

  如果是HA软件本身出现了问题,怎么办?我们通过部署HA,来保证数据库系统在各种场景下的持续可用,但是HA本身的持续可用谁来保证?难道我们需要为HA做主备,然后再HA之上再做另一层HA?一层层加上去,子子孙孙无穷尽也 … …

  其实,上面提到的这些问题,其实就是经典的分布式环境下的一致性问题(Consensus),近几年比较火热的Lamport老爷子的Paxos协议,Stanford大学最近发表的Raft协议,都是为了解决这一类问题。(对Raft协议感兴趣的朋友,可以再看一篇Raft的动态演示PPT:Understandable Distributed Consensus)

  前面,我们回答了第一个问题,数据库如果不使用共享存储,能否保证主备数据的强一致?答案是肯定的:可以。但是,通过前面的分析,我们又引出了第二个问题:如何保证数据库在各种情况下的持续可用?至少前面提到的HA机制无法保证。那么是否可以引入类似于Paxos,Raft这样的分布式一致性协议,来解决上面提到的各种问题呢?

  答案是可以的,我们可以通过引入类Paxos,Raft协议,来解决上面提到的各类问题,保证整个数据库系统的持续可用。考虑仍旧是两个数据库组成的主备强一致系统,仍旧使用HA进行主备监控和切换,再回顾一下上一节新引入的两个问题:

  相对于之前的系统,可以看到这个系统的复杂性明显增高,而且不止一成。数据库仍旧是一主一备,数据强同步。但是除此之外,多了很多变化,这些变化包括:

  这些变化,能够解决上面的两个问题吗?让我们一个一个来分析。首先是:HA软件自身的可用性如何保证?

  从一台HA主机,增加到3台HA主机,正是为了解决这个问题。HA服务,本身是无状态的,3台HA主机,可以通过Paxos/Raft进行自动选主。选主的逻辑,我这里就不做赘述,不是本文的重点,想详细了解其实现的,可以参考互联网上洋洋洒洒的关于Paxos/Raft的相关文章。总之,通过部署3台HA主机,并且引入Paxos/Raft协议,HA服务的高可用可以解决。HA软件的可用性得到了保障。

  第一个问题解决,再来看第二个问题:如何识别出当前是网络故障,还是主库Crash?如何保证任何情况下,数据库有且只有一个主库提供对外服务?

  通过在数据库服务器上部署HA Client,并且引入HA Client到HA Master的租约(Lease)机制,这第二个问题同样可以得到完美的解决。所谓HA Client到HA Master的租约机制,就是说图中的数据库实例,不是永远持有主库(或者是备库)的权利。当前主库,处于主库状态的时间是有限制的,例如:10秒。每隔10秒,HA Client必须向HA Master发起一个新的租约,续租它所在的数据库的主库状态,只要保证每10秒收到一个来自HA Master同意续租的确认,当前主库一直不会被降级为备库。

  主库Crash,HA Client正常运行。这种场景下,HA Client向HA Master发送一个放弃主库租约的请求,HA Master收到请求,直接将备库提升为主库即可。原主库起来之后,作为备库运行。

  此时,由于HA Client和主库同时Crash,HA Master到HA Client间的通讯失败。这个时候,HA Master还不能立即将备库提升为主库,因为区分不出场景二和接下来的场景三(网络问题)。因此,HA Master会等待超过租约的时间(例如:12秒),如果租约时间之内仍旧没有续租的消息。那么HA Master将备库提升为主库,对外提供服务。原主库所在的主机重启之后,以备库的状态运行。

  对于HA Master来说,是区分不出场景二和场景三的。因此,HA Master会以处理场景二同样的逻辑处理场景三。等待超过租约的时间,没有收到续租的消息,提升原备库为主库。但是在提升备库之前,原主库所在的HA Client需要做额外的一点事。原主库HA Client发送给HA Master的续租请求,由于网络问题,一直没有得到响应,超过租约时间,主动将本地的主库降级为备库。如此一来,待HA Master将原备库提升为主库时,原来的主库已经被HA Client降级为备库。双主的情况被杜绝,应用不可能产生双写。

  通过以上三个场景的分析,问题二同样在这个架构下被解决了。而解决问题二的过程中,系统最多需要等待租约设定的时间,如果租约设定为10秒,那么出各种问题,数据库停服的时间最多为10秒,基本上做到了持续可用。这个停服的时间,完全取决于租约的时间设置。

  到这儿基本可以说,要实现一个持续可用(分区可用性保证),并且保证主备数据强一致的数据库系统,是完全没问题的。在现有数据库系统上做改造,也是可以的。但是,如果考虑到实际的实现,这个复杂度是非常高的。数据库的主备切换,是数据库内部实现的,此处通过HA Master来提升主库;通过HA Client来降级备库;保证数据库崩溃恢复后,恢复为备库;通过HA Client实现主库的租约机制;实现HA主机的可用性;所有的这些,在现有数据库的基础上实现,都有着相当的难度。能够看到这儿,而且有兴趣的朋友,可以针对此问题进行探讨J

  问题三:性能数据一致性,通过日志的强同步,可以解决。分区可用性,在出现任何异常情况时仍旧保证系统的持续可用,可以在数据强同步的基础上引入Paxos/Raft等分布式一致性协议来解决,虽然这个目前没有成熟的实现。接下来再让我们来看看一个很多朋友都很感兴趣的问题:如何在保证强同步的基础上,同时保证高性能?回到我们本文的第一幅图:

  为了保证数据强同步,应用发起提交事务的请求时,必须将事务日志同步到Slave,并且落盘。相对于异步写Slave,同步方式多了一次Master到Slave的网络交互,同时多了一次Slave上的磁盘sync操作。反应到应用层面,一次Commit的时间一定是增加了,具体增加了多少,要看主库到备库的网络延时和备库的磁盘性能。

  为了提高性能,第一个很简单的想法,就是部署多个Slave,只要有一个Slave的日志同步完成返回,加上本地的Master日志也已经落盘,提交操作就可以返回了。多个Slave的部署,对于消除瞬时的网络抖动,非常有效果。在Oracle的官方建议中,如果使用最大保护模式,也建议部署多个Slave,来最大限度的消除网络抖动带来的影响。如果部署两个Slave,新的部署架构图如下所示:

  新增一个Slave,数据三副本。两个Slave,只要有一个Slave日志同步完成,事务就可以提交,极大地减少了某一个网络抖动造成的影响。增加了一个副本之后,还能够解决当主库Crash之后的数据安全性问题,哪怕主库Crash,仍旧有两个副本可以提供服务,不会形成单点。

  但是,在引入数据三副本之后,也新引入了一个问题:主库Crash的时候,到底选择哪一个备库作为新的主库?当然,选主的权利仍旧是HA Master来行使,但是HA Master该如何选择?这个问题的简单解决可以使用下面的几个判断标准:

  新的主库选择出来之后,第一件需要做的事,就是将新的Master和剩余的一个Slave,进行日志的同步,保证二者日志达到一致状态后,对应用提供服务。此时,三副本问题就退化为了两副本问题,三副本带来的防止网络抖动的红利消失,但是由于两副本强同步,数据的可靠性以及一致性仍旧能够得到保障。

  当然,除了这一个简单的三副本优化之外,还可以做其他更多的优化。优化的思路一般就是同步转异步处理,例如事务提交写日志操作;使用更细粒度的锁;关键路径可以采用无锁编程等。

  多副本强同步,做到极致,并不一定会导致系统的性能损失。极致应该是什么样子的?我的想法是:

  意犹未尽,给仍旧在坚持看的朋友预留一个小小的作业。考虑下面这幅图:如果用户的提交操作,在图中的第4步完成前,或者是第4步完成后第5步完成前,主库崩溃。此时,备库有最新的事务提交记录,崩溃的主库,可能有最新的提交记录(第4步完成,第5步前崩溃),也可能没有最新的记录(第4步前崩溃),系统应该如何处理?

  最后那个问题其实本质上跟主备无关。简化一下是,在单库场景下,db本地事务提交完成了,回复ack前crash,或者ack包到达前客户端已经判定超时…所以客户端只要没有收到明确成功或失败,临界事务两种状态都是可以接受的。主备环境下只需要保证系统本身一致。

  此图,相对于问题四简化了很多,数据库没有主备,只有一个单库。应用发起Commit,在数据库上执行日志落盘操作,但是在返回应用消息时失败(网络原因?超时?)。虽然架构简化了,但是问题大同小异,此时应用并不能判断出本次Commit是成功还是失败,这个状态,需要应用程序的出错处理逻辑处理。

  最后一个问题,关键是解决服务器端一致性的问题,可以让master从slave同步,也可以让slave回滚,因为客户端没有收到成功消息,所以怎么处理都行。服务器端达成一致后,客户端可以重新提交,为了实现幂等,每个transaction都分配唯一的ID;或者客户端先查询,然后根据结果再决定是否重新提交。

  如果应用程序在提交Commit操作,但是最后Catch到网络或者是超时的异常时,是怎么处理的?

  背景和介绍缓存是计算机里广泛使用的一种技术,对降低读取延迟、网络流量和服务器负载都非常有效,但也带来了一致性(Consistency)的问题。所谓一致就是客户端总能读到最新的数据,使用缓存后有可能服务...博文来自:IT_YUAN的专栏

  下面代码或格式如有错乱,请访问原文 ,或点击下面 阅读原文 即可进入在 HDFS 中,......博文来自:Hadoop技术博文

  前言分布式数据库的数据一致性管理是其最重要的内核技术之一,也是保证分布式数据库满足数据库最基本的ACID特性中的“一致性”(Consistency)的保障。在分布式技术发展下,数据一致性的解决方法和技...博文来自:巨杉数据库

  对于单机系统和集中系统是指一台或多台主计算机组成的中心节点,并数据和业务处理逻辑都集中于这个中心节点上,客户端仅仅负责数据的录入和展示。集中式系统的最大优点就是部署简单,同时不需要考虑分布式系统的协作...博文来自:CWeeYii的专栏

  在一些对数据有强一致性要求的应用中,数据库宕机导致数据丢失是我们一定要避免的情况。所以保证数据的一致性对我们而言非常重要。如何做到主从的强一致性呢?在单机数据库中为了保证事务更新操作不会丢失会使用WA...博文来自:的博客

  分布式事务相关数据一致性(状态一致性)raft协议会在几个节点之中选择一个领导,领导负责向外提供写,其他节点可以向外提供读。其它节点接受领导的命令进行相关的操作,只要半数人状态达成一致就行了。raft...博文来自:无限伟仔的专栏

  HBase在2.0.0版本之后在可用性上进行了发展,具体原理如下图所示:由上图可知,region将不再只保存在某一单独的regionserver上,而是选择其他的两个regionserver分别存储该...博文来自:进一步有一步的欢喜

  在分布式系统中,选择采用多副本方案,就要面对数据一致性问题;数据一致性主要是指在多副本的情况下,如何保证各个副本间数据的一致性。...博文来自:动静之间

  在分布式存储领域,为了增加系统的高可用性,经常将同一份数据存储多个副本,常见的做法的三备份。但是此做法也引来了数据一致性的问题。为了解决数据一致性的问题,业界常用的有CAP、ACID、BASE等理论模...博文来自:宋某人Jsong的代码世界

  数据一致性是分布式系统,特别是分布式存储系统设计实现中需要重点考虑的问题之一。根据CAP理论:在分布式数据系统中,一致性(Consistency )、可用性(Availability)、分区容忍性(P...博文来自:ArivnXu的博客

  ElasticSearch汇总请查看:ElasticSearch教程——汇总篇 一致性概念在分布式环境下,一致性指的是多个数据副本是否能保持一致的特性。在一致性的条件下,系统在执行数据更新操作之后能够...博文来自:东天里的冬天

  Ceph实现了Scrub机制,采用一种通过后台扫描的方案来解决ceph数据一致性的问题。...博文来自:土著部落

  该文章来自于阿里巴巴技术协会(ATA)精选文章。背景可用性(Availability)和一致性(Consistency)是分布式系统的基本问题,先有著名的CAP理论定义过分布式环境下二者不可兼得的关系...博文来自:yizich的专栏

  工作中用到了Consul来做服务发现,之后一段时间里,我会陆续发一些文章来讲述Consul实现原理。在前一篇文章中,我介绍了Raft算法。这篇文章会讲讲Consul是如何使用Raft算法来实现分布式一...博文来自:沈鸿斌的博客

  众所周知,zookeeper是一个开源的分布式协调服务,很多分布式的应用都是基于zookeeper来实现分布式锁,服务管理,服务发现,通知订阅等功能。那么。zookeeper自身是如何在分布式环境下实...博文来自:q的博客

  Eureka系统中有哪几种主要的模型?Eureka系统中不同模型之间是如何通信的?为什么说Eureka系统选择了CAP中的AP,为什么要这么选,Eureka系统能将一致性保证到什么程度?Eurekaw...博文来自:u011834741的专栏

  SQLServerAlwaysOn可用性组副本是允许只读的,默认情况下不可读。其中副本的可读性有几个选项:NO:不可连接到副本数据库,因此也不可读。默认设置。Read-intentonly:只有限定“...博文来自:KK 笔记:专注数据

  概述内部因素es的一致性主要有两个方面:使用lucene索引机制带来的refresh问题使用分片和复制带来的副本...博文来自:微尘的世界

  副本副本一致性是分布式系统的基本问题之一。副本问题是组通信问题,达成副本一致有很多种方式,在介绍具体算法之前,先从更高的层面上看看通信模型。客户端发起请求,最后客户端收到回复,有两种常见的模式:同步:...博文来自:低下自己的心,准备起飞了-_-

  Flink是流处理器,那么同样会涉及到一致性的3个级别,他们分别如下1、at-most-once这其实是没有正确性保障的委婉说法,故障发生后,计数可能丢失。2、at-least-once这表示计数结果...博文来自:余额不足

  构建操作简单的分布式系统,尤其是对微妙的行为,最好的一门艺术是经常收集生产环境经验。ApacheKafka的普及在很大程度上归功于它的设计和操作简单。ApacheKafka更微妙的特性之一是它的复制协...博文来自:李志涛的专栏

  今天微信群里一位网友发了一个问题:“mysql根据时间进行过滤,查询速度特别慢,需要30多秒”。然后我问她,数据库中总数据量大概是多少,她告诉我explain执......博文来自:weixin_33670713的博客

  AlwaysOn搭建成功后,主从数据库已经实现数据同步。但我们经常还需要向已经建好的AlwaysOn可用性组中添加数据库。这部分是怎样车操作的呢,今天我们来做一下。这是可用性组中原来的数据库信息。目前...博文来自:半世笙箫的博客

  在已有ALWAYSON可用性组的情况下,如何将新的副本添加进可用性组呢?前期准备工作:1.配置SQLSERVER2012服务器,配置静态IP地址。2.关闭防火墙和自动更新功能3.安装rame...博文来自:半世笙箫的博客

  分布式系统中的一致性协议之两阶段提交协议(2PC)     两阶段提交协议是很常见的解决分布式事务的方式,他可以保证分布式事务中,要么所有参与的进程都提交事务成功,要么都取消事务,这样做可以在分布式环...博文来自:chenglinhust的专栏

  最近读了GFS的论文,整理了一下其中涉及的一致性,总结在这里,个人理解,如果有不对的地方希望指出。一致性背景分布式存储系统中,不管是文件系统还是数据库,只要数据存在多个副本,都涉及一致性问题其中一致性...博文来自:乔的博客

  数据仓库之数据一致性不同阶段获取同样的指标,但是输出的数据不同,无法保持所有数据的一致性情况栗子:注册用户数:是在公司表中存在,且公司名称不为空的数据。存在问题:在一月份注册数据10条,填写公司名称的...博文来自:nima_apple的博客

  一、Kafka集群Kafka使用Zookeeper来维护集群成员(brokers)的信息。每个broker都有一个唯一标识broker.id,用于标识自己在集群中的身份,可以在配置文件server.p...博文来自:黑白影的博客

  etcd是一个分布式一致性键值存储系统,用于共享配置和服务发现,专注于:简单:良好定义的,面向用户的API(gRPC)安全:带有可选客户端证书认证的自动TLS快速:测试验证,每秒10000写入可靠:使...博文来自:象牙塔下的渣渣

  1、Kafka概览Apache下的项目Kafka(卡夫卡)是一个分布式流处理平台,它的流行是因为卡夫卡系统的设计和操作简单,能充分利用磁盘的顺序读写特性。kafka每秒钟能有百万条消息的吞吐量,因此很...博文来自:Tony_仔仔 的博客

  alwayson可用性组在主副本那边已被破坏,看不到了,但辅助副本这边还有,却删除不了可用性数据库:ALTERDATABASE[dbName]SETHADROFF;提示:消息41121,级别16,状态...博文来自:我想我是海 冬天的大海 心情随风轻摆

  1.简介大数据时代必须解决海量数据的高效存储问题,为此,谷歌开发了分布式文件系统(GoogleFileSystem,GFS),通过网络实现文件在多台机器上的分布式存储,较好地满足了大数据存储的要求.H...博文来自:Co_zy的博客

  Eureka是springcloud中的一个组件,提供注册发现功能。它是一个分布式应用,用于管理微服务地址。通过部署多个EurekaServer避免单点故障。     随着微服务的规模越来越...博文来自:wk022的专栏

  测试版本模拟场景测试结果相关建议测试版本kafka1.1.1模拟场景依次挂掉集群每一台机器,但是中间不间断发消息,然后按照挂掉的顺序依次重启测试程序采用每10s发送一批消息,在中间停顿这10s有序停止...博文来自:wuhulala的休息室

  在灾难恢复方面,目前业界公认有三个目标值得努力。一是恢复时间,企业能忍受多长时间没有IT,处于停业状态;二是网...博文来自:luke_wang的专栏

  从本文开始,笔者将花三到四篇文章的篇幅,介绍Paxos算法。包括它的理论基础、基本实现、变种实现,其它保证最终一致性的算法,等等。...博文来自:JAVA入门中

  系列一:ALWAYSON搭建:系列二:ALWAYSON实现主从切换:http:...博文来自:半世笙箫的博客

  本文分享了MySQL复制数据一致性校验和修复的详细步骤及其自动化实现思路和方法,对MySQL复制架构运维中该项工作的实施及其自动化具有较好的借鉴意义。...博文来自:hangxing_2015的博客

  网络摘抄理解:一致性:读操作总是能读取到之前完成的写操作结果,满足这个条件的系统称为强一致系统,这里的“之前”一般对同一个客户端而言;可用性:读写操作在单台机器发生故障的情况下仍然能够正常执行,而不需...博文来自:八角塘塘主的博客

  今天将数据库加入可用性组中时,添加成功,但在辅助副本中打开已添加的数据库进行查询时,报错,报错信息如下:查看其它数据库,发现已有的数据库也无法正常访问。查看数据库状态,发现该数据库并未挂起数据移动,也...博文来自:半世笙箫的博客

  如题,现在很多架构都采用了Redis+MySQL来进行存储,但是由于多方面的原因,总会导致Redis和MySQL之间出现数据的不一致性。   例如如果一个事务执行失败回滚了,但是如果采取了先写R...博文来自:此心光明,亦复何言~

  高并发场景有抢红包,双十一抢商品等。如何去处理这些高并发场景呢?1.从存储介质考虑:有内存缓存和磁盘缓存,内存缓存的速度是比磁盘缓存要高出几十倍的,因此可以考虑存储介质在内存上。想象一下如果抢红包的时...博文来自:u012345683的博客

  :这个表shedlock 里面的值是写死的吗 还是有一段代码在值行这个任务的时候会向这个表加值

本文链接:http://ravynhart.com/qiangyizhixing/495.html