`BatchStatement`偶尔会使数据不同步

时间:2017-09-21 21:40:46

标签: c# cassandra datastax

“Cassandra:The Definitive Guide,2nd Edition”说:

  

Cassandra的批次非常适合制作等用例   对单个分区进行多次更新,或者保留多个表   同步。一个很好的例子是对非规范化表进行修改   为不同的访问模式存储相同的数据。

上面的最后一条语句适用于以下尝试,其中所有Save...是不同表的insert语句

var bLogged = new BatchStatement();
var now = DateTimeOffset.UtcNow;
var uuidNow = TimeUuid.NewId(now);

bLogged.Add(SaveMods.Bind(id, uuidNow, data1));                      // 1
bLogged.Add(SaveMoreMods.Bind(id, uuidNow, data2));                  // 2
bLogged.Add(SaveActivity.Bind(now.ToString("yyyy-MM-dd"), id, now)); // 3

await GetSession().ExecuteAsync(bLogged);

我们将重点关注语句1和2(第3个只是表示批处理中还有一个语句)。

语句1写入由id分区的table1,其中uuidNow是群集密钥desc。 语句2仅写入由id分区的table2,因此它是同一id的table1的提示

table2没有table1提示的意义上,这两个表不同步的次数超过了同步。在几毫秒内它将​​是后面的一个或两个mod

虽然在网上寻求最大分辨率的建议而不是所有批次,这促使我的解决方案消除了所有不匹配:

await Task.WhenAll(
    GetSession().ExecuteAsync(SaveMods.Bind(id, uuidNow, data1)),
    GetSession().ExecuteAsync(SaveMoreMods.Bind(id, uuidNow, data2)),
    GetSession().ExecuteAsync(SaveActivity.Bind(now.ToString("yyyy-MM-dd"), id, now))
);

问题是:什么是批次有用,只是报价中的第一个声明?在这种情况下,我如何确保对不同表的修改是同步的?

1 个答案:

答案 0 :(得分:1)

在读/写上使用更高的一致性(即仲裁)可能会有所帮助,但表/分区之间始终存在不一致的可能性。

批处理语句将尝试确保批处理中的所有突变都发生或不发生。它并不能保证所有突变都会在瞬间发生(没有隔离,你可以在已经应用第一次突变的情况下进行读取但其他突变没有)。此外,批处理语句不会提供所有节点上所有数据的一致视图。对于可线性化的一致性,您应该考虑使用paxos(轻量级事务)进行条件更新,并尝试将需要线性化的内容限制为单个分区。