“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))
);
问题是:什么是批次有用,只是报价中的第一个声明?在这种情况下,我如何确保对不同表的修改是同步的?
答案 0 :(得分:1)
在读/写上使用更高的一致性(即仲裁)可能会有所帮助,但表/分区之间始终存在不一致的可能性。
批处理语句将尝试确保批处理中的所有突变都发生或不发生。它并不能保证所有突变都会在瞬间发生(没有隔离,你可以在已经应用第一次突变的情况下进行读取但其他突变没有)。此外,批处理语句不会提供所有节点上所有数据的一致视图。对于可线性化的一致性,您应该考虑使用paxos(轻量级事务)进行条件更新,并尝试将需要线性化的内容限制为单个分区。