【问题标题】:Regarding Cassandra's (sloppy, still confusing) documentation on keys, partitions关于 Cassandra 关于键、分区的文档(草率,仍然令人困惑)
【发布时间】:2019-08-29 01:26:41
【问题描述】:

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

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

这似乎不仅破坏了 PK 的有效查找,它还没有定义“字段之间查询”的含义以及内置索引、二级索引和主键+集群之间的区别创建表命令中的子短语。垃圾描述。现在是 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 可以很好地处理返回“很少结果”的高基数表搜索吗?

【问题讨论】:

  • 与文档似乎暗示的相反——或者不是因为它写得如此糟糕——这个选择非常有效:select * from dev.record其中 clientId=1001 和 id = 5bcd...ff 和 version = 0 就可以了。如果您尝试不带 clientId 的选择,则会警告您需要过滤子句,结果可能会很慢。因此,无论如何,您甚至都不会意外遇到错误的查询

标签: cassandra


【解决方案1】:

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

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

二级索引很难很好地扩展,这是关于基数的警告的来源,我强烈建议只对数据进行非规范化,不要以任何形式使用索引,因为在分布式系统中使用大型分散聚集查询将具有可用性和性能问题。如果您真的需要它,请查看 http://www.doanduyhai.com/blog/?p=13191 以尝试正确获取数据(在我看来不值得)。

【讨论】:

  • 我与 Oracle 合作超过 25 年,在过去 3 年开始与 Cassandra 合作。我学到了很多关于异同的知识(而且还有很多)。有问题可以线下联系我讨论。 Cassandra 索引只不过是它下面的表,这就是令人困惑的部分的来源。它不是一个高效的 b 树对象,因此如果您以这些术语思考,则更难理解。
  • @Chris - 非常感谢您花时间回复。但是你没有回答问题。您写“...扫描 id,因为您的任何 clientid 分区键都可能包含一个。” PK 是 (clientid, id, version) 例如由 clientId 分区到一个节点,然后 (id, version) 准确地命名该行。此外,我没有对select 不允许您在不明确添加过滤的情况下进行错误查询的事实提出任何反对意见。所以我的帖子结尾没有回答。文档很烂。
  • 分区键clientid 集群键(id, version)。当未指定时,主键的第一部分隐含地是分区键 - 例如((clientid), id, version) 分区键用于分割数据并且基本上是随机分布的。因此,您必须检查集群中的每个节点和每个分区,以找到单个 id 的任何值。它不能(也不应该)这样做——即使你可以通过过滤来强制它。
猜你喜欢
  • 2016-11-11
  • 1970-01-01
  • 1970-01-01
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多