精华内容
下载资源
问答
  • 随着微服务的越来越多,一致性问题也越来越被重视。纠结是怎样才能ACID呢?CAP还是Base呢?其实强一致性的方案也特别多,比如net的msdtc、java的atomikos...等。但他们这类基于2pc(两阶段提交协议)实现,基本上性能...

    随着微服务的越来越多,一致性问题也越来越被重视。纠结是怎样才能ACID呢?CAP还是Base呢?其实强一致性的方案也特别多,比如net的msdtc、java的atomikos...等。但他们这类基于2pc(两阶段提交协议)实现,基本上性能太差,根本不适合高并发的系统。而本地消息表、可靠消息最终一致性方案、最大努力通知方案都是不错的解决方案。

    目录

    一致性问题

    解决一致性问题的模式和思路

    ACID

    CAP

    BASE

    分布式一致性协议

    两阶段提交协议

    三阶段提交协议

    TCC

    最终一致性的解决方案

    1.查询模式

    2.补偿模式

    3.异步确保模式

    4. 定期校对模式

    5.可靠消息模式

    1.本地消息

    2. 可靠事务消息事务

    3.消息处理器的幂等性


    一致性问题

    1. 下订单和扣库存,即下订单和扣库存如何保持一致。如果先下订单,扣库存失败,那么将会导致超卖;如果下订单不成功,扣库存成功,那么会导致少卖。这两种情况都会导致运营成本增加,在严重情况下需要赔付。
    2. 同步调用超时,系统A 同步调用系统B 超时,系统A 可以明确得到超时反馈,但是无法确定系统B 是否已经完成了预设的功能
    3. 异步回调超时,和上一个同步超时的案例类似
    4. 掉单,如果一个系统中存在一个请求(通常指订单),另外一个系统不存在,则会导致掉单
    5. 系统间状态不一致,不同的是两个系统间都存在请求,但是请求的状态不一致
    6. 缓存和数据库不一致,服务于交易的数据库难以抗住大规模的读流量,通常需要在数据库前增加一层缓存,那么缓存和数据库之间的数据如何保持一致性?是要保持强一致性还是弱一致性呢?
    7. 本地缓存节点间不一致,本地缓存的有些数据是静态的、不变的,就永远不会有问题,但是如果经常被更新的,则被更新时各个节点的更新是有先后顺序的,在更新的瞬间,在某个时间窗口内各个节点的数据是不一致的

    解决一致性问题的模式和思路

    ACID

    关系型数据库天生用于解决具有复杂事务场景的问题,完全满足ACID 的特性。

    • A: Atomicity ,原子性
    • C : Consistency , 一致性
    • I: Isolation ,隔离性
    • D: Durability ,持久性

    由于业务规则的限制,我们无法将相关数据分到同一个数据库分片,这时就需要实现最终一致性。

    CAP

    由于对系统或者数据进行了拆分,我们的系统不再是单机系统,而是分布式系统!

    • C: Consistency , 一致性。在分布式系统中的所有数据备份,在同一时刻具有同样的值,所有节点在同一时刻读取的数据都是最新的数据副本
    • A: Availability ,可用性,好的响应性能。完全的可用性指的是在任何故障模型下,服务都会在有限的时间内处理完成井进行响应
    • P: Partition tolerance ,分区容忍性。尽管网络上有部分消息丢失,但系统仍然可继续工作

    CAP 原理证明,任何分布式系统只可同时满足以上两点,无法三者兼顾。由于关系型数据库是单节点无复制的,因此不具有分区容忍性,但是具有一致性和可用性,而分布式的服务化系统都需要满足分区容忍性,那么我们必须在一致性和可用性之间进行权衡。

    BASE

    BASE 思想解决了CAP 提出的分布式系统的一致性和可用性不可兼得的问题,如果想全面地学习BASE思想!BASE 思想与ACID 原理截然不同,它满足CAP 原理,通过牺牲强一致性获得可用性,一般应用于服务化系统的应用层或者大数据处理系统中,通过达到最终一致性来尽量满足业务的绝大多数需求。

    • BA: Basically Available ,基本可用。
    • S: Soft State ,软状态,状态可以在一段时间内不同步。
    • E: Eventually Consistent ,最终一致,在一定的时间窗口内, 最终数据达成一致即可。

    有了BASE 思想作为基础,我们对复杂的分布式事务进行拆解,对其中的每个步骤都记录其状态,有问题时可以根据记录的状态来继续执行任务,达到最终一致。

    分布式一致性协议

    两阶段提交协议

    JEE 的XA 协议就是根据两阶段提交来保证事务的完整性,并实现分布式服务化的强一致性。两阶段提交协议把分布式事务分为两个阶段, 一个是准备阶段,另一个是提交阶段。准备阶段和提交阶段都是由事务管理器发起的, 为了接下来讲解方便,我们将事务管理器称为协调者, 将资源管理器称为参与者。

    • 准备阶段: 协调者向参与者发起指令,参与者评估自己的状态,如果参与者评估指令可以完成,则会写redo 或者undo 日志( Write-Ahead Log 的一种),然后锁定资源,执行操作,但是并不提交
    • 提交阶段: 如果每个参与者明确返回准备成功,则协调者向参与者发起提交指令,参与者提交事务,释放锁定的资源。如果任何一个参与者明确返回准备失败,则协调者向参与者发起中止指令(取消事务),执行undo 日志,释放锁定的资源。

    两阶段提交协议在准备阶段锁定资源,这是一个重量级的操作, 能保证强一致性!但是实现起来复杂、成本较高、不够灵活,更重要的是它有如下致命的问题。

    • 阻塞:从上面的描述来看,对于任何一次指令都必须收到明确的响应,才会继续进行下一步,否则处于阻塞状态,占用的资源被一直锁定,不会被释放。
    • 单点故障:如果协调者宕机,参与者没有协调者指挥,则会一直阻塞,尽管可以通过选举新的协调者替代原有协调者,但是如果协调者在发送一个提交指令后宕机,而提交指令仅仅被一个参与者接收,并且参与者接收后也宕机,则新上任的协调者无法处理这种情况。
    • 脑裂:协调者发送提交指令,有的参与者接收到并执行了事务,有的参与者没有接收到事务就没有执行事务,多个参与者之间是不一致的。

    上面的所有问题虽然很少发生,但都需要人工干预处理,没有自动化的解决方案,因此两阶段提交协议在正常情况下能保证系统的强一致性,但是在出现异常的情况下,当前处理的操作处于错误状态,需要管理员人工干预解决, 因此可用性不够好,这也符合CAP 协议的一致性和可用性不能兼得的原理。

    三阶段提交协议

    三阶段提交协议是两阶段提交协议的改进版本。它通过超时机制解决了阻塞的问题, 井且把两个阶段增加为以下三个阶段。

    • 询问阶段:协调者询问参与者是否可以完成指令,协调者只需要回答是或不是,而不需要做真正的操作,若超时会导致中止。
    • 准备阶段: 如果在询问阶段所有参与者都返回可以执行操作,则协调者向参与者发送预执行请求,然后参与者写redo 和undo 日志,执行操作但是不提交操作。如果在询问阶段任意参与者返回不能执行操作的结果,则协调者向参与者发送中止请求,与两阶段提交协议的准备阶段是相似的。
    • 提交阶段:如果每个参与者在准备阶段返回准备成功,则协调者向参与者发起提交指令,参与者提交事务,释放锁定的资源。如果任何参与者返回准备失败,则协调者向参与者发起中止指令(取消事务),执行undo 日志,释放锁定的资源,与两阶段提交协议的提交阶段一致。

    三阶段提交协议与两阶段提交协议主要有以下两个不同点:

    • 增加了一个询问阶段,询问阶段可以确保尽可能早地发现无法执行操作而需要中止的行为,但是它并不能发现所有这种行为,只会减少这种情况的发生。
    • 在准备阶段以后,协调者和参与者执行的任务中都增加了超时,一旦超时,则协调者和参与者都会继续提交事务,默认为成功,这也是根据概率统计超时后默认为成功的正确性最大。

    三阶段提交协议与两阶段提交协议相比,具有如上优点,但是一旦发生超时,系统仍然会发生不一致,只不过这种情况很少见,好处是至少不会阻塞和永远锁定资源。

    TCC

    两阶段及三阶段方案中都包含多个参与者、多个阶段实现一个事务,实现复杂,性能也是一个很大的问题,因此,在互联网的高并发系统中,鲜有使用两阶段提交和三阶段提交协议的场景。

    TCC 协议将一个任务拆分成Try 、Confirm 、Cancel 三个步骤,正常的流程会先执行T可,如果执行没有问题,则再执行Confirm ,如果执行过程中出了问题,则执行操作的逆操作Cancel 。从正常的流程上讲,这仍然是一个两阶段提交协议,但是在执行出现问题时有一定的自我修复能力,如果任何参与者出现了问题,则协调者通过执行操作的逆操作来Cancel 之前的操作,达到最终的一致状态。

    从时序上来说,如果遇到极端情况,则TCC 会有很多问题,例如,如果在取消时一些参与者收到指令,而另一些参与者没有收到指令,则整个系统仍然是不一致的。对于这种复杂的情况,系统首先会通过补偿的方式尝试自动修复,如果系统无法修复,则必须由人工参与解决。

    从TCC 的逻辑上看,可以说TCC 是简化版的三阶段提交协议,解决了两阶段提交协议的阻塞问题,但是没有解决极端情况下会出现不一致和脑裂的问题。然而, TCC 通过自动化补偿手段,将需要人工处理的不一致情况降到最少,也是一种非常有用的解决方案。某著名的互联网公司在内部的一些中间件上实现了TCC 模式。

    最终一致性的解决方案

    现实系统的底线是仅仅需要达到最终一致性,而不需要实现专业的、复杂的一致性协议。

    1.查询模式

    任何服务操作都需要提供一个查询接口,用来向外部输出操作执行的状态。

    2.补偿模式

    对于服务化系统中同步调用的操作,若业务操作发起方还没有收到业务操作执行方的明确返回或者调用超时,有了上面的查询模式,我们便可以对处于不正常的状态进行修正操作(要么重新执行子操作,要么取消子操作),则可以通过补偿模式。

    3.异步确保模式

    异步确保模式是补偿模式的一个典型案例,经常应用到使用方对响应时间要求不太高的场景中,通常把这类操作从主流程中摘除,充分利用离线处理能力,通过异步的方式进行处理,处理后把结果通过通知系统通知给使用方。这个方案的最大好处是能够对高并发流量进行消峰。

    最大努力通知方案也属于此类

    1. 系统 A 本地事务执行完之后,发送个消息到 MQ;
    2. 这里会有个专门消费 MQ 的最大努力通知服务,这个服务会消费 MQ 然后写入数据库中记录下来,或者是放入个内存队列也可以,接着调用系统 B 的接口;
    3. 要是系统 B 执行成功就 ok 了;要是系统 B 执行失败了,那么最大努力通知服务就定时尝试重新调用系统 B,反复 N 次,最后还是不行就放弃。

    4. 定期校对模式

    在操作主流程中的系统间执行校对操作,可以在事后异步地批量校对操作的状态,如果发现不一致的操作,则进行补偿,补偿操作与补偿模式中的补偿操作是一致的。

    定期校对模式多应用于金融系统中。金融系统由于涉及资金安全, 需要保证准确性, 所以需要多重的一致性保证机制,包括商户交易对账、系统间的一致性对账、现金对账、账务对账、手续费对账等,这些都属于定期校对模式。顺便说一下,金融系统与社交应用在技术上的本质区别为: 社交应用在于量大, 而金融系统在于数据的准确性。

    5.可靠消息模式

    对于主流程中优先级比较低的操作,大多采用异步的方式执行,也就是前面提到的异步确保模型,为了让异步操作的调用方和被调用方充分解耦。我们通常通过消息队列实现异步化。

    消息的可靠发送又分两种

    1.本地消息

    在发送消息之前将消息持久到数据库,状态标记为待发送, 然后发送消息,如果发送成功,则将消息改为发送成功。定时任务定时从数据库捞取在一定时间内未发送的消息并将消息发送。

    本地消息表其实是国外的 ebay 搞出来的这么一套思想,它主要是利用本地消息表来保障可靠保存凭证(消息)。这个方案说实话最大的问题就在于严重依赖于数据库的消息表来管理事务啥的,如果是高并发场景咋办呢?咋扩展呢?所以一般确实很少用。

     

    2. 可靠事务消息事务

    不同的是持久消息的数据库是独立的, 并不藕合在业务系统中。发送消息前,先发送一个预消息给某个第三方的消息管理器,消息管理器将其持久到数据库,并标记状态为待发送,在发送成功后,标记消息为发送成功。

    阿里的 RocketMQ 就支持消息事务,解放了本地消息的局限性。这个还是比较合适的,目前国内互联网公司大都是这么玩儿的。

    1. A 系统先发送一个 prepared 消息到 mq,如果这个 prepared 消息发送失败那么就直接取消操作别执行了;
    2. 如果这个消息发送成功过了,那么接着执行本地事务,如果成功就告诉 mq 发送确认消息,如果失败就告诉 mq 回滚消息;
    3. 如果发送了确认消息,那么此时 B 系统会接收到确认消息,然后执行本地的事务;
    4. mq 会自动定时轮询所有 prepared 消息回调你的接口,问你,这个消息是不是本地事务处理失败了,所有没发送确认的消息,是继续重试还是回滚?一般来说这里你就可以查下数据库看之前本地事务是否执行,如果回滚了,那么这里也回滚吧。这个就是避免可能本地事务执行成功了,而确认消息却发送失败了。
    5. 这个方案里,要是系统 B 的事务失败了咋办?重试咯,自动不断重试直到成功,如果实在是不行,要么就是针对重要的资金类业务进行回滚,比如 B 系统本地回滚后,想办法通知系统 A 也回滚;或者是发送报警由人工来手工回滚和补偿。
    6. 这个还是比较合适的,目前国内互联网公司大都是这么玩儿的,要不你举用 RocketMQ 支持的,要不你就自己基于类似 ActiveMQ?RabbitMQ?自己封装一套类似的逻辑出来,总之思路就是这样子的。

     

    3.消息处理器的幂等性

    • 使用数据库表的唯一键进行滤重
    • 使用分布式表对请求进行滤重。
    • 使用状态流转的方向性来滤重,通常使用数据库的行级锁来实现。
    • 根据业务的特点,操作本身就是幕等的, 例如: 删除一个资源、增加一个资源、获得一个资源等。

    在分布式系统中,保证一致性的解决方案非常多,要针对场景而定,在另一篇中将针对微服务同步 & 异步 & 超时 & 补偿 & 快速失败进行分析。

    展开全文
  • 内部一致性与相互一致性关系总结

    千次阅读 2017-05-16 20:11:14
    对内部一致性、相互一致性进行整理总结

    参考:

    • 【1】Thomas R H. A majority consensus approach to concurrency control for multiple copy databases[J]. ACM Transactions on Database Systems (TODS), 1979, 4(2): 180-209.

    在分布式系统中,一个数据有多个副本,由于存在节点间通讯的延迟,当进行一个更新操作时,不可能保证所有副本所有时间都一样,或多或少都会有不相同的的时间差。

    一个更新操作要保证副本之间的 相互一致性 和每个副本的 内部一致性 。下面就来介绍这两种一致性的联系。

    举例

    这个例子用来后边的讨论。

    数据库中有两个节点A和B,分别存储3个数据x,y,z,值都为1。

    • A:x=1,y=1,z=1
    • B:x=1,y=1,z=1
    • 内部约束:x+y+z=3

    现在有两个更新操作:

    • update1:x=-1, y=3
    • update2:y=-1, z=3

    内部一致性(ACID中的C)

    ACID中的C。

    内部一致性是一种应用程序指定的不变性。这种一致性关心一个数据库内不同数据项之间的关系不变。保证内部一致性不仅依赖应用程序而且依赖存储系统。【1】【2】关于内部一致性的定义大家的观点比较相同。

    上边的例子中,x+y+z=3就是内部一致性约束。

    如果两个update都执行了,那么有两种顺序,两个节点的数据只可能是下面两种情况:

    • update1->update2: x=-1,y=-1,z=3
    • update2->update1: x=-1,y=3,z=3

    那么每个节点的内部一致性(x+y+z=3)都会被破坏。所以至少有一个update要被拒绝,这就是并发控制要干的事了。并发控制要保证每个节点的内部一致性(通过锁机制等)。可以看到每一个update更类似一个事务,事务本身应该满足内部一致性。当多个事务并发执行时需要系统保证其隔离性来保证内部一致性。

    相互一致性(CAP中的C)

    由于这篇文章为了区别内部一致性与相互一致性。所以不过多涉及相互一致性的定义。仅把相互一致性最后需要满足的相互一致与内部一致性进行比较。

    相互一致:多个副本的值相同。如果一个系统中数据的多个副本值都相同,那么系统就处于相互一致的状态。

    以上边的例子,来说明相互一致和内部一致性的关系。如果两个节点分别接受了其中一个更新操作:

    • A:update1: x=-1,y=3,z=1
    • B:update2: x=1,y=-1,z=3

    那么两个节点的内部一致性(x+y+z=3)都没有被破坏。但是两个节点的数据不一样了,也就是不相互一致了。保证相互一致需要所有节点对并发的冲突操作做出相同的判断。

    大家有兴趣的可以关注我的公众号《数据库漫游指南》,涉及分布式系统、大数据和个人成长分享,欢迎大家一起交流进步

    这里写图片描述

    展开全文
  • 一致性哈希

    万次阅读 2019-11-08 10:13:16
    一致性哈希 通俗说活

    一、前言

    在解决分布式系统中负载均衡的问题时候可以使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡的作用。

    但是普通的余数hash(hash(比如用户id)%服务器机器数)算法伸缩性很差,当新增或者下线服务器机器时候,用户id与服务器的映射关系会大量失效。一致性hash则利用hash环对其进行了改进。

    二、一致性Hash概述

    为了能直观的理解一致性hash原理,这里结合一个简单的例子来讲解,假设有4台服务器,地址为ip1,ip2,ip3,ip4。

    • 一致性hash 是首先计算四个ip地址对应的hash值
      hash(ip1),hash(ip2),hash(ip3),hash(ip3),计算出来的hash值是0~最大正整数直接的一个值,这四个值在一致性hash环上呈现如下图:

       

       

    • hash环上顺时针从整数0开始,一直到最大正整数,我们根据四个ip计算的hash值肯定会落到这个hash环上的某一个点,至此我们把服务器的四个ip映射到了一致性hash环

    • 当用户在客户端进行请求时候,首先根据hash(用户id)计算路由规则(hash值),然后看hash值落到了hash环的那个地方,根据hash值在hash环上的位置顺时针找距离最近的ip作为路由ip.

       

      如上图可知user1,user2的请求会落到服务器ip2进行处理,User3的请求会落到服务器ip3进行处理,user4的请求会落到服务器ip4进行处理,user5,user6的请求会落到服务器ip1进行处理。

    下面考虑当ip2的服务器挂了的时候会出现什么情况?
    当ip2的服务器挂了的时候,一致性hash环大致如下图:

     

    根据顺时针规则可知user1,user2的请求会被服务器ip3进行处理,而其它用户的请求对应的处理服务器不变,也就是只有之前被ip2处理的一部分用户的映射关系被破坏了,并且其负责处理的请求被顺时针下一个节点委托处理。

    下面考虑当新增机器的时候会出现什么情况?
    当新增一个ip5的服务器后,一致性hash环大致如下图:

     

    根据顺时针规则可知之前user5的请求应该被ip5服务器处理,现在被新增的ip5服务器处理,其他用户的请求处理服务器不变,也就是新增的服务器顺时针最近的服务器的一部分请求会被新增的服务器所替代。

    三、一致性hash的特性

    • 单调性(Monotonicity),单调性是指如果已经有一些请求通过哈希分派到了相应的服务器进行处理,又有新的服务器加入到系统中时候,应保证原有的请求可以被映射到原有的或者新的服务器中去,而不会被映射到原来的其它服务器上去。 这个通过上面新增服务器ip5可以证明,新增ip5后,原来被ip1处理的user6现在还是被ip1处理,原来被ip1处理的user5现在被新增的ip5处理。

    • 分散性(Spread):分布式环境中,客户端请求时候可能不知道所有服务器的存在,可能只知道其中一部分服务器,在客户端看来他看到的部分服务器会形成一个完整的hash环。如果多个客户端都把部分服务器作为一个完整hash环,那么可能会导致,同一个用户的请求被路由到不同的服务器进行处理。这种情况显然是应该避免的,因为它不能保证同一个用户的请求落到同一个服务器。所谓分散性是指上述情况发生的严重程度。好的哈希算法应尽量避免尽量降低分散性。 一致性hash具有很低的分散性

    • 平衡性(Balance):平衡性也就是说负载均衡,是指客户端hash后的请求应该能够分散到不同的服务器上去。一致性hash可以做到每个服务器都进行处理请求,但是不能保证每个服务器处理的请求的数量大致相同,如下图

       

    服务器ip1,ip2,ip3经过hash后落到了一致性hash环上,从图中hash值分布可知ip1会负责处理大概80%的请求,而ip2和ip3则只会负责处理大概20%的请求,虽然三个机器都在处理请求,但是明显每个机器的负载不均衡,这样称为一致性hash的倾斜,虚拟节点的出现就是为了解决这个问题。

    五、虚拟节点

    当服务器节点比较少的时候会出现上节所说的一致性hash倾斜的问题,一个解决方法是多加机器,但是加机器是有成本的,那么就加虚拟节点,比如上面三个机器,每个机器引入1个虚拟节点后的一致性hash环的图如下:

     

    其中ip1-1是ip1的虚拟节点,ip2-1是ip2的虚拟节点,ip3-1是ip3的虚拟节点。
    可知当物理机器数目为M,虚拟节点为N的时候,实际hash环上节点个数为M*N。比如当客户端计算的hash值处于ip2和ip3或者处于ip2-1和ip3-1之间时候使用ip3服务器进行处理。

    六、均匀一致性hash

    上节我们使用虚拟节点后的图看起来比较均衡,但是如果生成虚拟节点的算法不够好很可能会得到下面的环:

     

    可知每个服务节点引入1个虚拟节点后,情况相比没有引入前均衡性有所改善,但是并不均衡。

    均衡的一致性hash应该是如下图:

     

    均匀一致性hash的目标是如果服务器有N台,客户端的hash值有M个,那么每个服务器应该处理大概M/N个用户的。也就是每台服务器负载尽量均衡

    七、总结

    在分布式系统中一致性hash起着不可忽略的地位,无论是分布式缓存,还是分布式Rpc框架的负载均衡策略都有所使用。

    展开全文
  • 分布式数据库的数据一致性管理是其最重要的内核技术之一,也是保证分布式数据库满足数据库最基本的ACID特性中的 “一致性”(Consistency)的保障。在分布式技术发展下,数据一致性的解决方法和技术也在不断的演进,...

    前言

    分布式数据库的数据一致性管理是其最重要的内核技术之一,也是保证分布式数据库满足数据库最基本的ACID特性中的 “一致性”(Consistency)的保障。在分布式技术发展下,数据一致性的解决方法和技术也在不断的演进,本文就以分布式数据库作为案例,介绍分布式数据库数据一致性的原理以及实际实现。

    1、数据一致性

    1.1 数据一致性是什么

    大部份使用传统关系型数据库的DBA在看到“数据一致性”时,第一反应可能都是数据在跨表事务中的数据一致性场景。但是本文介绍的“数据一致性”,指的是**“数据在多份副本中存储时,如何保障数据的一致性”**场景。

    由于在大数据领域,数据的安全不再由硬件来保证,而是通过软件手段,通过同时将数据写入到多个副本中,来确保数据的安全。数据库在同时向多个副本写入记录时,如何确保每个副本数据一致,称为“数据一致性”。

    1.2 关系型数据库如何保障数据一致性

    传统的关系型数据库对于运行环境–硬件要求都比较高,例如Oracle会建议用户使用小型机+共享存储作为数据库的运行环境,DB2 DPF也同样建议用户采用更好的服务器+高端存储来搭建数据库的运行环境。所以在数据存储安全的技术要求下,传统关系型数据库更多是依赖硬件的技术来保障数据的安全性。

    在这里插入图片描述
    因为关系型数据库的数据安全是基于硬件来保障,并且数据也不会通过同时存储多份来保障数据的安全,所以关系型数据库的用户默认认为数据存储是一致的。

    1.3 分布式存储如何保障数据一致性

    本文在讨论分布式存储时,主要指的是大数据产品中的分布式文件系统和分布式数据库,例如:SequoiaDB和HDFS。

    用户在搞明白分布式存储的数据一致性原理时,必须要先明白为什么他们就需要数据一致性,和分布式存储的数据存储与关系型数据库的数据存储又有什么区别。

    大数据技术的诞生,确确实实让系统的性能有新的突破,并且支持硬件以水平扩展的方式来获得线性增长的性能和存储。这些都是过去传统关系型数据库所无法提供的。另外,大数据技术也抛弃了运行环境必须足够好的硬性要求,而是允许用户通过批量廉价X86服务器+本地磁盘的方式搭建规模集群,从而获得比过去依赖硬件垂直扩展所提供的更强的计算能力和更多的存储空间。

    大数据技术的核心思想就是分布式,将一个大的工作任务分解成多个小任务,然后通过分布式并发操作的方式将其完成,从而提高整个系统的计算效率或者是存储能力。而在分布式环境下,由于硬件的要求降低,必然需要大数据产品提供另外一个重要的功能–数据安全

    在这里插入图片描述
    大数据产品在解决数据安全的方式上,都比较接近,简单来说,就是让一份数据通过异步或者同步的方式保存在多台机器上,从而保障数据的安全。

    分布式存储在解决数据安全的技术难点后,又引入了一个新的技术问题,就是如何保障多个副本中的数据一致性。目前SequoiaDB是使用Raft算法来保证数据在多个副本中一致性。

    2、Raft算法

    2.1 Raft算法背景

    在分布式环境下,最著名的一致性算法应该是Paxos算法,但是由于它实在过于晦涩难懂,并且实现起来极度困难,所以在2013年,Diego Ongaro、John Ousterhout两个人以易懂(Understandability)为目标设计了一套一致性算法Raft。Raft算法最大的特点在于简单易懂,并且实现起来简单

    2.2 Raft算法概述

    与Paxos不同,Raft强调的是易懂,Raft和Paxos一样只要保证n/2+1节点正常就能够提供服务。

    众所周知当问题较为复杂时可以把问题分解为几个小问题来处理,Raft也使用了分而治之的思想。Raft算法重点解决三个子问题:选举(Leader election)、日志复制(Log replication)、安全性(Safety)。

    Raft算法强化了Leader节点的功能,Follower节点的数据只能够从Leader中获取,所以Follower节点的实现就变得简单,只要负责和Leader保持通信,并且接受Leader推送的数据即可。

    2.3 Raft算法原理

    2.3.1 节点角色

    Raft算法中,对节点的状态分为3种角色,分别是Leader(领导者)、Follower(追随者)和Candidate(候选者)。

    Leader,负责处理来自客户端的请求,负责将日志同步到Follower中,并且保证与Follower之间的heartBeat联系;

    Follower,当集群刚刚启动时,所有节点均为Follower状态,它的工作主要为响应Leader的日志同步请求,响应Candidate的请求,以及把请求到Follower的事务请求转发给Leader;

    Candidate,选举Leader时负责投票,选举出来Leader后,节点将从Candidate状态变为Leader状态。

    在这里插入图片描述

    2.3.2 Terms

    在分布式环境下,“时间同步”一直都是老大难的技术难题。Raft为了解决这个问题,将时间划分为一个一个的Term(可以理解为“逻辑时间”)来处理在不同时间段里的数据一致性。

    Terms有以下原则

    • 每个Term中,至多存在一个Leader
    • 某些Term中,有可能存在由于选举失败,没有Leader的情况
    • 每个节点自己维护本地的currentTerm
    • 每个Term都是一个连续递增的编号
    • 如果Follower的Term编号比别的Follower Term编号小时,该Follower Term编号将更新Term编号,以保持与其他Follower Term编号一致

    2.3.3 选举

    Raft的选举由定时器触发,每个节点的触发时间都不相同。

    所有的节点在开始时状态都为Follower,当定时器触发选举后Term编号递增,该节点的状态由Follower转为Candidate,并且向其他节点发起RequestVote RPC请求,这时选举有3种情况可能发生:

    发起RequestVote的节点收到n/2+1(过半数)个节点的投票,该节点将从Candidate状态变为Leader状态,开始向其他节点发送HeartBeat以保持Leader的正常状态

    如果收到投票请求后,该节点发现发起投票的节点Term大于自己,则该节点状态从Candidate转为Follower,否则保持Candidate状态,并且拒绝该投票请求

    选举期间发生了超时,则Term编号递增,重新发起选举
    在这里插入图片描述

    2.3.4 日志复制

    日志复制主要的作用就是用来保证节点的数据一致性与高可用性。

    当Leader被选举出来后,所有的事务操作都必须要经过Leader处理。这些事务操作成功后,将会被按顺序写入到LOG中,每个LOG都包含一个index编号。

    Leader在LOG发生变化后,通过HeartBeat将新的LOG同步到Follower上,Follower在接收到LOG后,再向Leader发送ACK信息,当Leader接到大多数(2/n+1)Follower的ACK信息后,将该LOG设置为已提交,并且Leader将LOG追加到本地磁盘中。

    同时Leader将在下一个HeartBeat中,通知所有的Follower将该LOG存储在各自的本地磁盘中。

    2.3.5 安全性

    安全性是用于确保每个节点都是按照相同的日志序列进行执行的安全机制。

    如果当某个Follower在同步Leader的日志时失败,但是未来该Follower又可能被选举为Leader时,就有可能导致前一个Leader已经commit的日志发生覆盖,这样就导致了节点执行不同序列的日志。

    Raft的安全性就是用于保证选举出来的Leader一定包含先前已经commit LOG 的机制,主要遵循的原则如下:

    每个Term 只能选举一个Leader;

    Leader的日志完整性,则当Candidate重新选举Leader时,新的Leader必须要包含先前已经commit的LOG;

    Candidate在选举新的Leader时,使用Term来保证LOG的完整性;

    3、分布式数据库数据一致性技术实现

    以国产原厂的分布式数据库SequoiaDB为例,SequoiaDB在多副本的部署中,采用Raft算法保证数据在多副本环境中保持一致。

    SequoiaDB集群中,总共包含3中角色节点,分别是协调节点、编目节点和数据节点。由于协调节点本身不存任何数据,所以只有编目节点和数据节点存在事务操作,换言之,编目分区组和数据分区组的副本同步采用Raft算法保证数据一致性。

    在这里插入图片描述

    3.1 编目节点和数据节点的事务日志介绍

    编目节点和数据节点由于都是需要存储数据的,并且在集群部署中该,为了确保数据的安全,都是建议采用分布式的方式进行部署,所以在数据同步中,需要采用Raft算法的基本原理进行数据同步。

    编目节点和数据节点在存储数据时,共包含两大部分,一个真实的数据文件,另一个是事务日志文件。
    在这里插入图片描述
    SequoiaDB的节点事务日志,默认情况下由20个64MB(总大小为1.25GB)的文件构成。节点的事务日志主要包含一个index编号和数据操作内容,index编号保持永远递增状态。

    另外,SequoiaDB节点的事务日志不会永久保存,而是当所有的事务日志写满后,再重新从第一个文件开始进行覆盖写入。

    3.2 编目分区组的数据一致性

    由于编目分区组是保存SequoiaDB集群的元信息,数据同步要求高,所以编目分区组的数据一致性要求为强一致性,即每次向编目分区组执行事务操作时,必须要确保所有的编目节点操作成功,才计算该操作执行成功,否则该事务操作将在整个编目分区组中回退事务日志,以保证分区组内的数据一致性。

    另外,编目分区组还有一个比较重要的特性,即编目分区组必须要存在主节点才能够正常工作,如果老的主节点宕机了,编目分区组暂时没有主节点,则该编目分区组不能够对外提供任何事务操作和数据查询操作。

    3.3 数据分区组的数据一致性

    数据分区组的数据一致性默认情况下为最终一致性性,即只要求主节点执行事务操作成功即视为操作成功,主节点将在未来异步同步ReplicaLOG到从节点上。

    3.4 主从节点的事务日志同步

    SequoiaDB的主从节点是通过事务日志同步来保证数据一致性的,并且主从节点的事务日志同步是单线程完成。

    如果当主节点和从节点的LSN差距为一条记录,则主节点会主动将最新的事务日志推送给从节点。

    如果主节点和从节点的LSN差距超过一条记录,则从节点会主动向主节点请求同步事务日志,主节点收到同步请求后,会将从节点的LSN号到主节点最新的LSN号对应的事务日志打包一次性发送给从节点。

    3.5 从节点日志重放

    当从节点获取到主节点推送过来的事务日志后,就会自动解析事务日志和重放。从节点在重放事务日志时,默认情况下会以10并发来重放事务日志。

    从节点在执行并发重放日志时有条件限制,即在集合的唯一索引个数<=1的情况下,INSERT、DELETE、UPDATE、LOB WRITE、LOBUPDATE、LOB REMOVE操作可以支持并发重放事务日志。从节点在做并发重放时,是通过记录的OID进行打散并发执行,这样就可以保证对相同记录的操作不会由于并发重放导致数据不一致。

    但是用户需要注意,从节点在重放事务日志时, DROP CL操作不能够支持并发重放。

    4、SequoiaDB数据一致性应用

    目前SequoiaDB数据分区组的数据一致性是基于集合级别进行配置的。用户在使用SequoiaDB过程中,可以随时调整数据一致性的强度。

    4.1 创建集合时指定

    在一个多副本的SequoiaDB集群中,集合默认的数据一致性行级别为“最终一致性”。用户可以在创建集合时显式指定该集合的“数据一致性强度”,例如可以在SequoiaDB Shell中执行以下命令

    db.CSNAME.createCL(“CLNAME”,{ReplSize:3})

    ReplSize参数填写范围
    在这里插入图片描述

    4.2 修改已经存在的集合

    如果集合在创建时没有设置“数据一致性”ReplSize参数,用户也可以对已经存在的集合进行修改,在SequoiaDB Shell修改命令如下

    db.CSNAME.CLNAME.alter({ReplSize:3})

    ReplSize的取值范围和创建集合时一致。

    4.3 如何查看集合的ReplSize参数

    如果用户希望检查当前集合的RepliSize参数值,可以通过数据库快照进行查看,在SequoiaDB Shell查看命令如下

    db.snapshot(SDB_SNAP_CATALOG,{}, {“Name”:null, “IsMainCL”:null,“MainCLName”:null, “ReplSize”:null})
    打印信息如下

    {

    “MainCLName”:“test.main2”,

    “Name”: “foo.bar2”,

    “IsMainCL”: null,

    “ReplSize”: null

    }

    {

    “IsMainCL”: true,

    “Name”: “test.main2”,

    “MainCLName”: null,

    “ReplSize”: null

    }

    {

    “Name”: “foo.tt”,

    “ReplSize”: 3,

    “IsMainCL”: null,

    “MainCLName”: null

    }

    5、总结

    分布式的数据库,通过Raft算法来确保在分布式情况上数据的一致性,并且编目分区组和数据分区组对数据一致性要求又有所不同,编目分区组始终要求的是数据在多副本请情况下数据强一致性,而数据分区组则可以由用户在创建集合时来执行数据一致性的强度,强度越高,数据安全性越好,但是执行的效率就会相对较差,反之依然。

    目前SequoiaDB在数据一致性场景上,用户的调整空间较大,可以根据不同的业务要求来调整数据一致性的强度,以满足业务或追求性能最优,或者数据最安全的技术要求。

    展开全文
  • 分布式系统的一致性问题(汇总)

    万次阅读 2019-09-02 15:32:19
    保证分布式系统数据一致性的6种方案 问题的起源 在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性? 具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,需要...
  • 分布式一致性

    千次阅读 2016-06-10 17:41:41
    分布式一致性 分布式系统的一致性问题总是伴随数据复制而生, 数据复制技术在提高分布式系统的可用性、可靠性和性能的同时,却带来了不一致问题。 理想情况下, 多个副本应该是应用透明的, 从外界看来多...
  • 一致性Hash原理

    千次阅读 2019-03-10 20:05:14
    文章目录前言一致性Hash概述一致性hash的特性虚拟节点均匀一致性hash总结 前言 在解决分布式系统中负载均衡的问题时候可以使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并...
  • 分布式环境Raft一致性共识算法解读

    万次阅读 2018-06-03 16:16:32
    Raft是分布式环境下的一致性算法,它通过少数服从多数的选举来维持集群内数据的一致性。它与RBFT算法名称有点像,然而Raft算法里不能存在拜占庭节点,而RBFT则能容忍BFT节点的存在。Raft非常类似于paxos协议(参见我...
  • 一致性协议总览

    千次阅读 2018-03-23 20:36:09
    一致性模型 一致性模型本质上是进程与数据存储的约定,主要是用于解决分布式系统中数据复制时保持一致性的问题 一致性协议 一致性模型就像是接口,而一致性协议就像是接口的具体实现
  • KAPPA一致性

    千次阅读 2017-03-14 10:05:07
    Kappa检测用于测量两次判断的一致性,即两个判断的结果是否相似。 具体如下图(图片取自http://blog.sina.com.cn/s/blog_4aa4593d0100rwjd.html) 表格类似于一个混淆矩阵,第一行第一个数‘4’表示R1和R2都判断为...
  • 数据库的事务必须满足4个特性:原子性, 一致性, 隔离性, 持久性,它们英文单词首字母合起来就是:ACID 在这些事务特性中,数据“一致性”为最终目标,其他特性都是为达到这个目标而采取的措施和手段。数据库...
  • USB一致性测试-USB2.0测试

    千次阅读 2019-11-26 21:26:00
    USB一致性测试-USB2.0测试 泰克 USB Tx 和 Rx 软件解决方案可满足负责设计基于 USB 3.1 C 型、USB 3.1 和 USB 2.0 的系统(符合 USB-IF 测试标准)的工程师的电气验证、一致性、检定和调试需求。 也是解决 USB-PD ...
  • 分布式系统中一致性问题

    千次阅读 2018-10-20 15:28:11
    区块链系统,首先是一个分布式系统,一致性问题是分布式领域最为基础也是最重要的问题。 1、定义 一致性( consistency ),是指对于分布式系统中的多个服务节点,给定一系列操作,在约定协议的保障下,试图使得...
  • 一致性Hash(Consistent Hashing)原理剖析及Java实现

    万次阅读 多人点赞 2018-08-10 18:04:09
    目录 一、一致性Hash(Consistent Hashing...一致性哈希算法解决了普通余数Hash算法伸缩性差的问题,可以保证在上线、下线服务器的情况下尽量有多的请求命中原来路由到的服务器。 在业务开发中,我们常把数据持久化...
  • 分布式事务一致性

    千次阅读 2018-05-25 17:18:45
    有人的地方,就有江湖有江湖的地方,就有纷争问题的起源在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性? 具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,...
  • 深入浅出一致性Hash原理

    千次阅读 2018-04-22 12:37:39
    一、前言 在解决分布式系统中负载均衡的问题时候可以使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡的作用。...二、一致性...
  • kappa一致性检验

    千次阅读 2019-09-16 06:56:29
    Kappa检测用于测量两次判断的一致性,即两个判断的结果是否相似。 具体如下图(图片取自http://blog.sina.com.cn/s/blog_4aa4593d0100rwjd.html) 表格类似于一个混淆矩阵,第一行第一个数‘4’表示R1和R2都判断为...
  • 一致性指数

    万次阅读 2017-11-12 09:38:52
    C-index,英文名全称concordance index,中文里有人翻译成一致性指数,最早是由范德堡大学(Vanderbilt University)生物统计教教授Frank E Harrell Jr 1996年提出,主要用于计算生存分析中的COX模型预测值与真实...
  • 对于数据库来说,关系型数据库对于保证数据完整性和一致性方面表现是最好的! 数据的完整性 完整性分类 具体描述 如何保证 实体完整性 每个实体都是独一无二的 主键 / 唯一索引(唯一约束) 参照完整性...
  • redis数据一致性之延时双删详解

    千次阅读 2021-02-02 12:11:44
    在使用redis时,需要保持redis和数据库数据的一致性,最流行的解决方案之一就是延时双删策略,今天我们就来详细刨析一下 注意:要知道经常修改的数据表不适合使用redis,因为双删策略执行的结果是把redis中保存的那...
  • session一致性的解决方案

    千次阅读 2019-05-22 07:57:58
    什么是session? 服务器为每个用户创建一个会话,存储用户的相关信息,以便多次请求能够定位到同一个上下文,这个相关信息就是session。...什么是session一致性问题? 假设用户包含登录信息的sessio...
  • 如何保证分布式系统数据一致性

    万次阅读 2018-12-24 10:26:05
    面试的时候,有面试官问到:选取你比较熟悉的项目,谈谈如何在做容灾负载的时候数据一致性问题,具体点比如你里面的派单,如何保证一个司机不在同一时间内接到两个订单,然后保证实时性?  一般的解决方案是在派单...
  • redis系列之——一致性hash算法

    千次阅读 2020-07-13 23:28:05
    一致性hash算法你了解吗?什么时候使用?解决什么问题?redis集群模式使用了一致性hash算法了吗? 数据分片(sharding) 分布式数据存储时,经常要考虑数据分片,避免将大量的数据放在单表或单库中,造成查询等操作...
  • 一致性哈希算法与Java实现

    万次阅读 多人点赞 2016-10-09 16:07:05
    一致性哈希算法与Java实现 ======================================================== 一致性哈希算法是分布式系统中常用的算法。比如,一个分布式的存储系统,要将数据存储到具体的节点上, 如果采用普通的...
  • zookeeper是强一致性的吗

    千次阅读 2020-10-07 16:08:44
    前端时间面试,面试官问我一个问题,听说你看过zookeeper源码,那你能告诉我zookeeper是不是强一致性的,如果是,又怎么保证数据强一致性的吗? 针对这个问题,我从下面几个角度进行了分析和解答。 什么是一致性 ...
  • 细说分布式下的数据一致性

    万次阅读 2018-08-29 11:21:47
    细说分布式下的数据一致性 名词解释 强一致性 最终一致性 XA事物 JDBC事物、JTA事物 TCC 产生场景 单一数据库、单一系统无法支撑业务和数据的增长而出现拆分化的演进,数据存储于不同的事物管理单元但又要...
  • MQ消息最终一致性解决方案

    千次阅读 2019-09-30 10:00:21
    多个服务之间使用自己单独维护的数据库,它们彼此之间不在同一个事务中,假如A执行成功了,B执行却失败了,而A的事务此时已经提交,无法回滚,那么最终就会导致两边数据不一致性的问题;尽管很早之前就有基于两阶段...
  • hash和一致性hash

    千次阅读 2019-07-25 09:19:45
    hash;简单的hash取余 优点: 计算简单,快速定位 缺点: 容错和扩展,任何的增加机器或减少...一致性hash:hash环 想象一个环,共有2^(32-1) 个节点,如果有五台机器缓存,那么就将这五台的ip分别hash后对2^(32...
  • 分布式事务的一致性

    千次阅读 2018-07-25 20:27:44
    今天在看书的时候,看到了分布式事务的一致性问题,就赶紧记下来。 一、分布式事务介绍 在我们平时写的代码中,我们可以用一个事务包含许多个SQL调用,如果某一个数据库操作发生异常,就可以将之前的SQL操纵全部...
  • 相位一致性——利用频域检测边缘

    万次阅读 2014-10-20 21:22:29
    一、相位一致性提出的背景 二、xiangwe

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 255,551
精华内容 102,220
关键字:

一致性差