假设我有一张100台机器上有100亿行的桌子.该表具有以下 struct :

PK1 PK2 PK3 V1 V2

其中PK表示分区键,V表示值.在上面的例子中,分区键由3列组成.

Scylla要求您在WHERE子句中指定分区键的所有列.

如果要在只指定部分列的情况下执行查询,则会收到警告,因为这需要进行完整的表扫描:

SELECT V1 & V2 FROM table WHERE PK1 = X & PK2 = Y

在上面的查询中,我们只指定了3列中的2列.假设查询匹配1 billion out of 10 billion rows——考虑这个查询的成本/性能,什么是一个好的心智模型?

我的假设是成本很高:这相当于对数据集执行1)亿个单独的查询,因为行存储到磁盘的方式在行之间没有逻辑关联,因为每行都有不同的分区键(高基数)2),以便Scylla确定哪些行与查询匹配,它必须扫描所有1)亿行(即使结果集仅匹配10亿行)

假设一台服务器每秒可以处理10万个事务(在ScyllaDB个人公布的范围内),并且数据驻留在ScyllaDB台服务器上,处理此查询的(估计)时间可以计算为:10万*ScyllaDB=ScyllaDB0万个查询/秒.ScyllaDB亿除以10米等于ScyllaDB0秒.因此,集群大约需要ScyllaDB0秒来处理查询(消耗所有集群资源).

对吗?或者,在我的心智模型中,Scylla如何处理这样的查询,是否存在任何缺陷?

谢谢

推荐答案

正如你自己所建议的,Scylla(我在回答中所说的一切也适用于Cassandra)用完整的分区键对分区进行散列——包含三列.ּ所以锡拉没有有效的方法来扫描only个匹配的分区.它必须扫描所有分区,并判断每个分区的分区密钥是否与请求匹配.

然而,这并不意味着它像"对数据执行100亿个单独的查询"那样效率低下.扫描100亿个分区通常(当每行的数据本身不是很大时)比执行100亿个随机访问读取(每个读取一个分区)要高效得多.随机存取读取需要做很多工作——锡拉需要到达协调器,然后协调器将其发送给副本,每个副本需要在其一个磁盘数据文件(通常是多个文件)中找到特定位置,通常需要从磁盘过度读取(如磁盘和压缩对齐所需),等等.与此相比,这是一种扫描——它可以从磁盘读取按令牌(分区键散列)排序的长连续数据带,并可以相当快地返回许多行,而I/O操作更少,CPU工作更少.

因此,如果您的示例设置可以对每个 node 进行https://www.scylladb.com/2019/12/12/how-scylla-scaled-to-one-billion-rows-a-second/000次随机访问读取,那么在扫描期间,它可能每秒读取的行数远远超过https://www.scylladb.com/2019/12/12/how-scylla-scaled-to-one-billion-rows-a-second/000行.我不知道该给出哪个确切数字,但博客文章https://www.scylladb.com/2019/12/12/how-scylla-scaled-to-one-billion-rows-a-second/ we(完全披露:我是一名锡拉开发人员)展示了一个扫描10亿(!)的示例用例每秒只有83个 node 的行数——即每个 node 每秒有1200万行,而不是您估计的https://www.scylladb.com/2019/12/12/how-scylla-scaled-to-one-billion-rows-a-second/000行.因此,您的示例用例可能只需8.3秒,而不是您计算的https://www.scylladb.com/2019/12/12/how-scylla-scaled-to-one-billion-rows-a-second/0秒.

最后,请不要忘记(在前面提到的博客文章中也提到了这一点),如果你做了一个大的扫描,你应该显式地parallelize,也就是说,将令牌范围分成几部分,然后并行扫描.首先,显然没有一个客户端能够处理每秒扫描10亿个分区的结果,所以这种并行化或多或少是不可避免的.其次,扫描按分区顺序返回分区,分区(正如我上面解释的)连续地位于各个副本上——这对峰值吞吐量很好,但也意味着在扫描期间的任何时候只有一个 node (甚至一个CPU)处于活动状态.因此,将扫描分为几部分并并行进行非常重要.我们也有一篇关于平行扫描的重要性以及如何做的博客文章:https://www.scylladb.com/2017/03/28/parallel-efficient-full-table-scan-scylla/.

Database相关问答推荐

数据库设计 - 类别(categories)和子类别(sub-categories)

如何开始使用 SQLCipher for android?

使用 Java 对 mysql 数据库进行简单备份和恢复

如果限制在本地机器上,最好使用 R 和 SQL

当可伸缩性无关紧要时,NoSQL 与 SQL

保存图像:文件还是 blob?

从 XML 读取数据

在 MySQL 中实现一对一关系时确定外键

存储并仍然索引加密客户数据的最佳方式是什么?

从 postgresql 转储文件填充 MySQL 数据库

表模块与域模型

A QuerySet 按聚合字段值

数据库 - 设计 Events事件表

Sqlite 判断表是否为空

cURL 和 PHP 显示1

存储信用卡号 - PCI?

App=EntityFramework 在 Sql 连接字符串中有什么作用?

使用带有联合和 CLOB 字段的 Select 时出现错误 ORA-00932

Oracle order NULL LAST 默认

使用命令行在 Mysql 中导入压缩文件