Java Cassandra=单个节点上单行上列更新的原子性/隔离性?

Java Cassandra=单个节点上单行上列更新的原子性/隔离性?,java,concurrency,cassandra,Java,Concurrency,Cassandra,很抱歉再次向卡桑德拉询问一些事情,我非常感谢你的告别: 我读过这篇文章,完全迷路了,我想知道: 在Cassandra中,一行键在一个单节点上的写入(在同一个COLUMNFAMILY中有许多列要更新,使用batch_mutate)不是与同一节点上的读取隔离的,这是真的吗 到同一行键的列,以确保读取未准备好“部分更改的数据”?例如: Current Status: [KEY=1 , ColumnName=A with Value=A , ColumnName=B with Value=B]

很抱歉再次向卡桑德拉询问一些事情,我非常感谢你的告别:

我读过这篇文章,完全迷路了,我想知道:

在Cassandra中,一行键在一个单节点上的写入(在同一个COLUMNFAMILY中有许多列要更新,使用batch_mutate)不是与同一节点上的读取隔离的,这是真的吗 到同一行键的列,以确保读取未准备好“部分更改的数据”?例如:

Current Status:     [KEY=1 , ColumnName=A with Value=A , ColumnName=B with Value=B] on Node 1
Client A => Writes: [KEY=1 , ColumnName=A with Value=C , ColumnName=B with Value=D] on Node 1
原子性:

根据cassandra文档,写入对于执行写入的客户端来说是原子的: 上面的写操作要么完全成功,要么完全失败!? 差不多
[KEY=1,ColumnName=A,Value=C,ColumnName=B,Value=B]
(=有一半的列更新成功, 但另一半尚未应用/失败(D)是否可能是发生错误时写入的结果? 这是正确的吗

隔离:

对于在同一节点上读取同一行的人来说,即使在一个节点上(这里是节点1),写操作也不是孤立的,这是真的吗? 如上所述,如果客户机A更新了要更改的一半列(此处ColumnName=A,值=C), 连接到节点1的另一个客户机B真的会看到记录为

Client B => Reads:  [KEY=1 , ColumnName=A with Value=C , ColumnName=B with Value=B] on Node 1
几毫秒后,再次读取它会看到什么

Client B => Reads:  [KEY=1 , ColumnName=A with Value=C , ColumnName=B with Value=D] on Node 1

为什么更新不是基于每个节点隔离的

对mee来说,这似乎很简单,也很便宜? 为什么节点1上没有内存锁,KEY=1当前处于更新过程中,因此读取可以等待完成写入? (这将只是一个非常小的开销,因为锁本地保存在Node1上的内存中,并且可以配置为读取客户端可以接受“锁”或只是读取脏值? 因此,这类似于“可配置隔离级别”?如果我需要高性能,我会忽略锁/禁用它们,如果我需要基于每个节点的隔离,并接受 负面性能影响,然后我等待内存中的锁(在节点1上)被释放?(注意,我不是在谈论压缩/分布式锁,而是在单个机器上保证每行密钥隔离写入的锁!)

或者,在“更改现有列”和“追加/添加列”的操作方面,隔离是否有所不同。因此,chaing columnsn(如上面的示例所示)是隔离的但添加新列不是孤立的。从我的观点来看,更改现有列必须是孤立的/原子的…添加列不需要太多的隔离

我为什么要问的问题是:如果像上面提到的那样的事情会发生,读起来真的是部分改变了的记录,那是什么 然后,用例对于nosql/cassandra是合法的?这意味着任何类型的随机列数据都可以以每行为单位作为columsn存在 可能处于任何随机读/写状态?我几乎不知道有任何数据和用例允许在每行上“任意”更改 基础

非常感谢!!! 詹斯说:

“作为一种特殊情况,针对 单个键是原子键,但不是原子键 隔离。在 这样的突变可能会导致部分基因突变 在他们看到整件事之前写信

我不确定原因,但我怀疑所需的锁定过于粗糙,会对性能造成太大影响。请记住,在大多数情况下,所有更新都会先写入提交日志,然后立即写入磁盘上的SSTables(除非设置了非常低的一致性级别),因此纯粹基于内存的锁不一定有用

一些不重要的用例:

  • 数据写入、可能添加到但未更新的系统
  • 已知读与写在时间上分离的系统
  • 列的值不紧密耦合的系统(如果可以将任何值聚合为单个列值,则可以安排这种情况)
  • 数据一致性并不重要,并且用户经常刷新其视图的系统
为什么节点1上没有内存锁,KEY=1当前处于更新过程中,因此读取可以等待完成写入

因为Cassandra非常强调性能的非规范化(分布式联接不可伸缩,是的,我在这里正确地使用了“伸缩”——分布式联接在集群中的机器数量上是O(N)),所以将卷写入“物化视图”“行可能非常高。因此,行级锁定会对许多实际工作负载引入不可接受的争用。

来自IRC日志的聊天: itissid: 好吧,这么说 这是一个特例 但是如果我们做一个正常的写入,它们是孤立的吗

托布斯: 柱是隔离单元 上面没有什么是孤立的(尚未)

itissid: 好的,明白了

托布斯: 需要将写操作隔离到一行

漂移X:
这是为1.1完成的

非常感谢jonathan。我绝对同意你关于非规范化和物化视图的观点。但是没有一行被“原子化”编写(在java意义上)以便其他人(!)看到它是否更新(不是中间的状态)=隔离,由于数据损坏问题,很多用例都不可能实现。如果您真的能够确认,就像第一句话所问的那样:在Cassandra中,一行键在一个单节点上写入(在同一个COLUMNFAMILY中有许多列要更新,使用batch_mutate)不是孤立于同一节点上对同一行键列的读取吗?谢谢!只是一个想法/建议“可调行级锁定”:Cassandra很棒。但是对于许多用例,“启用/禁用”行级锁定将很重要。想想(现实世界)实体,如“人员、产品…”或索引:它们的所有属性/数据都“相互依赖”。不一致的视图不适用