使用包含单行分区的 Cassandra 表是一种不好的做法吗?

Car*_*ila 6 primary-key cassandra partition

假设我有一张这样的桌子

CREATE TABLE request(
  transaction_id text,
  request_date timestamp,
  data text, 
  PRIMARY KEY (transaction_id)
);
Run Code Online (Sandbox Code Playgroud)

transaction_id 是唯一的,因此据我了解此表中的每个分区只有一行,我不确定这种情况是否会导致操作系统中的性能问题,也许是因为 Cassandra 为每个分区创建一个文件,导致大量文件来管理其托管操作系统,请注意,我不确定 Cassandra 如何为其表创建文件。

在这种情况下,我可以通过其 transaction_id 找到请求,例如

select data from request where transaction_id = 'abc';

如果前面的假设是正确的,那么下一个可能会采用不同的方法?

CREATE TABLE request( 
  the_date date, 
  transaction_id text, 
  request_date timestamp, 
  data text, 
  PRIMARY KEY ((the_date), transaction_id)
);
Run Code Online (Sandbox Code Playgroud)

字段the_date每隔一天都会更改,因此表中的分区将为每一天创建。

在这种情况下,我必须让the_date数据始终可供客户端使用,以便我可以使用下一个查询找到请求

select data from request where the_date = '2020-09-23' and transaction_id = 'abc';

预先感谢您的帮助!

Ale*_*Ott 6

Cassandra 不会为每个分区创建单独的文件。一个SSTable文件可能包含多个分区。仅包含一行的分区通常称为“瘦行” - 它们并不是很糟糕,但可能会导致一些性能问题:

  • 要访问此类分区,您仍然需要读取包含压缩数据的块(默认情况下为 64Kb),需要解压缩才能读取该数据。如果您正在进行真正的随机访问,这些块将从文件缓存中丢弃,并且需要从磁盘重新读取。在这种情况下,减小块大小可能有用
  • 如果每个节点的每个表有很多这样的分区 - 这可能会大大增加布隆过滤器的大小,因为每个分区都有一个单独的条目。我看到一些客户为布隆过滤器分配了数十GB的内存,只是因为分区很薄

所以这实际上取决于数据量、访问模式等。它可能是好是坏,取决于这些因素。

如果您有可用的日期,并且希望将其用作部分分区键 - 这也可能是不可取的,因为如果您在那天写入和读取大量数据,那么只有某些节点会处理该负载 - 就是这样 -称为“热分区”。

当您从数据推断分区键时,您可以实现所谓的分桶。但这将取决于可用的数据。例如,如果您将日期 + 事务 ID 作为字符串,则可以将分区键创建为日期 + 该字符串的第一个字符 - 在这种情况下,您每天将有 N 个分区键,这些分区键分布在节点之间,从而消除了热分区问题。

请参阅DataStax 中有关该主题的相应最佳实践文档。