根据datastax文章,如果R+W>N,其中R是读操作的一致性级别W是写操作的一致级别N是副本数,则可以保证强一致性
强一致性在这里意味着什么?这是否意味着“每次”从数据库发出查询响应时,响应将“始终”是最后更新的值?如果Cassandra保持了强一致性条件,那么,是否没有返回的数据可能不一致的情况?简而言之,强一致性是否意味着100%一致性?
编辑1
添加一些关于Cassandra即使在R+W>RF时也可能不一致的场景的附加材料
1.Write fails with Quorum CL
1.Cassandra's eventual consistency
5条答案
按热度按时间vh0rcniy1#
Cassandra具有可调节的一致性,您可以选择一些折衷方案。
R+W>N-这只是意味着往返中必须有一个重叠的节点,该节点具有可用的实际和最新数据,以保持一致。
例如,如果在CL.ONE处写入,则需要在CL.ALL处读取,以确保获得一致的结果:N+1>N-但您可能不需要CL.ALL,因为您不能容忍集群中的单个节点故障。
通常,您可以在读写时选择CL.QUORUM,以确保一致性并容忍节点故障。例如,当RF=3时,QUORUM需要(3/2)+1=2个可用节点,因此R+W>N将为4>3-您的请求是一致的,并且您可以容忍单节点故障。
需要记住的一点是,在所有节点(cassandra和应用程序)上拥有30个同步时钟非常重要,您需要启动并运行ntp。
uxh89sit2#
虽然这是一个老问题,但我想我会插手来澄清这个问题。
R+W>RF并不意味着一致性强
具有**R+W>RF*的系统最终将保持一致。强一致性声明保证了节点故障期间或写入之间的中断。例如,考虑以下场景:
假设有3个节点A、B、C,RF=3,W=3,R=2(因此,R+W=5>3=RF)
进一步假设键k与值v相关联,即(k,v)存储在数据库中。假设发生以下一系列操作:
*t=1:(k,v1)写入请求从用户发送到A、B、C
*t=2:(k,v1)达到A并写入存储在A
*t=3:读卡器1发送密钥k的读取请求,由a和B回复
*t=4:读卡器1收到响应(k,v1)-根据最新写入获胜规则
*t=5:读卡器1发送另一个读取请求,由节点B和C提供服务
*t=6:读卡器1接收到响应(k,v),这是一个较早的值不一致
*t=7:(k,v1)达到C并被写入C存储
*t=8:(k,v1)达到B并写入存储在B
这表明,W+R>RF不能保证强一致性。为了确保强一致性,您可能需要使用另一种算法,如paxos或raft,这有助于确保写入是原子的您可以在同一here上阅读一篇有趣的文章(请查看FAQ部分)
编辑:
Cassandra确实有一些内部机制(称为阻塞读取修复),在将数据库的响应发送回客户端之前触发同步写入。这种同步读取修复发生在被查询的节点之间出现不一致的情况下,以达到读取一致性级别,并确保所谓的单调读取一致性[定义见下文]。这会导致在第一个读取请求返回响应之前,将上例中的(k,v1)写入节点B,因此第二个读取请求也会有更新的值。(感谢@Nadav Har'El指出这一点)
然而,这仍然不能保证很强的一致性。以下是一些明确的定义:
顺序/强一致性:任何执行的结果都是相同的,就像读和写是按某种顺序发生的,每个处理器的操作都是按其程序指定的顺序出现的(由Leslie Lamport定义)
单调读取一致性:一旦读取一个值,所有后续读取都将返回该值或更新的版本
顺序一致性要求客户端程序/读取器查看写入的最新值,因为在程序指令序列中,写入语句在读取语句之前执行。
jum4pzuy3#
对于读取和写入,ANY、ONE、TWO和THREE的一致性级别被视为弱,而QUORUM和ALL被视为强。
rmbxnbpk4#
对如果R+W一致性大于副本,那么您将始终获得一致的数据。100%一致性。但您必须权衡可用性以实现更高的一致性。
Cassandra有可调一致性的概念(基于查询设置一致性)。
fkaflof65#
实际上,我将此强一致性视为强读取一致性。它是会话性的,也称为单调阅读一致性。(参考@NadavHar'El答案)。
但它不是顺序一致性,因为Cassandra不完全支持锁、事务或串行化写入操作。只有轻量级事务支持写入操作的本地序列化和读取操作的序列化。
使事情易于理解。假设我们有三个节点——A、B、C,并将读取仲裁设置为3,将写入设置为1。
如果只有一个客户机,它会写入任何节点-A。
B和C可能不同步。(最终他们会——最终的一致性)
但是当客户端再次读取时,它要求客户端至少获得三个节点的响应,并且通过比较最新的时间戳,我们将使用A的记录。这是单调读取一致性
但是,如果有两个客户机尝试同时更新记录,或者他们尝试先读取值,然后同时重写(例如,将列增加100):客户机C1和客户机C2都将当前列值读取为10,并且都决定将其增加100:而C1只需将110写入一个节点,客户端C2也会这样做,任何节点上的最终结果最多只能为110
然后我们在这些操作中损失了100次(丢失更新)。它是由竞争条件或并发问题引起的问题。它必须通过序列化操作和使用任何形式的锁来修复,就像其他SQL DB实现事务一样。
我知道Cassandra现在有了新的柜台栏,这可能会解决这个问题,但就整个交易而言,它仍然是有限的。而且Cassandra也不应该是事务性的,因为它是NoSQL数据库,它牺牲了可用性的一致性