精华内容
下载资源
问答
  • d*v表示矩阵乘法,要求d的列数必须与v的行数一致,也就是说,如果d是m行n列的矩阵,v必须是n行w列的矩阵2.错误使用.* 矩阵维度必须一致 d.*v 表示矩阵的点乘运算,也就是d矩阵和v矩阵对应元素直接相乘,所以要求d和...

    1.错误使用* 内部矩阵维度必须一致
    d*v表示矩阵乘法,要求d的列数必须与v的行数一致,也就是说,如果d是m行n列的矩阵,v必须是n行w列的矩阵

    2.错误使用.* 矩阵维度必须一致
    d.*v 表示矩阵的点乘运算,也就是d矩阵和v矩阵对应元素直接相乘,所以要求d和v的维度必须一致,即如果d是m行n列的矩阵,v也必须是m行n列的矩阵

    展开全文
  • 一致性是一个深刻而复杂的问题,这篇文章是我目前的粗浅理解,如果发现理解错误还会继续更新 目前这篇文章只是记录我自己的理解,并没有考虑文章的可读性 本文由giantpoplar发表于CSDN,未经允许不得转载。 ...

    本文由giantpoplar发表于CSDN,转载请保留本声明。


    “Cache Coherence” V.S. “Memory Consistency” V.S. “Data Consistency”

    缓存一致性

    cache coherence 的coherence这个词猜测是体系结构圈为了和memory consistency做区分,用了coherence这个词,但我理解缓存一致性和分布式多副本数据的一致性基本接近,只不过cache coherence是一种同步可靠通信、有全局时钟条件下的强一致(linearizability)。cache一致性协议有MSI,MESI等,虽然处理器的整个内存系统很复杂,但就cache一致性协议来说,比分布式环境下的数据一致要简明一些

    多核处理器每个核会有私有cache,也就是内存里的一份数据在多个核上可能有了副本,这多个副本,每个核都可能会对一个内存地址有读写操作,每个核是直接读写自己私有的副本,这就要求各个副本上的读写操作顺序要一致,这和分布式环境下的数据一致性很接近。

    具体的MSI,MESI协议暂不展开写。

    内存一致性

    内存一致性说的是共享内存多核处理器访存序的问题,进程对某一个内存地址(和分布式的同一数据多副本的一致性有所区别)的访问序的在多核下暴露出的问题 全部内存读写顺序的正确性问题,单核乱序执行重新排列无关的指令在多核系统中可能出现问题。也就是程序中 Load Store 的(ISA)顺序(冯诺依曼架构下看可以看做内存操作请求的顺序)和Load Store实际执行完成的顺序可能相同、可能不同(这取决于微体系结构的实现),在多核情况下,程序的正确性可能出问题。有各种一致性模型来表达各种程度的相同不同,相应的有软、硬件机制来确保多核处理器上程序的正确运行。

    这里只具体写顺序一致性(sequential consistency)模型,更弱的一致性模型在学习过相关资料论文后再做补充。顺序一致性的概念来源于Lamport 1977年的一篇论文How to Make a Multiprocessor Computer That Correctly Executes Multiprocess Program
    这里写一下论文中给出的阐述
    看一个互斥协议,问题是多核处理器下多进程并发/并行会使得两个进程都进入临界区么?

    几点说明写在前面:

    • 1,2,3,4,5,6只是标号,数字本身带有的序和问题没联系
    • 程序里的读写操作都是一条指令的粒度,不是高级语言的一句语句
    • P1, P2指处理器
    - P1 - P2
    a=0 b=0
    1 a=1 4 b=1
    2 IF(b==0) THEN 5 IF(a==0) THEN
    (临界区) (临界区)
    3 a=0 6 b=0
    ELSE ELSE
    {…} {…}

    考虑这个例子,如下事件依次发生

    • 1 P1 发出a=1的请求,请求的是内存模块1,内存模块1此时正忙
    • 2 P1 发出取b的请求,请求的是内存模块2,内存模块2此时可用,取b的指令执行
    • 4 P2 发出b=1的请求,请求的是内存模块2,这个请求会在取b执行完成后执行
    • 5 P2 发送取a得请求,请求的是内存模块1,内存模块1此时正忙

    在这个例子里,这4条指令对同一内存请求顺序是1 ->5 ; 2->4
    这4条指令执行完成的顺序是什么呢 2->4;
    如果是 2->4;5 -> 1 这两个处理器会同时进入临界区
    如果是 2->4;1 -> 5 则不会
    -> 符号不直接对应happen-before

    顺序一致性有两个条件:

    • 每个处理器按程序序发射内存请求(1->2;4->5)
    • 所有处理器到单个存储器模块的请求依照FIFO序服务。请求的发射过程包含进入FIFO队列。

    我理解就是说,不管这多个处理器对同一内存的请求顺序如何交叠,都可以,但是内存必须按照请求到达的顺序执行(这里应该隐含着对同一地址先请求(指令发射)的先到达(指令执行)的假设),这样保证上面的互斥协议正确。这样的要求称为顺序一致的要求,是很严格的,会对硬件性能造成影响,其实可以放宽,不必严格按请求顺序执行,但是必须有软件机制来提供正确的互斥协议的实现,上面的护持互斥协议在弱于顺序一致的内存模型下是不正确的。

    也就是说1,2,4,5的请求可以有C(4,2)=6种交叠方式,每一种都符合顺序一致只要每种情况的执行也是按照这个顺序

    现在来看这句很拗口的话

    the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program

    似乎这个定义里要求每个核上不同内存地址的请求也要安程序序执行,但是在微体系结构层次,提交时要保持,但是执行时程序序是可以打破的,同一处理器不同地址请求序(乱序发射)和程序序(冯诺依曼ISA序)是否一致,请求序和执行序是否一致,这里似乎没有明说。分布式环境中的一致性是关于同一数据的多个副本上要达成全局一致性,某种角度来讲,如果把内存的请求发射和到达,类比分布式中对一个副本的写/读和向各个副本传播写/读操作,这两者非常类似 //但是感觉还是没有理解二者的本质

    单核处理器下多进程并发会使得两个进程都进入临界区么?此时表里的P1,P2代指进程。不会有这个问题,内存请求是从同一个核过来,到达顺序和服务顺序一样(单核天然是顺序一致的),不会有多核中多个请求到达,在执行请求时会涉及调度导致服务顺序和到达顺序不一致的情况。

    如果你考虑一个多核处理器的内存体系,就会发现这个问题很复杂,cache以及一致性,buffer,pipeline和内存一致性的保证,和分布式的一致性相比,虽然分布式下异步不可靠网络带来了很大挑战,但是现在我觉得处理器的内存系统可以说比分布式环境下的一致性问题更加复杂

    x86的内存一致模型是顺序一致的TSO,所以在实现一个正确的互斥锁的时候也没有考虑太多,比如没用memory barrier这种东西就对了

    数据一致性

    分布式系统为了性能、容错的需要,数据进行多副本冗余是一项很基本的技术。数据一致性说的是一份数据有多个副本,在多个副本上的读写操作的顺序要达成一致,这个一致也有很多不同的强弱要求,产生了众多的强弱一致性模型,这些模型的术语和内存一致性的术语有很大的重叠,可能是历史上并行体系结构和分布式系统两个领域是一伙人在搞?

    由强到弱的数据一致性模型构成了 数据一致性谱

    线性一致性和顺序一致性

    这两种都是称为强一致性

    • 线性一致性和顺序一致性都是强一致性
    • 都给客户端提供单副本的假象
    • Linearizability关乎时间,sequential consistency 关乎程序顺序

    分布式下强一致是个困难问题,著名的paxos算法挺复杂的,Raft是2014年出的一个可以看作是改良版的算法。

    线性一致性 Linearizability

    • 表现出单副本的行为
    • 读操作返回最近(most recent)的写,和client无关
    • 所有后序读返回相同值,直到下一次写,和client无关

    最近所有后序: 由时间确定
    e.g.
    这里写图片描述
    这里写图片描述
    这里写图片描述

    顺序一致性

    • 表现出单副本的行为
    • 读操作返回最近(most recent)的写,和client无关
    • 所有后序读返回相同值,直到下一次写,和client无关

    最近所有后序
    同一个client的操作由时间决定(程序序);
    跨client的操作:不由时间决定,我们可以安排某种序,只要保持程序序。

    从系统外的观察者来看:顺序一致性需要提供操作的全局序,1)工作起来像一个副本,2)来自同一个client的操作顺序被保持

    e.g.

    • 不违背顺序一致
    - - - - - -
    P1: W(x)a
    P2: W(x)b
    P3: R(x)b R(x)a
    P4: R(x)b R(x)a

    这个例子里面,横轴代表时间,时间上虽然W(x)a在前,W(x)b在后,但是其序不一定也如此,所以这个例子并不违背分布式环境下的顺序一致,也再次说明分布式的顺序一致是比内存的顺序一致更弱的一致

    • 违背顺序一致
    - - - - - -
    P1: W(x)a
    P2: W(x)b
    P3: R(x)b R(x)a
    P4: R(x)a R(x)b
    • 不违背顺序一致,违背线性一致
    - - - -
    P1: W(x)a W(x)b
    P2: R(x)a
    time ——-> ——-> ——->

    内存的顺序一致是顺序一致么?

    内存的顺序一致性和分布式哪一种强一致性是一样的呢?是顺序一致性么?因为分布式环境下没有全局时间,所以分布式数据顺序一致性退化成较弱的一种一致性,而Linearizability和内存的顺序一致性更接近。

    因果一致性
    放宽顺序一致性的要求,有因果关联的操作保持顺序,并发的(相互没有因果关联的)写操作可能在不同机器上顺序不同
    因果关系可以由vector-clock捕捉
    e.g.

    • 违背顺序一致,不违背因果一致
    - - - - - - -
    P1: W(x)a W(x)c
    P2: R(x)a W(x)b
    P3: R(x)a R(x)c R(x)b
    P4: R(x)a R(x)b R(x)c
    • 违背因果一致
    - - - - - -
    P1: W(x)a
    P2: R(x)a W(x)b
    P3: R(x)b R(x)a
    P4: R(x)a R(x)b
    • 不违背因果一致
    - - - - - -
    P1: W(x)a
    P2: W(x)b
    P3: R(x)b R(x)a
    P4: R(x)a R(x)b

    最终一致性
    某些副本的数据已经修改,而另一些副本的数据还没来得及修改。当修改可靠地传播到所有副本,并给予足够的时间,所有副本的数据都将变成新值,取得一致。

    happen-before

    理解一致性要理解一个并发系统中的“序”的问题,什么叫先,什么叫后。在分布式系统中,这个问题困难是因为没有完美的全局同步时钟,多核系统中是因为多核的微体系结构上的原因。

    Lamport在1978年的论文中给出了happen-before的定义,这篇论文非常经典,提出了很多分布式系统中十分重要的概念,此处暂不展开,只谈happen-before。据说这篇文章受相对论启发,了解happen-before有助于理解时间、顺序。

    happen-before 关系

    基本假设

    • 假设进程的事件(event)形成一个序列(sequence),单个进程定义为 一组事件的全序(total ordering)
    • 假设进程之间消息(message)的发送(send)和接受(receive)是事件

    happen-before 是满足以下条件的最小关系(relation)

    • 如果a,b是同一个进程的事件,a在b前面 ,那么ab
    • 如果a是发送消息进程的发送事件,b是接收该消息进程的接受事件,那么ab
    • 如果ab,bc,那么ac

    定义aa
    另外,如果两个不同的事件a,b,有 ab,ba,就称a,b是并发的(concurrent)

    这样从数学上看,happen-before就是一个定义在所有事件上偏序关系,反自反,反对称,传递性都有了,偏序关系中存在不可比的情况,所以有些事件并无先后是并发的,如果在加上限制条件 break tie,那么在这个偏序关系上就可以定义一个全序关系。

    进程和事件的定义非常general,事件可以是一个子程序的执行、也可以是一条机器指令的执行。

    消息的发送和接受在分布式系统中很显然。在体系结构方面也有类似之处,考虑单核处理器、冯诺依曼架构中指令顺序执行,其实这些指令并不需要严格一条接着一条指令,所以会有乱序执行,在乱序执行里,如果把同一内存地址的写读看做消息发送接收,其实乱序执行的写后读依赖就和happen-before序十分类似。

    引用

    [1].Gharachorloo, Kourosh, et al. Memory consistency and event ordering in scalable shared-memory multiprocessors. Vol. 18. No. 2SI. ACM, 1990.
    [2].Lamport, Leslie. “Time, clocks, and the ordering of events in a distributed system.” Communications of the ACM 21.7 (1978): 558-565.
    [3]Lamport, Leslie. “How to make a multiprocessor computer that correctly executes multiprocess progranm.” IEEE transactions on computers 9 (1979): 690-691.
    [4].Tanenbaum, Andrew S., and Maarten Van Steen. Distributed systems: principles and paradigms. Prentice-Hall, 2007.
    [5].https://homes.cs.washington.edu/~bornholt/post/memory-models.html
    [6].https://cse.buffalo.edu/~stevko/courses/cse486/spring15/lectures/23-consistency2.pdf

    展开全文
  • 浅析数据一致

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

    欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


    什么是数据一致性?

      在数据有多分副本的情况下,如果网络、服务器或者软件出现故障,会导致部分副本写入成功,部分副本写入失败。这就造成各个副本之间的数据不一致,数据内容冲突。 实践中,导致数据不一致的情况有很多种,表现样式也多种多样,比如数据更新返回操作失败,事实上数据在存储服务器已经更新成功。


    CAP定理

      CAP定理是2000年,由 Eric Brewer 提出来的。Brewer认为在分布式的环境下设计和部署系统时,有3个核心的需求,以一种特殊的关系存在。这里的分布式系统说的是在物理上分布的系统,比如我们常见的web系统。
      这3个核心的需求是:Consistency,Availability和Partition Tolerance,赋予了该理论另外一个名字 - CAP。
      Consistency:一致性,这个和数据库ACID的一致性类似,但这里关注的所有数据节点上的数据一致性和正确性,而数据库的ACID关注的是在在一个事务内,对数据的一些约束。系统在执行过某项操作后仍然处于一致的状态。在分布式系统中,更新操作执行成功后所有的用户都应该读取到最新值。
      Availability:可用性,每一个操作总是能够在一定时间内返回结果。需要注意“一定时间”和“返回结果”。“一定时间”是指,系统结果必须在给定时间内返回。“返回结果”是指系统返回操作成功或失败的结果。
      Partition Tolerance:分区容忍性,是否可以对数据进行分区。这是考虑到性能和可伸缩性。
      CAP定理认为,一个提供数据服务的存储系统无法同事满足数据一致性、数据可用性、分区容忍性。
      为什么不能完全保证这个三点了,个人觉得主要是因为一旦进行分区了,就说明了必须节点之间必须进行通信,涉及到通信,就无法确保在有限的时间内完成指定的行文,如果要求两个操作之间要完整的进行,因为涉及到通信,肯定存在某一个时刻只完成一部分的业务操作,在通信完成的这一段时间内,数据就是不一致性的。如果要求保证一致性,那么就必须在通信完成这一段时间内保护数据,使得任何访问这些数据的操作不可用。
      如果想保证一致性和可用性,那么数据就不能够分区。一个简单的理解就是所有的数据就必须存放在一个数据库里面,不能进行数据库拆分。这个对于大数据量,高并发的互联网应用来说,是不可接受的。
      在大型网站应用中,数据规模总是快速扩张的,因此可伸缩性即分区容忍性必不可少,规模变大以后,机器数量也会变得庞大,这是网络和服务器故障会频繁出现,要想保证应用可用,就必须保证分布式处理系统的高可用性。所以在大型网站中,通常会选择强化分布式存储系统的可用性(A)和伸缩性§,在某种程度上放弃一致性©。一般来说,数据不一致通常出现在系统高并发写操作或者集群状态不稳(故障恢复、集群扩容等)的情况下,应用系统需要对分布式数据处理系统的数据不一致性有所了解并进行某种意义上的补偿和纠错,以避免出现应用系统数据不正确。


    数据一致性模型

      一些分布式系统通过复制数据来提高系统的可靠性和容错性,并且将数据的不同的副本存放在不同的机器,由于维护数据副本的一致性代价高,因此许多系统采用弱一致性来提高性能,一些不同的一致性模型也相继被提出。

    1. 强一致性: 要求无论更新操作实在哪一个副本执行,之后所有的读操作都要能获得最新的数据。
    2. 弱一致性:用户读到某一操作对系统特定数据的更新需要一段时间,我们称这段时间为“不一致性窗口”。
    3. 最终一致性:是弱一致性的一种特例,保证用户最终能够读取到某操作对系统特定数据的更新。

    数据一致性实现技术

    Quorum系统NRW策略

      这个协议有三个关键字N、R、W。

    • N代表数据所具有的副本数。
    • R表示完成读操作所需要读取的最小副本数,即一次读操作所需要参与的最小节点数目。
    • W表示完成写操作所需要写入的最小副本数,即一次写操作所需要参与的最小节点数目。

      该策略中,只需要保证R+W>N,就可以保证强一致性。
      例如:N=3,W=2,R=2,那么表示系统中数据有3个不同的副本,当进行写操作时,需要等待至少有2个副本完成了该写操作系统才会返回执行成功的状态,对于读操作,系统有同样的特性。由于R + W > N,因此该系统是可以保证强一致性的。
      R + W> N会产生类似Quorum的效果。该模型中的读(写)延迟由最慢的R(W)副本决定,有时为了获得较高的性能和较小的延迟,R和W的和可能小于N,这时系统不能保证读操作能获取最新的数据。
      如果R + W > N,那么分布式系统就会提供强一致性的保证,因为读取数据的节点和被同步写入的节点是有重叠的。在关系型数据管理系统中,如果N=2,可以设置为W=2,R=1,这是比较强的一致性约束,写操作的性能比较低,因为系统需要2个节点上的数据都完成更新后才将确认结果返回给用户。
      如果R + W ≤ N,这时读取和写入操作是不重叠的,系统只能保证最终一致性,而副本达到一致的时间则依赖于系统异步更新的实现方式,不一致性的时间段也就等于从更新开始到所有的节点都异步完成更新之间的时间。
    R和W的设置直接影响系统的性能、扩展性与一致性。如果W设置为1,则一个副本完成更改就可以返回给用户,然后通过异步的机制更新剩余的N-W的副本;如果R设置为1,只要有一个副本被读取就可以完成读操作,R和W的值如较小会影响一致性,较大则会影响性能,因此对这两个值的设置需要权衡。

    下面为不同设置的几种特殊情况:
    1. 当W=1,R=N时,系统对写操作有较高的要求,但读操作会比较慢,若N个节点中有节点发生故障,那么读操作将不能完成。
    2. 当R=1,W=N时,系统对读操作有较高性能、高可用,但写操作性能较低,用于需要大量读操作的系统,若N个节点中有节点发生故障,那么些操作将不能完成。
    3. 当R=Q,W=Q(Q=N/2+1)时,系统在读写性能之间取得平衡,兼顾了性能和可用性。

    两阶段提交算法

      在两阶段提交协议中,系统一般包含两类机器(或节点):一类为协调者(coordinator),通常一个系统中只有一个;另一类为事务参与者(participants,cohorts或workers),一般包含多个,在数据存储系统中可以理解为数据副本的个数。两阶段提交协议由两个阶段组成,在正常的执行下,这两个阶段的执行过程如下所述:

    • 阶段1:请求阶段(commit-request phase,或称表决阶段,voting phase)。
      在请求阶段,协调者将通知事务参与者准备提交或取消事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行故障)。
    • 阶段2:提交阶段(commit phase)。
      在该阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消。当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务。参与者在接收到协调者发来的消息后将执行响应的操作。

      举个例子:A组织B、C和D三个人去爬长城:如果所有人都同意去爬长城,那么活动将举行;如果有一人不同意去爬长城,那么活动将取消。用2PC算法解决该问题的过程如下:

    1. 首先A将成为该活动的协调者,B、C和D将成为该活动的参与者。
    2. 阶段1:A发邮件给B、C和D,提出下周三去爬山,问是否同意。那么此时A需要等待B、C和D的邮件。B、C和D分别查看自己的日程安排表。B、C发现自己在当日没有活动安排,则发邮件告诉A它们同意下周三去爬长城。由于某种原因,D白天没有查看邮件。那么此时A、B和C均需要等待。到晚上的时候,D发现了A的邮件,然后查看日程安排,发现周三当天已经有别的安排,那么D回复A说活动取消吧。
    3. 阶段2:此时A收到了所有活动参与者的邮件,并且A发现D下周三不能去爬山。那么A将发邮件通知B、C和D,下周三爬长城活动取消。此时B、C回复A“太可惜了”,D回复A“不好意思”。至此该事务终止。

      两阶段提交算法在分布式系统结合,可实现单用户对文件(对象)多个副本的修改,多副本数据的同步。其结合的原理如下:

    1. 客户端(协调者)向所有的数据副本的存储主机(参与者)发送:修改具体的文件名、偏移量、数据和长度信息,请求修改数据,该消息是1阶段的请求消息。
    2. 存储主机接收到请求后,备份修改前的数据以备回滚,修改文件数据后,向客户端回应修改成功的消息。如果存储主机由于某些原因(磁盘损坏、空间不足等)不能修改数据,回应修改失败的消息。
    3. 客户端接收发送出去的每一个消息回应,如果存储主机全部回应都修改成功,向每存储主机发送确认修改的提交消息;如果存在存储主机回应修改失败,或者超时未回应,客户端向所有存储主机发送取消修改的提交消息。该消息是2阶段的提交消息。
    4. 存储主机接收到客户端的提交消息,如果是确认修改,则直接回应该提交OK消息;如果是取消修改,则将修改数据还原为修改前,然后回应取消修改OK的消息。
    5. 客户端接收全部存储主机的回应,整个操作成功。

      在该过程中可能存在通信失败,例如网络中断、主机宕机等诸多的原因,对于未在算法中定义的其它异常,都认为是提交失败,都需要回滚,这是该算法基于确定的通信回复实现的,在参与者的确定回复(无论是回复失败还是回复成功)之上执行逻辑处理,符合确定性的条件当然能够获得确定性的结果哲学原理。
      缺点:单个A是个严重问题:没有热备机制,A节点宕机了或者链接它的网络坏了会阻塞该事务;吞吐量不行,没有充分发动更多A的力量,一旦某个A第一阶段投了赞成票就得在它上面加独占锁,其他事务不得接入,直到当前事务提交or回滚。

    分布式锁服务

      分布式锁是对数据被外界修改持保守态度,在整个数据处理过程中将数据处于锁定状态,在用户修改数据的同时,其它用户不允许修改。
      采用分布式锁服务实现数据一致性,是在操作目标之前先获取操作许可,然后再执行操作,如果其他用户同时尝试操作该目标将被阻止,直到前一个用户释放许可后,其他用户才能够操作目标。分析这个过程,如果只有一个用户操作目标,没有多个用户并发冲突,也申请了操作许可,造成了由于申请操作许可所带来的资源使用消耗,浪费网络通信和增加了延时。
      采用分布式锁实现多副本内容修改的一致性问题, 选择控制内容颗粒度实现申请锁服务。例如我们要保证一个文件的多个副本修改一致, 可以对整个文件修改设置一把锁,修改时申请锁,修改这个文件的多个副本,确保多个副本修改的一致,修改完成后释放锁;也可以对文件分段,或者是文件中的单个字节设置锁, 实现更细颗粒度的锁操作,减少冲突。
      常用的锁实现算法有Lamport bakery algorithm (俗称面包店算法), 还有Paxos算法以及乐观锁。下面对其原理做简单概述。

    1. Lamport面包店算法

      是解决多个线程并发访问一个共享的单用户资源的互斥问题的算法。 由Leslie Lamport(英语:Leslie Lamport)发明。
      这个算法也可以称为时间戳策略,或者叫做Lamport逻辑时钟。
      这里先陈述一下这个逻辑时钟的内容:
      我们用分布式系统中的事件的先后关系,用“->”符号来表示,例如:若事件a发生在事件b之前,那么a->b.
      该关系需要满足下列三个条件:

    1. 如果a和b是同一进程中的事件,a在b之前发生,则a->b
    2. 如果事件a是消息发送方,b是接收方,则a->b
    3. 对于事件a、b、c,如果有a->b,b->c,则有a->c

      注意,对于任何一个事件a,a -> a都是不成立的,也就是说,关系->是反自反的。有了上面的定义,我们也可以定义出“并发”(concurrent)的概念了:

    对于事件a、b,如果a -> b,b -> a两个都不成立,那么a和b就是并发的。

      直观上,上面的->关系非常好理解,即“xxx在xxx之前发生”。也就是说,一个系统在输入I1下,如果有a->b,那么对于这个系统的同一个输入I1,无论重复运行多少次,a也始终发生在b之前;如果在输入I1下a和b是并发的,则表示在同一个输入I1下的不同运行中,a可能在b之前,也可能在b之后,也可能恰好同时发生。也就是,并发并不是指一定同时发生,而是表示一种不确定性。->和并发的概念,就是我们理解一个系统时最基础的概念之一了。
      有了上面的概念,我们可以给系统引入时钟了。这里的时钟就是lamport逻辑时钟。一个时钟,本质上是一个事件到实数(假设时间是连续的)的函数。这个函数将每个事件映射到一个数字,代表这个事件发生的时间。形式一点来说,对于每个进程Pi,都有一个时钟Ci,这个时钟将该进程中的事件a映射到Ci(a)。而整个系统的时钟C=< C0, C1, …, Cn>,对于一个事件b,假设b属于进程Pj,那么C(b) =Cj(b)。

      这里插一句,从这个定义也可以看到大师对分布式系统的理解。分布式系统中不存在一个“全局”的实体。在该系统中,每个进程都是一个相对独立的实体,它们有自己的本地信息(本地Knowledge)。而整个系统的信息则是各个进程的信息的一个聚合。
      有了时钟的一个“本质定义”还不够,我们需要考虑,什么样的时钟是一个有意义的,或者说正确的时钟。其实,有了前文的->关系的定义,正确的时钟应满足的条件已经十分明显了:
      时钟条件:对于任意两个事件a,b,如果a -> b,那么C(a) < C(b)。
      注意,反过来讲这个条件可不成立。如果我们要求反过来也成立,即“如果a -> b为假,那么C(a) < C(b)也为假”,那就等于要求并发事件必须同时发生,这显然是不合理的。
      结合前文->关系的定义,我们可以把上面的条件细化成如下两条:

    1. 如果a和b是进程Pi中的两个事件,并且在Pi中,a在b之前发生,那么Ci(a) < Ci(b);
    2. 如果a是Pi发送消息m,b是Pj接收消息m,那么Ci(a) < Cj(b);

      上面就定义了合理的逻辑时钟。显然,一个系统可以有无数个合理的逻辑时钟。实现逻辑时钟也相对简单,只要遵守两条实现规则就可以了:

    1. 每个进程Pi在自己的任何两个连续的事件之间增加Ci值;
    2. 如果事件a是Pi发送消息m,那么在m中应该带上时间戳Tm=Ci(a);如果b是进程Pj接收到消息m,那么,进程Pj应该设置Cj为大于max(Tm,Cj(b))。

      有了上面逻辑时钟的定义,我们现在可以为一个系统中所有的事件排一个全序,就是使用事件发生时的逻辑时钟读数进行排序,读数小的在先。当然,此时可能会存在两个事件同时发生的情况。如果要去除这种情况,方法也非常简单:如果a在进程Pi中,b在进程Pj中,Ci(a) = Cj(b)且i < j,那么a在b之前。形式化一点,我们可以把系统事件E上的全序关系“=>”定义为:
      假设a是Pi中的事件,b是Pj中的事件,那么:a => b当且仅当以下两个条件之一成立:

    1. Ci(a) < Cj(b);
    2. Ci(a) = Cj(b) 且 i < j;

      Lamport把上面这些数理逻辑时钟的概念以非常直观地类比为顾客去面包店采购。面包店只能接待一位顾客的采购。已知有n位顾客要进入面包店采购,安排他们按照次序在前台登记一个签到号码。该签到号码逐次加1。根据签到号码的由小到大的顺序依次入店购货。完成购买的顾客在前台把其签到号码归0. 如果完成购买的顾客要再次进店购买,就必须重新排队。
      这个类比中的顾客就相当于线程,而入店购货就是进入临界区独占访问该共享资源。由于计算机实现的特点,存在两个线程获得相同的签到号码的情况,这是因为两个线程几乎同时申请排队的签到号码,读取已经发出去的签到号码情况,这两个线程读到的数据是完全一样的,然后各自在读到的数据上找到最大值,再加1作为自己的排队签到号码。为此,该算法规定如果两个线程的排队签到号码相等,则线程id号较小的具有优先权。
      把该算法原理与分布式系统相结合,即可实现分步锁。
      注意这个系统中需要引入时钟同步,博主的意见是可以采用SNTP实现时钟同步(非权威,仅供参考)。

    2.Paxos算法

      该算法比较热门,类似2pc算法的升级版,在此不做赘述,可以自行搜索相关资料。(博主会在之后整理列出)
      需要注意的是这个算法也是Leslie Lamport提出的,由此可见这位大师之牛逼!
      Paxos算法解决的问题是一个分布式系统如何就某个值(决议)达成一致。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。一个通用的一致性算法可以应用在许多场景中,是分布式计算中的重要问题。节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。Paxos算法就是一种基于消息传递模型的一致性算法。BigTable使用一个分布式数据锁服务Chubby,而Chubby使用Paxos算法来保证备份的一致性。
      不仅只用在分布式系统,凡是多个过程需要达成某种一致性的都可以用到Paxos 算法。一致性方法可以通过共享内存(需要锁)或者消息传递实现,Paxos 算法采用的是后者。下面是Paxos 算法适用的几种情况:一台机器中多个进程/线程达成数据一致;分布式文件系统或者分布式数据库中多客户端并发读写数据;分布式存储中多个副本响应读写请求的一致性。

    3. 采用乐观锁原理实现的同步

      我们举个例子说明该算法的实现原理。如一个金融系统,当某个操作员读取用户的数据,并在读出的用户数据的基础上进行修改时(如更改用户帐户余额),如果采用前面的分布式锁服务机制,也就意味着整个操作过程中(从操作员读出数据、开始修改直至提交修改结果的全过程,甚至还包括操作员中途去煮咖啡的时间),数据库记录始终处于加锁状态,可以想见,如果面对几百上千个并发,这样的情况将导致怎样的后果。
      乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本( Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。
      对于上面修改用户帐户信息的例子而言,假设数据库中帐户信息表中有一个 version 字段,当前值为 1 ;而当前帐户余额字段( balance )为 $100 。

    1. 操作员 A 此时将其读出(version=1 ),并从其帐户余额中扣除 $50($100-$50 )。
    2. 在操作员 A 操作的过程中,操作员B也读入此用户信息( version=1 ),并从其帐户余额中扣除 $20 ( $100-$20 )。
    3. 操作员 A 完成了修改工作,将数据版本号加一( version=2 ),连同帐户扣除后余额( balance=$50),提交至数据库更新,此时由于提交数据版本大于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。
    4. 操作员 B 完成了操作,也将版本号加一( version=2 )试图向数据库提交数据( balance=$80),但此时比对数据库记录版本时发现,操作员 B 提交的数据版本号为 2 ,数据库记录当前版本也为 2 ,不满足 “提交版本必须大于记录当前版本才能执行更新 “ 的乐观锁策略,因此,操作员 B 的提交被驳回。这样,就避免了操作员 B 用基于version=1 的旧数据修改的结果覆盖操作员A 的操作结果的可能。

    欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


    展开全文
  • Cache 一致

    千次阅读 2019-06-16 16:13:16
    Write invalidate提供了实现Cache一致性的简单思想,处理器上会有一套完整的协议,来保证Cache一致性。比较经典的Cache一致性协议当属MESI协议,奔腾处理器有使用它,很多其他的处理器都是使用它的变种。 单核处理器...

    Write invalidate提供了实现Cache一致性的简单思想,处理器上会有一套完整的协议,来保证Cache一致性。比较经典的Cache一致性协议当属MESI协议,奔腾处理器有使用它,很多其他的处理器都是使用它的变种。

    单核处理器Cache中每个Cache line有2个标志:dirty和valid标志,它们很好的描述了Cache和Memory(内存)之间的数据关系(数据是否有效,数据是否被修改), 而在多核处理器中,多个核会共享一些数据,MESI协议就包含了描述共享的状态。

    在MESI协议中,每个Cache line有4个状态,可用2个bit表示,它们分别是:

    状态 描述
    M(Modified) :这行数据有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。
    E(Exclusive):这行数据有效,数据和内存中的数据一致,数据只存在于本Cache中。
    S(Shared):这行数据有效,数据和内存中的数据一致,数据存在于很多Cache中。
    I(Invalid) :这行数据无效
    MESI状态
    M(Modified)和E(Exclusive)状态的Cache line,数据是独有的,不同点在于M状态的数据是dirty的(和内存的不一致),E状态的数据是clean的(和内存的一致)。
    S(Shared)状态的Cache line,数据和其他的Cache共享。只有clean的数据才能被多个Cache共享。
    I(Invalid)表示这个Cache line无效。

    E状态示例如下:
    在这里插入图片描述

    E状态

    只有Core 0访问变量x,它的Cache line状态为E(Exclusive)。

    S状态示例如下:
    在这里插入图片描述

    S状态

    3个Core都访问变量x,它们对应的Cache line为S(Shared)状态。

    M状态和I状态示例如下:
    在这里插入图片描述

    M状态和I状态

    Core 0修改了x的值之后,这个Cache line变成了M(Modified)状态,其他Core对应的Cache line变成了I(Invalid)状态。
    在MESI协议中,每个Cache的Cache控制器不仅知道自己的读写操作,而且也监听(snoop)其它Cache的读写操作。每个Cache line所处的状态根据本核和其它核的读写操作在4个状态间进行迁移。

    MESI协议状态迁移图如下:
    在这里插入图片描述

                                      MESI协议状态迁移图
    

    在上图中,Local Read表示本内核读本Cache中的值,Local Write表示本内核写本Cache中的值,Remote Read表示其它内核读其它Cache中的值,Remote Write表示其它内核写其它Cache中的值,箭头表示本Cache line状态的迁移,环形箭头表示状态不变。

    MESI状态之间的迁移过程如下:
    在这里插入图片描述
    AMD的Opteron处理器使用从MESI中演化出的MOSEI协议,O(Owned)是MESI中S和M的一个合体,表示本Cache line被修改,和内存中的数据不一致,不过其它的核可以有这份数据的拷贝,状态为S。

    Intel的core i7处理器使用从MESI中演化出的MSEIF协议,F(Forward)从Share中演化而来,一个Cache line如果是Forward状态,它可以把数据直接传给其它内核的Cache,而Share则不能。

    展开全文
  • GFS中一致性的总结

    千次阅读 2021-03-19 13:32:13
    这两个一致性有本质的区别,事务的 ACID 属性中有一个 C 是 Consistency,表示事务的执行一定保证数据库中数据的约束不被破坏。而分布式领域提及的 Consistency 表示系统的正确性模型。 下面只讨论分布式系统中的...
  • 一致代码段与非一致代码段

    千次阅读 2012-08-27 21:56:00
    一致”的意思大约是这样,当转移的目标是一个特权级更高的一致代码段时,当前的特权级会被延续下去,而向特权级更高的非一致代码段的转移则会引起 常规的保护异常,除非使用调用门或者任务门。一致代码段往往是用...
  • 一致代码段和非一致代码段在存储段描述符中,属性区域的TYPE...位2称为C位,位C=1,表示对应的代码段是一致代码段;位C=0,表示对应的代码段不是一致代码段.所谓的“一致代码段”,目的是为了共享,比如该一致代码段的特
  • 一致性hash算法

    千次阅读 2019-04-27 22:47:14
    一致性hash算法Hash算法的作用Hash算法的冲突一致性hash算法一致性hash算法的原理容错性虚拟节点 Hash 算法也叫做散列算法,他可以让任意长度的数据M映射成为长度固定的值H。 Hash算法的作用 Hash算法的第一个作用...
  • 分布式系统的一致性问题(汇总)

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

    万次阅读 多人点赞 2018-03-13 21:15:32
    最近有小伙伴跑过来问什么是Hash一致性算法,说面试的时候被问到了,因为不了解,所以就没有回答上,问我有没有相应的学习资料推荐,当时上班,没时间回复,晚上回去了就忘了这件事,今天突然看到这个,加班为大家...
  • GFS一致性总结

    千次阅读 多人点赞 2017-05-10 19:29:47
    最近读了GFS的论文,整理了一下其中涉及的一致性,总结在这里,个人理解,如果有不对的...副本一致表示同一数据的多个副本的值相同。GFS作为一种分布式文件系统,采用了多副本机制,自然也会有一致性问题。影响一致
  • 一致性哈希算法

    千次阅读 2015-07-20 21:00:47
    前言很多人估计都听过哈希,顾名思义,一般程序的直接反映就是做映射的嘛,哈希算法,当然这不是今天本文所讲的重点,今天主要所讲的是另外一个名词,一致性哈希算法,光从字面上的意思想,这一定是对于原有算法的一...
  • 缓存一致

    千次阅读 2016-12-18 20:55:49
    Cache 一致性问题:在多核系统中,各个核的cache存储相同变量的副本,当一个处理器更新cache中该变量的副本时,其他处理器应该知道该变量已更新,即其他处理器中cache的副本也应该更新。  有两种主要的方法来保证...
  • Raft 一致性算法论文

    万次阅读 2019-05-17 09:52:13
    本篇博客为著名的 RAFT 一致性算法论文的中文翻译,论文名为《In search of an Understandable Consensus Algorithm (Extended Version)》(寻找一种易于理解的一致性算法)。 Raft 是一种用来管理日志复制的一致性...
  • 分布式一致性hash算法

    千次阅读 2018-01-01 11:44:40
    写在前面  在学习Redis的集群内容时,看到这么一句话:Redis并没有使用一致性hash算法,而是引入哈希槽的概念。而分布式缓存Memcached则是使用分布式一致性hash算法来实现分布式存储。所以就专门学习了一下什么是...
  • Redis集群的数据一致

    万次阅读 2019-04-11 16:54:54
    Redis集群的数据一致性 Redis 集群没有使用一致性hash, 而是引入了哈希槽的概念。 Reds 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽。这种结构很容易...
  • CPL(Current Priviliege Level):它代表了当前代码段的特权等级,由CS和SS的第0位和第1位表示。当程序转移到不同的特权等级的代码时处理器将改变CPL。在遇到一致代 码段时,一致代码可以被相同或者更低特权等级(用户...
  • KAPPA一致

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

    千次阅读 2019-12-12 13:30:12
    订阅关系一致指的是同一个消费者 Group ID 下所有 Consumer 实例的处理逻辑必须...消息队列 RocketMQ 版里的一个消费者 Group ID 代表一个 Consumer 实例群组。对于大多数分布式应用来说,一个消费者 Group ID 下通...
  • 多核cache一致

    千次阅读 2013-12-05 17:31:53
    多核cache主要有两种一致性协议,一种所基于监听的,另外一种是基于目录,在这里我们主要考察基于监听的。 标志位有: valid: 是否有效 dirty: 脏位 exclusive: 独享、共享、标志 状态有: 表示: 2 多核cache操作
  • Linux内核 文件一致性之主动一致

    千次阅读 2013-08-11 22:17:31
     一般来说,一个成熟的系统需要提供多种机制来保证数据一致性,其一是用户可控的,即用户能通过特定的接口去控制文件数据的一致性,这是对于文件数据一致性要求比较高的应用需要的语义。另一方面
  • 分布式环境Raft一致性共识算法解读

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

    千次阅读 2019-02-04 20:08:30
    在分布式系统中,有一类经典的问题经常会被提起:一致性问题。在单机环境中,这看起来根本不是一个问题。但是在多机,多服务,不同网络环境下时,一致性问题就是一个典型的问题了。在分布式系统中,当我们提到一致性...
  • ElasticSearch教程——数据一致

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

    千次阅读 2019-01-26 19:52:04
    一致性模型 一致性(Consistency)是指多副本(Replications)问题中的数据一致性。关于分布式系统的一致性模型有以下几种: 强一致性 当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过...
  • Raft一致性算法

    万次阅读 多人点赞 2014-08-04 20:42:15
    Paxos算法是莱斯利·兰伯特(LeslieLamport,就是 LaTeX 中的”La”,此人现在在微软研究院)于1990年提出的一种基于消息传递的一致性算法。由于算法难以理解起初并没有引起人们的重视,使Lamport在八年后1998年...
  • ZooKeeper数据一致

    千次阅读 2017-11-30 10:42:04
    ZooKeeper为存储的数据提供了一致性保证,不管应用从哪个服务端获取数据,都能获取到一致的数据。ZooKeeper内部使用原子广播协议(Zab)作为其一致性复制的核心,并通过对服务端请求的排序达到数据一致性的保障要求...
  • 一致性算法分析

    万次阅读 2018-01-18 14:25:47
    目的 :一致性算法的出现是为了解决一致性问题,一致性问题是指对于一组服务器(集群),给定一组操作,需要使用一种协议使得它们的结果最终达成一致,看起来好像是一台服务器一样。 作用 :一致性算法在构建可信赖...
  • 返回结果的HTTP状态码分别代表什么意思? 本篇博客总结自《图解HTTP》,内容没有复制粘贴,纯手打(也为了自己记的更牢)???? 文章目录返回结果的HTTP状态码分别代表什么意思?状态码类别2xx成功200 OK204 No ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,390,841
精华内容 556,336
关键字:

一致表示的意思