使用一行分区的cassandra表是一种不好的做法吗?

v8wbuo2f  于 2021-06-09  发布在  Cassandra
关注(0)|答案(2)|浏览(332)

假设我有一张这样的table

CREATE TABLE request(
  transaction_id text,
  request_date timestamp,
  data text, 
  PRIMARY KEY (transaction_id)
);

事务id是唯一的,所以据我所知,这个表中的每个分区只有一行,我不确定这种情况是否会导致操作系统出现性能问题,可能是因为cassandra为每个分区创建了一个文件,导致许多文件要为其宿主操作系统管理,作为一个注解,我不确定cassandra是如何为它的表创建文件的。
在这个场景中,我可以通过事务id查找请求,如 select data from request where transaction_id = ''; 如果前面的假设是正确的,那么下一种方法可能是另一种方法?

CREATE TABLE request( 
  the_date date, 
  transaction_id text, 
  request_date timestamp, 
  data text, 
  PRIMARY KEY ((the_date), transaction_id)
);

_date字段将在第二天更改,因此表中的分区将为每天创建。
在这种情况下,我必须让客户端始终可以使用\u日期数据,这样我就可以使用下一个查询找到请求 select data from request where the_date = '2020-09-23' and transaction_id = ''; 提前感谢您的帮助!

mzmfm0qo

mzmfm0qo1#

cassandra不会为每个分区创建单独的文件。一个sstable文件可以包含多个分区。仅由一行组成的分区通常称为“瘦行”——它们不是很差,但可能会导致一些性能问题:
要访问这样的分区,您仍然需要读取一个包含压缩数据的块(默认值为64kb),该块需要解压缩才能读取该数据。如果你做的是真正的随机访问,这样的块会从文件缓存中被丢弃,需要从磁盘中重新读取。在这种情况下,减小块大小可能是有用的
如果在每个节点的每个表中有很多这样的分区,这可能会大大增加bloom过滤器的大小,因为每个分区中都有一个单独的条目。我看到一些客户仅仅因为分区太窄,才为bloomfilter分配了几十GB的内存
因此,这实际上取决于数据量、访问模式等,它的好坏取决于这些因素。
如果您有可用的日期,并希望将其用作部分分区键-这可能也不可取,因为如果您在当天写入和读取大量数据,那么只有一些节点将处理该负载-这就是所谓的“热分区”。
当您从数据中推断分区键时,可以实现所谓的bucketing。但这将取决于现有的数据。例如,如果将日期+事务id作为字符串,则可以将分区键创建为该字符串的日期+第一个字符—在这种情况下,每天将有n个分区键分布在节点之间,从而消除了热分区问题。
有关该主题,请参阅datastax中相应的最佳实践文档。

y0u0uwnf

y0u0uwnf2#

让我不谈不同类型的钥匙,但让我提一下并简短地解释一下你在提问中使用的两个钥匙。
主键
一行必须有一个唯一的主键(该主键将该行标识为与相等相关的行)。主键可以是列的集合(如第二个示例中的 (the_date), transaction_id )或者仅仅是一列(在您的第一个示例中使用 transaction_id ). 尽管如此,如前所述,重要的一点是,对于一行,主键必须是唯一的,以标识该行。
分区键
分区键实际上是基于主键确定的。您可以使用复合分区键(您在第二个示例中使用了该键的语法,以强制 (the_date) 要成为分区键,实际上不需要这样做,因为默认情况下它是主键的第一列)。
cassandra使用(组合的)分区键值的散列值来确定在哪个节点上存储(或在请求数据时从哪个节点检索)数据。
所以你的问题的答案是,使用 transaction_id 作为主键和分区键。这是一个不错的做法,如果您的数据中有一个唯一的标识符,它可以存储在一行中并满足您关于请求的需求,那么这或多或少是一种非常常见的做法。
更多信息:
哈希解释:一致哈希
定义基本主键
定义多列分区键

相关问题