精华内容
下载资源
问答
  • 数据一致性

    千次阅读 2018-12-13 10:52:37
    在高并发的场景里,如何保证一个业务事务的数据一致性非常重要 在高并发的业务场景中通常出现这样的现象 T1读数据B(sql1) T2读数据B(sql2) T1修改数据B(sql3)(数据库会自动对事务加上排他锁) T2修改...

    在高并发的场景里,如何保证一个业务事务的数据一致性非常重要

    在高并发的业务场景中通常出现这样的现象

    T1读数据B(sql1)

    T2读数据B(sql2)

    T1修改数据B(sql3)(数据库会自动对事务加上排他锁)

    T2修改数据B(sql4)(数据库会自动对事务加上排他锁)

    在这样的场景中通常会出现几种情况:

    1、不加锁的条件下,T2修改产生脏数据。或者当T2修改以查询的结果为条件则修改失败(分布式系统容易导致数据不一致)

    2、在数据库层面(sql1、sql2)加上共享锁时,通常容易致使sql3无法执行,由于sql1、sql2,都对统一数据加上共享锁,但是在修改时都无法对数据加上排他锁导致业务产生死锁情况,导致程序崩溃

    3、对于第二种情况的,解决方案有,在程序业务处理的过程中T1在读取数据的时候手都对数据B加上排他锁,因此程序当业务T2进入处理程序时,也会对数据B加排他锁,但是T1业务还在进行没有是否锁,T2进出便会挂起等待T1的事务进行完成,(但是在分布式的系统中由于一个业务由多服务,多数据库事务组成,无法做到对事物的统一管理)

    4、在单机的业务环境下,通常可以通过代码业务层面解决,高并发产生的数据问题。具体解决方案为对可能产生高并发的业务处理代码快加上程序锁,使其在做业务处理的时候,由多线程的业务转化成单线程的业务

     但是这种情况,仅限于再请求量处理及时的情况下才能使用,一旦有大量的请求涌进,由于单线程的业务处理无法及时,系统拥堵量过大导致系统崩溃,

    5,鉴于4的解决方案在系统处理效率的牺牲比较大不可取,于是可以采用将单线程业务,使用mq机制将所有的请求统一放入一个一队列中,使其业务在处理的时候通过mq的排队机制进行处理,当mq队列过大的时候,可以在处理mq里面的业务时,通过多线程的业务方式提高系统的效率,但对统一数据操作时需要,保证,该数据不存在正在处理的线程(存在并发风险)

    6、使用redis分布式锁,来提高单线程处理效率低下的问题,具体解决方案为。当一个业务处理进来时,程序会对业务处理的主体表数据,获取一个锁,并保存在redis中,(当redis中已存在该数据的锁时,程序会进入一个不断获取锁的机制,直至获取到锁,并获取对数据的操作权限),从而提高系统的处理效率,以及业务数据的一致性

     redis锁实现方式:

    JedisPoolConfig 继承Java通用对象池GenericObjectPool

     

     

     

     

    展开全文
  • 微服务系统中的数据一致性,你都会了吗

    万次阅读 多人点赞 2021-09-17 23:11:34
    你好,我是看山。 从单体架构到分布式架构,从巨石架构到微服务...需要注意一下,本文所设计的数据一致性,不是多数据副本之间保持数据一致性,而是系统之间的业务数据保持一致性。 本地事务 在早期的系统中,我们可.

    关于微服务系统中数据一致性的总结

    你好,我是看山。

    从单体架构到分布式架构,从巨石架构到微服务架构。系统之间的交互越来越复杂,系统间的数据交互量级也是指数级增长。作为一个系统,我们要保证逻辑的自洽和数据的自洽。

    数据自洽有两方面要求:

    1. 抛开代码,数据能够自己验证自己的准确性,也就是数据彼此之间不矛盾
    2. 所有数据准确且符合期望

    为了实现这两点,需要实现数据的一致性,为了实现一致性,就需要用到事务。

    需要注意一下,本文所设计的数据一致性,不是多数据副本之间保持数据一致性,而是系统之间的业务数据保持一致性。

    本地事务

    在早期的系统中,我们可以通过关系型数据库的事务保证数据的一致性。这种事务有四个基本要素:ACID。

    • A(Atomicity,原子性):整个事务中的所有操作,要么全部完成,要么全部失败,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
    • C(Consistency,一致性):一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。
    • I(Isolation,隔离性):隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
    • D(Durability,持久性):在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

    这四个要素是关系型数据库的根本。无论系统多么复杂,只要使用同一个关系型数据库,我们就可以借助事务保证数据一致性。基于对关系型数据库的信任,我们可以认为本地事务是可靠的,开发过程中不需要额外的工作。从架构的角度,关系型数据库也是一个单独的系统,那关系型数据库与应用之间也是形成了分布式。所以我们先研究一下这种简单的分布式系统如何实现 ACID。

    首先,A(原子性)和 D(持久性)是彼此之间密不可分的两个属性:原子性保证了事务的所有操作,要么全部完成,要么全部失败,不可能停滞在中间某个环节;持久性保证了一旦事务完成,该事务对数据库所作的更改便持久的保存在数据库之中,不会因为任何原因而导致其修改的内容被撤销或丢失。

    众所周知,数据必须写入到磁盘后才能保证持久化,仅仅保存在内存中,一旦出现系统崩溃、主机断电等情况,数据就会丢失。所以,关键是“写入磁盘”要实现原子性和持久性,然而这个动作存在中间态:正在写入。所以,现代的关系型数据库通常采用追加日志记录的方式。将修改数据所需的全部信息(包括修改什么数据、数据物理上位于哪个内存页和磁盘块中、从什么值改成什么值,等等),以顺序追加的形式记录到磁盘中。只有在日志记录全部落盘,数据库在日志中看到代表事务成功提交的“提交记录”后,才会根据日志上的信息对真正的数据进行修改。修改完成后,再在日志中加入一条“结束记录”表示事务已完成持久化,这种事务实现方法被称为“提交日志”。

    本地事务

    我们能够通过日志保证一个事务的原子性和持久性,那如果出现多个事务访问同一个资源呢?作为程序猿都知道,多个线程/进程访问同一个资源,这个资源就称为临界资源,想要解决临界资源占用冲突的方式很简单,就是加锁。关系型数据库为我们准备了三种锁:

    • 写锁(Write Lock):同一个时刻,只有有一个事务对数据加写锁,所以写锁也被称为排它锁(exclusive Lock)。数据被加了写锁后,其他事务不能写入数据,也不能对其添加读锁(注意,是不能加读锁,但是可以读取数据)。
    • 读锁(Read Lock):同一时刻,多个事务可以对数据添加读锁,所以读锁也被称为共享锁(Shared Lock)。数据库被添加读锁后,数据不能被添加写锁。
    • 范围锁(Range Lock):对一个范围的数据添加写锁,这个范围的数据不能被写入。也可以算作写锁的批量行为。

    根据这三种锁的不同组合,我们可以实现四种不同的事务隔离级别:

    • 可串行化(Serializable):写入的时候加写锁,读取的时候加读锁,范围读写的时候加范围锁。
    • 可重复度(Repeatable Read):写入的时候加写锁,读取的时候加读锁,范围读写的时候不加锁,这样会出现读取相同范围数据的时候,返回结果不同,即幻读(Phantom Read)。
    • 读已提交(Read Committed):写入的时候加写锁,读取的时候加读锁,读取完成后立马释放读锁。这样会出现同一个事务多次读取相同数据,返回结果不同,即不可重复读(Non-Repeatable Read)。
    • 读未提交(Read Uncommitted):写入的时候加写锁,读取的时候不加锁。这样就会读取到另一个还未提交的事务写入的数据,即脏读(Dirty Read)。

    全局事务

    随着系统规模不断扩大,业务量不断增加。单体应用不再满足需求,我们会拆分系统,然后拆分数据库。此时,同一个请求中,就会出现同时访问多个数据库的情况。为了解决这种情况的数据一致性问题,X/Open 组织在 1991 年(那个时候我还小)提出了一套 X/Open XA 的处理事务的架构。XA 的核心内容是定义了全局的事务管理器(Transaction Manager,用于协调全局事务)和局部的资源管理器(Resource Manager,用于驱动本地事务)之间的通信接口,在一个事务管理器和多个资源管理器(Resource Manager)之间形成通信桥梁,通过协调多个数据源的一致动作,实现全局事务的统一提交或者统一回滚。与 XA 架构配套的是两阶段提交协议(2PC,Two Phase Commitment Protocol)。在这个协议中,最关键的点就是,多个数据库的活动,均由一个事务协调器的组件来控制。具体的分为 5 个步骤:

    1. 应用程序调用事务管理器中的提交方法
    2. 事务管理器将联络事务中涉及的每个数据库,并通知它们准备提交事务(这是第一阶段的开始)
    3. 接收到准备提交事务通知后,数据库必须确保能在被要求提交事务时提交事务,或在被要求回滚事务时回滚事务。如果数据库无法准备事务,它会以一个否定响应来回应事务管理器。
    4. 事务管理器收集来自各数据库的所有响应。
    5. 在第二阶段,事务管理器将事务的结果通知给每个数据库。如果任一数据库做出否定响应,则事务管理器会将一个回滚命令发送给事务中涉及的所有数据库。如果数据库都做出肯定响应,则事务管理器会指示所有的资源管理器提交事务。一旦通知数据库提交,此后的事务就不能失败了。通过以肯定的方式响应第一阶段,每个资源管理器均已确保,如果以后通知它提交事务,则事务不会失败。

    2PC

    两阶段提交协议实现简单,但存在几个明显缺陷:

    • 单点问题:事务管理器在两段提交中具有举足轻重的作用,事务管理器等待资源管理器回复时可以有超时机制,允许资源管理器宕机,但资源管理器等待事务管理器指令时无法做超时处理。一旦宕机的不是其中某个资源管理器,而是事务管理器的话,所有资源管理器都会受到影响。如果事务管理器一直没有恢复,没有正常发送 Commit 或者 Rollback 的指令,那所有资源管理器都必须一直等待。
    • 性能问题:两段提交过程中,所有资源管理器相当于被绑定成为一个统一调度的整体,期间要经过两次远程服务调用,三次数据持久化(准备阶段写重做日志,事务管理器做状态持久化,提交阶段在日志写入 Commit Record),整个过程将持续到资源管理器集群中最慢的那一个处理操作结束为止,这决定了两段式提交的性能通常都较差。
    • 一致性风险:尽管提交阶段时间很短,但这仍是一段明确存在的危险期。如果事务管理器在发出准备指令后,根据收到各个资源管理器发回的信息确定事务状态是可以提交的,事务管理器会先持久化事务状态,并提交自己的事务,如果这时候网络断开,无法再通过网络向所有资源管理器发出 Commit 指令的话,就会导致部分数据(事务管理器的)已提交,但部分数据(资源管理器的)既未提交,也没有办法回滚,产生了数据不一致的问题。

    能够发现问题,就能够想到办法解决。我们高中老师说了,只要意识不滑坡,办法总比困难多。所以又发展出了三阶段提交协议(3PC,Three Phase Commitment Protocol),能够缓解单点问题和准备阶段的性能问题。这个协议把 2PC 中的准备阶段拆分为 CanCommit 和 PreCommit,把提交阶段改名为 DoCommit。CanCommit 是询问阶段,让每个资源管理器根据自身情况判断该事务是否有可能完成。

    3PC 本质是通过一次问询,如果大家都说自己可以,那成事的可能性很大,减少了准备阶段直接锁定资源的重操作。由于事务失败回滚概率变小的原因,在三段式提交中,如果在 PreCommit 阶段之后发生了事务管理器宕机,即资源管理器没有能等到 DoCommit 的消息的话,默认的操作策略将是提交事务而不是回滚事务或者持续等待,这就相当于避免了事务管理器单点问题的风险。

    3PC

    分布式事务

    说到分布式事务,不得不提 CAP 理论:任何分布式系统只可同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)中的两点,没法三者兼顾。

    CAP 理论

    • 一致性(Consistency):数据在任何时刻、任何分布式节点中所看到的都是符合预期的。
    • 可用性(Availability):系统不间断地提供服务的能力,可用性是由可靠性(Reliability)和可维护性(Serviceability)计算得出的比例值。可靠性通过平均无故障时间(Mean Time Between Failure,MTBF)来度量;可维护性通过平均可修复时间(Mean Time To Repair,MTTR)来度量。可用性衡量系统可以正常使用的时间与总时间之比,公式为:A=MTBF/(MTBF+MTTR)。
    • 分区容错性(Partition Tolerance):分布式环境中部分节点因网络原因而彼此失联后,系统仍能正确地提供服务的能力。

    CAP 理论定义是经过几次修改的,修改后的定义本质没有区别,只是在逻辑上更加严谨。本文为了好理解,使用了最容易让大众接收并理解的定义。

    既然 CAP 不能兼顾,那我们来看看缺少其中一环会出现什么情况:

    • 选择 CA 放弃 P:即我们认为网络可靠不会出现分区情况,这种可靠是各个节点之间不会出现网络延迟、中断等情况,显然是不成立的。
    • 选择 CP 放弃 A:这样做就是抛弃了可用性,为了保证数据一致性,一旦出现网络异常,节点之间的信息同步时间可以无限制地延长。使用 CP 组合的一般用于对数据质量要求很高的场合,也就是为了保证数据完全一致,暂时不提供服务,直到网络完全恢复,这可能持续一个不确定的时间,尤其是在系统已经表现出高延迟时或者网络故障导致失去连接时。
    • 选择 AP 放弃 C:意味着一旦发生网络分区,优先提供服务可用,放弃数据一致性。这是目前分布式系统的主流选择,因为网络本身就是链接不同区域的服务器的,网络又是不可靠的,所以 P 不能被舍弃。同时,我们实现分布式系统就是为了提高可用性,这是我们的目的,不能舍弃。

    这里需要再说明一下,我们选择 AP 放弃 C 不是放弃数据一致,而是暂时放弃强一致性(Strong Consistency),而是选择弱一致性,即最终一致性(Eventual Consistency):系统中的所有数据副本经过一段时间后,最终能够达到一致的状态。这里所说的一段时间,也要是用户可接受范围内的一段时间。

    最终一致性也有一个理论支撑:BASE 理论(不得不说,理论界的缩写真牛啊,ACID 是酸,CAP 是帽子,BASE 是碱),内容主要包括:

    • 基本可用(Basically Available):当系统在出现不可预知故障的时候,允许损失部分可用性。比如,允许响应时间增长,允许部分非关键接口降级或熔断等。
    • 软状态(Soft State):软状态也称为弱状态,和硬状态相对。是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
    • 最终一致性(Eventually Consistent):最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

    在工程实践中,最终一致性分为 5 种,这 5 种方式会结合使用,共同实现最终一致性:

    • 因果一致性(Causal consistency):如果节点 A 在更新完某个数据后通知了节点 B,那么节点 B 之后对该数据的访问和修改都是基于 A 更新后的值。于此同时,和节点 A 无因果关系的节点 C 的数据访问则没有这样的限制。
    • 读己之所写(Read your writes):节点 A 更新一个数据后,它自身总是能访问到自身更新过的最新值,而不会看到旧值。
    • 会话一致性(Session consistency):会话一致性将对系统数据的访问过程框定在了一个会话当中,系统能保证在同一个有效的会话中实现“读己之所写”的一致性,也就是说,执行更新操作之后,客户端能够在同一个会话中始终读取到该数据项的最新值。
    • 单调读一致性(Monotonic read consistency):如果一个节点从系统中读取出一个数据项的某个值后,那么系统对于该节点后续的任何数据访问都不应该返回更旧的值。
    • 单调写一致性(Monotonic write consistency):一个系统要能够保证来自同一个节点的写操作被顺序的执行。

    一致性关系模型

    有了理论之后,我们来说一下实现最终一致性的几种模式。

    可靠事件模式

    可靠事件模式属于事件驱动架构:当某个事件发生时,例如更新一个业务实体,服务会向消息代理发布一个事件。消息代理会向订阅事件的服务推送事件,当订阅这些事件的服务接收此事件时,就可以完成自己的业务,也可能会引发更多的事件发布。

    我们通过一个例子来解释一下这种模式,用户下单成功后,订单系统需要通知库存系统减库存。

    可靠事件模式

    1. 订单系统根据用户操作完成下单操作。此时会使用同一个本地事务保存订单信息和写入事件。
    2. 另外一个消息服务会轮询事件表,将状态是“进行中”的事件以消息形式发送到消息服务中。如果发送失败,因为是轮询任务,会在下一次轮询的时候再次发送。(此处有一些优化点,本例为了简化模型,不展开)
    3. 消息服务向订阅下单消息的库存服务发送下单成功消息,库存服务开始处理。此时会有这么集中情况:
      1. 库存服务扣减库存成功,消息服务接收到处理成功响应。消息服务将响应结果返回给订单服务,订单服务中事件接收器将事件修改为“已完成”。
      2. 库存服务扣减库存失败,消息服务接收到处理失败响应。此时消息服务会再次向库存服务发送消息,直到得到成功响应。如果失败次数达到阈值,可以告警通知人工介入。
      3. 消息服务给订单服务返回结果时,发生失败,订单服务没有接收到成功响应。这个时候,事件轮询逻辑会再次将事件发送给消息服务。这样,库存服务会重复收到扣减库存的消息,所以要求库存服务做好幂等。库存服务发现消息已经处理过,直接返回成功。

    这种靠着持续重试来保证可靠性的解决方案,叫做“最大努力交付”(Best-Effort Delivery),也是“可靠”两个字的来源。

    可靠事件模式还有一种更普通的形式,被称为“最大努力一次提交”(Best-Effort 1PC),指的就是将最有可能出错或最核心的业务以本地事务的方式完成后,采用不断重试的方式(不限于消息服务)来促使同一个分布式事务中的其他关联业务全部完成。找到最可能出错的方式是提前做好出错概率的先验评估,才能够知道哪块最容易出错。找到最核心的业务的方式是找到那种只要成功,其他业务必须成功的那块业务。

    这里我们再补充两个概念:

    • 业务异常:业务逻辑产生错误的情况,比如账户余额不足、商品库存不足等。
    • 技术异常:非业务逻辑产生的异常,如网络连接异常、网络超时等。

    TCC 模式

    TCC(Try-Confirm-Cancel)是一种业务侵入式较强的事务方案,要求业务处理过程必须拆分为“预留业务资源”和“确认/释放消费资源”两个子过程,由统一的服务协调调度不同业务系统的子过程。分为以下三个阶段:

    • Try:尝试执行阶段,完成所有业务可执行性的检查(保障一致性),并且预留好全部需要用到的业务资源(保障隔离性)。
    • Confirm:确认执行阶段,不进行任何业务检查,直接使用 Try 阶段准备的资源来完成业务处理。Confirm 阶段可能会重复执行,需要满足幂等性。
    • Cancel:取消执行阶段,释放 Try 阶段预留的业务资源。Cancel 阶段可能会重复执行,需要满足幂等性。

    TCC 模式

    1. 订单系统创建事务,生成事务 ID(用于作为识别请求幂等的标识),通过活动管理器记录活动日志。
    2. 进入 Try 阶段
      1. 调用账户系统,检查账户余额是否充足,如果充足,冻结需要的金额,此时账户余额是临界资源,需要通过排它锁或乐观锁保证冻结操作的安全性。
      2. 调用库存系统,检查商品库存是否充足,如果充足,锁定需要的库存,锁库操作也需要加锁保证安全
    3. 如果所有业务返回成功,记录活动日志为 Confirm,进入 Confirm 阶段:
      1. 调用账户系统,扣减冻结的金额
      2. 调用库存系统,扣减锁定的库存
    4. 第 3 步操作中如果全部完成,事务宣告结束。如果第 3 步中任何一方出现异常,都会根据活动日志中的记录,重复执行 Confirm 操作,即进行最大努力交付。所以各业务系统的 Confirm 操作需要实现幂等性。
    5. 如果第 2 步有任何一方失败(包括业务异常和技术异常),将活动日志记录为 Cancel,进入 Cancel 阶段:
      1. 调用账户系统,释放冻结的金额
      2. 调用库存系统,释放锁定的库存
    6. 第 5 步操作中如果全部完成,事务宣告失败。如果第 5 步中任何一方出现异常(包括业务异常和技术异常),都会根据活动日志中的记录,重复执行 Cacel 操作,即最大努力交付。所以各业务系统的 Cancel 操作也需要实现幂等性。

    是不是感觉 TCC 与 2PC 的很像,两者的区别在于,TCC 位于业务代码层面,属于白盒,2PC 位于基础设施层面,属于黑盒。所以 TCC 有更高的灵活性,可以根据需要,调整资源锁定的粒度。

    TCC 在业务执行过程中可以预留资源,解决了可靠事件模式的资源隔离问题。但是,TCC 还有两个明显缺点:

    1. TCC 将基础设施层的逻辑上移到业务代码,对业务有很高的侵入性,需要更高的开发成本,开发成本提升,相对应的维护成本、开发人员的素质等,都会有更高的要求。
    2. TCC 要求资源可以锁定、占用或释放,但是有的资源属于外部系统,没有办法实现锁定。

    鉴于上面的两个缺点,我们看看 SAGA 是否可以弥补。

    SAGA 模式

    SAGA 在英文中是“长篇故事、长篇记叙、一长串事件”的意思。SAGA 模式的提出远早于分布式事务概念的提出(再次对前辈大佬佩服的五体投地),它源于 1987 年普林斯顿大学的 Hector Garcia-Molina 和 Kenneth Salem 在 ACM 发表的一篇论文《SAGAS》。文中提出了一种提升“长时间事务”(Long Lived Transaction)运作效率的方法,大致思路是把一个大事务分解为可以交错运行的一系列子事务集合,后来发展成将一个分布式环境中的大事务分解为一系列本地事务的设计模式。在有的文章中,将这种模式称为业务补偿模式,SAGA 是对事务形式的描述,业务补偿是对事务行为的描述,其本质是一样的。

    SAGA 模式有两种实现:

    • 正向恢复(Forward Recovery):顺序执行各个子事务,如果遇到某个子事务执行失败,将一直重试该操作,知道成功,然后继续执行下一个子事务。比如用户下单支付成功了,就一定要扣减库存。
    • 反向恢复(Backward Recovery):顺序执行各个子事务,如果遇到某个子事务执行失败,将执行该子事务的补偿操作(避免因为技术异常造成的失败,补偿操作需要幂等),然后倒序执行已经成功的子事务的补偿操作。这种一般是可取消的批量操作,比如出行订票,需要购买飞机票、订酒店、买门票,如果买门票失败了,飞机票和酒店就可以取消了。

    SAGA 模式

    根据这两种实现,SAGA 可以分为两部分:

    • 子事务(Normal Transactions):大事务拆分若干个小事务,将整个事务 T 分解为 n 个子事务,命名为 T1、T2、…、Tn。每个子事务都应该是或者能被视为是原子行为。如果分布式事务能够正常提交,其对数据的影响(最终一致性)应与连续按顺序成功提交 Ti 等价。
    • 补偿事务(Compensating Transactions):每个子事务对应的补偿动作,命名为 C1、C2、…、Cn

    子事务与补偿动作需要满足一些条件:

    1. Ti与 Ci必须对应
    2. 补偿动作 Ci一定会执行成功,即需要实现最大努力交付。
    3. Ti与 Ci需要具备幂等性

    文末总结

    本文主要总结了本地事务、全局事务、最终一致性等方式实现数据自洽。重点介绍了实现最终一致性的集中模式:可靠事件模式、TCC 模式、SAGA 模式等。数据的一致性一直是个难题,随着微服务化之后,数据一致性更加困难,有困难不怕,只要不放弃,总会解决的。

    参考


    你好,我是看山。游于码界,戏享人生。如果文章对您有帮助,请点赞、收藏、关注。我还整理了一些精品学习资料,关注公众号「看山的小屋」,回复“资料”即可获得。

    个人主页:https://www.howardliu.cn
    个人博文:关于微服务系统中数据一致性的总结
    CSDN 主页:https://kanshan.blog.csdn.net/
    CSDN 博文:关于微服务系统中数据一致性的总结

    公众号:看山的小屋

    展开全文
  • 在分布式技术发展下,数据一致性的解决方法和技术也在不断的演进,本文就以分布式数据库作为案例,介绍分布式数据库数据一致性的原理以及实际实现。 1、数据一致性 1.1 数据一致性是什么 大部份使用传统关系型数据库...

    前言

    分布式数据库的数据一致性管理是其最重要的内核技术之一,也是保证分布式数据库满足数据库最基本的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在数据一致性场景上,用户的调整空间较大,可以根据不同的业务要求来调整数据一致性的强度,以满足业务或追求性能最优,或者数据最安全的技术要求。

    展开全文
  • 一致性的条件下,系统在执行数据更新操作之后能够从一致性状态转移到另一个一致性状态。对系统的一个数据更新成功之后,如果所有用户都能够读取到最新的值,该系统就被认为具有强一致性。分布式系统不可能同时满足...

    1. 当我们在说一致性,我们在说什么?

    在分布式环境下,一致性指的是多个数据副本是否能保持一致的特性。

    在一致性的条件下,系统在执行数据更新操作之后能够从一致性状态转移到另一个一致性状态。

    对系统的一个数据更新成功之后,如果所有用户都能够读取到最新的值,该系统就被认为具有强一致性。

    61dd9fb7d785

    分布式系统不可能同时满足一致性(C:Consistency)、可用性(A:Availability)和分区容忍性(P:Partition Tolerance),最多只能同时满足其中两项。

    2. ES 的数据一致性问题

    ES 数据并发冲突控制是基于的乐观锁和版本号的机制

    一个document第一次创建的时候,它的_version内部版本号就是1;以后,每次对这个document执行修改或者删除操作,都会对这个_version版本号自动加1;哪怕是删除,也会对这条数据的版本号加1(假删除)。

    客户端对es数据做更新的时候,如果带上了版本号,那带的版本号与es中文档的版本号一致才能修改成功,否则抛出异常。如果客户端没有带上版本号,首先会读取最新版本号才做更新尝试,这个尝试类似于CAS操作,可能需要尝试很多次才能成功。乐观锁的好处是不需要互斥锁的参与。

    es节点更新之后会向副本节点同步更新数据(同步写入),直到所有副本都更新了才返回成功。

    61dd9fb7d785

    分片向副本同步数据

    61dd9fb7d785

    es节点之间强连通

    Elasticsearch Master 节点的职责

    There are two fault detection processes running. The first is by the master, to ping all the other nodes in the cluster and verify that they are alive. And on the other end, each node pings to master to verify if its still alive or an election process needs to be initiated.

    由主节点负责ping 所有其他节点,判断是否有节点已经挂掉

    创建或删除索引

    决定分片在节点之间的分配

    稳定的主节点对集群的健康是非常重要的。虽然主节点也可以协调节点,路由搜索和从客户端新增数据到数据节点,但最好不要使用这些专用的主节点。一个重要的原则是,尽可能做尽量少的工作。

    对于大型的生产集群来说,推荐使用一个专门的主节点来控制集群,该节点将不处理任何用户请求。

    3. ElasticSearch 的数据实时性

    ElasticSearch 是通过怎样的手段做到数据的近实时搜索的?

    61dd9fb7d785

    一个Index由若干段组成,搜索的时候按段搜索,我们索引一条段后,每个段会通过fsync 操作持久化到磁盘,而fsync 操作比较耗时,如果每索引一条数据都做这个full commit(rsync)操作,提交和查询的时延都非常之大,所以在这种情况下做不到实时的一个搜索。

    FileSystem Cache 与 refresh

    针对这个问题的解决是在Elasticsearch和磁盘之间引入一层称为FileSystem Cache的系统缓存,正是由于这层cache的存在才使得es能够拥有更快搜索响应能力。

    61dd9fb7d785

    新的文档数据写入缓存区

    61dd9fb7d785

    缓存区的数据写入一个新段

    es中新增的document会被收集到indexing buffer区后被重写成一个segment然在es中新增的document会被收集到indexing buffer区后被重写成一个segment然后直接写入filesystem cache中,这个操作是非常轻量级的,相对耗时较少,之后经过一定的间隔或外部触发后才会被flush到磁盘上,这个操作非常耗时。但只要sengment文件被写入cache后,这个sengment就可以打开和查询,从而确保在短时间内就可以搜到,而不用执行一个full commit也就是fsync操作,这是一个非常轻量级的处理方式而且是可以高频次的被执行,而不会破坏es的性能。

    在elasticsearch里面,这个轻量级的写入和打开一个cache中的segment的操作叫做refresh,默认情况下,es集群中的每个shard会每隔1秒自动refresh一次,这就是我们为什么说es是近实时的搜索引擎而不是实时的,也就是说给索引插入一条数据后,我们需要等待1秒才能被搜到这条数据,这是es对写入和查询一个平衡的设置方式,这样设置既提升了es的索引写入效率同时也使得es能够近实时检索数据。

    参考:

    j近实时搜索翻译的比较好的博客:

    展开全文
  • HDFS数据一致性

    千次阅读 2018-09-11 10:22:45
    2.NameNode如何保证元数据一致性 3.校验和 4.为实现高可用,HDFS采用的诸多策略 4.1 冗余副本 4.2 机架感知 4.3 心跳机制 4.4 安全模式 4.5 校验和 4.6 回收站 4.7 元数据保护 4.8 快照机制 ...
  • 如何保证分布式系统数据一致性

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

    万次阅读 多人点赞 2016-02-19 15:27:38
    什么是数据一致性?  在数据有多分副本的情况下,如果网络、服务器或者软件出现故障,会导致部分副本写入成功,部分副本写入失败。这就造成各个副本之间的数据不一致,数据内容冲突。 实践中,导致数据不一致的情况...
  • 数据一致性校验

    千次阅读 2019-05-28 17:10:01
    todo
  • 目录 1. 传统应用的事务管理 1.1 本地事务 1.2 分布式事务 2. 微服务下的事务管理 3. 实现微服务下数据一致性的方式 3.1 可靠事件通知模式 ...再介绍微服务下的数据一致性之前,先简单地介绍一...
  • 数据一致性问题 写作背景:看了些视频,网上也看了很多篇文章,感觉写得都很片面,不是很全,所以我整体总结了一些,我不喜欢重复造轮子,对于网上很多篇复制机类型的文章(很多文章所有字体相同)且很多不正确严重...
  • 数据一致性问题

    万次阅读 2018-09-18 10:44:36
    2.一致性,在事务开始之前和结束之后,数据完整性不被破坏。 3.隔离性,允许并发事务对数据同时进行读写。防止多个事务交叉执行而导致数据不一致。事务隔离分为读未提交、读提交、可重复读和串行化。 4.持久性,...
  • ZooKeeper是如何保证数据一致性

    万次阅读 2019-08-05 11:03:02
    前面在讲HDFS和HBase架构分析的时候就提到了Zookeeper。...今天要讨论的是分布式系统一致性与Zookeeper的架构 通过之前的文章大家应该已经了解了HDFS为了保证整个集群的高可用,需要部署两台NameNod...
  • 背景  可用性(Availability)和一致性(Consistency)是分布式系统的基本问题,先有著名的CAP理论定义过分布式环境下二者不可兼... 在大数据场景下,分布式数据库的数据一致性管理是其最重要的内核技术之一,也...
  • mq的作用主要是用来解耦,削峰,异步,...也就是数据一致性问题。 下面是MQ丢失的3种情况 1,生产者发送消息至MQ的数据丢失 解决方法:在生产者端开启comfirm 确认模式,你每次写的消息都会分配一个唯一的 id, ...
  • 目录背景什么是一致性?B端业务场景重试幂等并发小结总结 背景 已经好久没写博客了,看了下最近的一篇已经是去年的了,由于工作一直忙,没有抽时间来写(其实就是懒)。加上也没有觉得非常有收获的事情,所以就干脆...
  • ZooKeeper能保证任何时刻读到的数据绝对一致吗? Zookeeper的特点就是,分布式,高可用,...也就是说可用性和一致性是Zookeeper的关键特性,作为一个消息的中间商,做了一个可靠的信息传递和存储的角色。 但是了解下ZooKeep
  • RPC--数据一致性

    千次阅读 2021-11-22 14:46:49
    分布式系统的一致性问题
  • Redis集群的数据一致性

    万次阅读 2019-04-11 16:54:54
    Redis集群的数据一致性 Redis 集群没有使用一致性hash, 而是引入了哈希槽的概念。 Reds 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽。这种结构很容易...
  • 数据库同步有3大难题: 1是如何保障目标和源数据一致性; 2是异构数据库如何做数据类型转换,导致数据同步失败的原因常常是因为数据类型不一样; 3是在数据越实时越有价值的背景下,同步过程中能否做到实时同步。
  • 细说分布式下的数据一致性

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

    千次阅读 多人点赞 2021-02-02 12:11:44
    1,首先要理解在并发环境下redis数据一致性的问题所在 在多线程并发情况下,假设有两个数据库修改请求,为保证数据库与redis的数据一致性, 修改请求的实现中需要修改数据库后,级联修改redis中的
  • 在数据集成中经常被提及的...而DataPipeline平台采用的Kafka Connect框架是如何保证数据一致性的? DataPipeline数据一致性示例 DataPipeline平台对于数据一致性的保证是通过Kafka Connect中内嵌的Offset管理机制,...
  • 高并发场景下如何保证数据库和缓存的数据一致性分析经典做法 分析 只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题? 经典做法 最经典的...
  • 保证分布式数据一致性的6种方案

    万次阅读 2018-07-30 17:17:07
    在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据一致性?  具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,需要满足要么同时成功;要么同时失败。A、B、C 可能是多...
  • 本人最近学习了一下微服务下数据一致性的特点,总结了下目前的保障微服务下数据一致性的几种实现方式如下,以备后查。此篇文章旨在给大家一个基于微服务的数据一致性实现的大概介绍,并未深入展开,具体的实现方式...
  • ElasticSearch教程——数据一致性

    千次阅读 2018-09-28 16:53:51
    一致性的条件下,系统在执行数据更新操作之后能够从一致性状态转移到另一个一致性状态。 对系统的一个数据更新成功之后,如果所有用户都能够读取到最新的值,该系统就被认为具有强一致性。 写一致性 对于写...
  • redis数据一致性

    万次阅读 2019-01-15 17:19:13
    前言:所谓的redis数据一致性即当进行修改或者保存、删除之后,redis中的数据也应该进行相应变化,不然用户再次查询的时候很可能查询出已经删除过的脏数据。 一、缓存一致的必要性 还是接上篇来说,我们已经解决了...
  • redis主从保证数据一致性

    万次阅读 多人点赞 2020-03-11 11:00:04
    redis主从保证数据一致性 前言 在redis中为了保证redis的高可用,一般会搭建一种集群模式就是主从模式。 主从模式可以保证redis的高可用,那么redis是怎么保证主从服务器的数据一致性的,接下来我们浅谈下redis主...
  • Redis与MySQL数据一致性问题详解

    千次阅读 2019-02-25 18:07:03
    不要求强一致性的读请求,走redis,要求强一致性的直接从mysql读取。 写请求: 数据首先都写到数据库,之后更新redis(先写redis再写mysql,如果写入失败事务回滚会造成redis中存在脏数据)。 【2】MySQL和Redis...
  • 微服务架构下的数据一致性保证

    千次阅读 2018-09-30 17:30:08
    设计到系统,其中绕不开的就是数据一致性,从本地事务,到后来的分布式事务,都能够有效的保证数据一致性。但是在微服务架构中,这两种方式都不是最好的选择。 1. 使用本地事务和分布式事务保证一致性 在传统的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,476,416
精华内容 590,566
关键字:

数据一致性