>用户数据的单个表,按用户ID分区,不同的组件读/写到不同的列?
>具有相同密钥结构的多个表(每个组件一个),偶尔需要在分区键上“连接”在一起?
我们拥有与客户相关的各种数据和元数据,我们目前将这些数据和元数据保存在具有相同分区的单独表格中.群集密钥.
这导致来自不同表(例如,分析)的用户的信息位,在其分区键上有效地“加入”两个或更多个Cassandra表.
从积极的方面来说,插入表是独立完成的.
在同一分区键下同时更新数据但不同列时是否存在竞争条件?或者在SSTables上优雅地合并了三角洲?
是否有多个表具有相同的分区(和聚类)键或反模式?
为了使这个更具体,让我们说:
CREATE TABLE example ( pk text PRIMARY KEY col_a text col_b text )
假设对于给定的分区密钥(pk),最初col_a和col_b都具有某个值(即,不为空).并且两个并发插入更新它们中的每一个.那里有没有竞争条件?尽管写入了不同的专栏,但是丢失了两个更新中的一个?
解决方法
写冲突是你不应该担心的.所有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,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,'Rick'); cqlsh:test_keyspace> select pk,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,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