如何在Cassandra中为用户数据建模?
我们拥有与客户相关的各种数据和元数据,我们目前将这些数据和元数据保存在具有相同分区的单独表格中。聚类键。
这会导致来自不同表格(例如分析)的用户信息不足,有效地“加入”其分区键上的两个或更多Cassandra表。
从积极的方面来说,插入表格是独立完成的。
同时更新相同分区键但不同列的数据时是否存在竞争条件?或者在SSTables上优雅地合并增量?
是否有多个表具有相同的分区(和群集)键或反模式?
为了使这更具体,让我们说:
CREATE TABLE example (
pk text PRIMARY KEY
col_a text
col_b text
)
假设对于给定的分区键(pk
),最初col_a
和col_b
都有一些值(即非空)。并且两个并发插入更新它们中的每一个。那里有没有竞争条件?丢失了两个更新中的一个,尽管写入了不同的列?
答案 0 :(得分:1)
写冲突是您不必担心的事情。所有INSERTS / UPDATES / DELETES都是Cassandra的Upserts。 Cassandra的所有内容都是以列为基础的。
Cassandra使用最后写赢策略来管理冲突。正如您在下面的示例中所看到的,无论何时更改值,都会更新与该列关联的时间戳。由于您正在运行并发更新,并且一个线程将更新 col_a ,另一个线程将更新 col_b 。
初始插入
cqlsh:test_keyspace> insert into race_condition_test (pk, col_a, col_b ) VALUES ( '1', 'deckard', 'Blade Runner');
cqlsh:test_keyspace> select * from race_condition_test ;
pk | col_a | col_b
----+---------+--------------
1 | deckard | Blade Runner
(1 rows)
时间戳在初始插入中是相同的
cqlsh:test_keyspace> select pk, col_a, writetime(col_a), col_b, writetime(col_b) from race_condition_test ;
pk | col_a | writetime(col_a) | col_b | writetime(col_b)
----+---------+------------------+--------------+------------------
1 | Deckard | 1526916970412357 | Blade Runner | 1526916970412357
(1 rows)
一旦 col_b 被提升,它的时间戳会发生变化以反映变化。
cqlsh:test_keyspace> insert into race_condition_test (pk, col_b ) VALUES ( '1', 'Rick');
cqlsh:test_keyspace> select pk, col_a, writetime(col_a), col_b, writetime(col_b) from race_condition_test ;
pk | col_a | writetime(col_a) | col_b | writetime(col_b)
----+---------+------------------+-------+------------------
1 | Deckard | 1526916970412357 | Rick | 1526917272641682
(1 rows)
col_a 更新后,它的时间戳也更新为新值
cqlsh:test_keyspace> insert into race_condition_test (pk, col_a) VALUES ( '1', 'bounty hunter');
cqlsh:test_keyspace> select pk, col_a, writetime(col_a), col_b, writetime(col_b) from race_condition_test ;
pk | col_a | writetime(col_a) | col_b | writetime(col_b)
----+---------------+------------------+-------+------------------
1 | bounty hunter | 1526917323082217 | Rick | 1526917272641682
(1 rows)
我的建议是您使用一个表来满足您的查询需求。如果您需要通过 pk 进行查询,请创建一个包含所需列的单个表。这样,您将拥有一个可以有效回读的宽行,作为单个查询的一部分。
您在选项2中描述的数据模型有点关系,并不适合Cassandra。你不能在cassandra中本地执行连接,你应该避免在客户端执行连接。
数据模式规则:
规则1:在整个群集中均匀分布数据 您需要创建一个分区键,以确保数据在整个群集中均匀分布,并且您没有任何热点。
规则2:最小化分区数量 每个分区可能驻留在不同的节点中,因此您应该尝试创建一个场景,为了性能,您的查询理想地只针对一个节点。
规则3:围绕您的查询建模
如果您想了解更多关于此信息,请参阅此数据传输页面: Basic Rules of Cassandra Data Modeling