关于Cassandra的(草率的,仍然令人困惑的)关于键,分区的文档

时间:2019-04-07 22:28:57

标签: cassandra

我有一个从Oracle移到Cassandra的高写入表。在Oracle中,PK是(int:clientId,id:UUID)。大约有100亿行。马上,我遇到了这个荒谬的警告:

https://docs.datastax.com/en/cql/3.3/cql/cql_using/useWhenIndex.html: “如果您在高基数列上创建一个索引,该索引具有许多不同的值,则字段之间的查询将导致许多搜索,结果很少。在包含十亿首歌曲的表中,按作者查找歌曲(该值通常对于每首歌曲来说都是唯一的),而不是由艺术家来决定,这可能会非常低效。以索引的形式手动维护表格而不是使用Cassandra内置索引可能会更有效。” >

这似乎不仅无法击败PK的高效查找,而且无法定义“查询字段之间”的含义以及内置索引,二级索引和primary_key + clustering之间的区别创建表命令中的用语。垃圾描述。这是2019年。现在不应该解决这个问题吗?

AFAIK仍然会引起误解:

CREATE TABLE dev.record (
clientid int,
id uuid,
version int,
payload text,
PRIMARY KEY (clientid, id, version)
) WITH CLUSTERING ORDER BY (id ASC, version DESC)

insert into record (id,version,clientid,payload) values
(d5ca94dd-1001-4c51-9854-554256a5b9f9,3,1001,'');
insert into record (id,version,clientid,payload) values
(d5ca94dd-1002-4c51-9854-554256a5b9e5,0,1002,'');

clientid上的令牌确实表明它们位于预期的不同分区中。

转向重点。如果在给定clientId的情况下查找单个行,并且UUID --- AND --- Cassandra允许您跳过指定clientId的操作,这样它就不知道要搜索哪个节点,那么请确保查找可能很慢。但事实并非如此:

select * from record where id=
  d5ca94dd-1002-4c51-9854-554256a5b9e5;
InvalidRequest: ... despite the performance unpredictability,
use ALLOW FILTERING"

同上,还有其他排除clientid的变体。因此,我们不应该得出结论,卡桑德拉(Cassandra)处理的基数高的表搜索返回“很少结果”就可以了吗?

1 个答案:

答案 0 :(得分:1)

任何需要读取数据库整个上下文的操作都无法正常进行,因为在id上进行扫描的情况就是如此,因为您的任何clientid分区键都可能包含一个。遍历每个主机可能存在的数千个sstable,遍历要检查的每个分区的每个分区将不起作用。如果在使用数据模型时遇到麻烦,并且在分区键和群集键之间没有完全区别,我建议您在设计架构之前逐步了解一些入门课程(例如,datastax学院),youtube视频或书籍等。这不是关系数据库,围绕数据而不是查询进行设计会给您带来麻烦。从oracle迁移时,您不要只是将表复制过来并移动数据,否则它将无法正常工作。

集群键是在磁盘上对分区数据进行排序的顺序,这就是它所谓的“内置索引”。每个sstable都有一个索引组件,其中包含该sstable的分区键位置。它还包括可以搜索的每64kb(至少默认情况下)每个分区的聚簇键索引。每个索引点之间存在的聚类关键字是未知的,因此都必须进行检查。很久以前,还保留了一个簇密钥的bloom过滤器,但这是一个非常罕见的用例,它可以帮助解决开销,并在2.0中将其删除。

二级索引很难很好地扩展,这就是有关基数的警告。我强烈建议您仅对数据进行规范化,而不使用任何形式的索引,因为在分布式系统上使用大型分散收集查询将具有可用性,并且性能问题。如果您确实需要它,请查看http://www.doanduyhai.com/blog/?p=13191尝试正确处理数据(我认为这不值得)。