了解 Cassandra 的存储开销

2024-01-19

我一直在阅读本节 http://www.datastax.com/documentation/cassandra/2.0/cassandra/architecture/architecturePlanningUserData_t.html查阅 Cassandra 文档,发现以下内容有点令人费解:

确定柱开销:

常规总列大小 = 列名称大小 + 列值大小 + 15

计数器 - 到期总列大小 = 列名称大小 + 列值大小 + 23

Cassandra 中的每一列都会产生 15 个字节的开销。由于表中的每一行可以具有不同的列名称以及不同的列数,因此为每一列存储元数据。对于计数器列和过期列,您应该添加额外的 8 个字节(总共 23 个字节)。

我对 CQL3 定义的模式解释上述内容的方式,例如:

CREATE TABLE mykeyspace.mytable(
  id text,
  report_id text,
  subset_id text,
  report_date timestamp,
  start_date timestamp,
  end_date timestamp,
  subset_descr text,
  x int,
  y double,
  z int,
  PRIMARY KEY (id, report_id, subset_id)
);

是每一行将包含列名称的元数据,例如字符串report_date, start_date, end_date等及其类型以及数据。但是,我不清楚表中的每一行可以有不同的列名意味着什么。鉴于上面的模式完全是这样,这对我来说听起来是错误的static,也就是说,如果我尝试编写以下内容,Cassandra 2.0 肯定会抱怨:

INSERT INTO mykeyspace.mytable (id, report_id , subset_id, x, y, z, w) 
VALUES ( 'asd','qwe','rty',100,1.234,12, 123.123);

Bad Request: Unknown identifier w

现在在我看来,给定这个表模式,列名是固定的,因此元数据不需要每行存储。我猜测要么文档中的措辞已经过时(与 Ca​​ssandra 1.2 相同),要么我误解了这里工作的一些核心概念。

有人能澄清一下吗?底线:我是否需要担心列名称的长度?

我们一直在谨慎行事,并尽可能使用单个字符名称(因此上面的列实际上是i, r, s, dr, ds, de, sd,...),但它是如此非人类不可读,并且使用起来可能会令人困惑。


要弄清楚在这种情况下发生了什么,最简单的方法是检查数据的 sstable2json (cassandra/bin) 表示形式。这将向您显示最终实际保存在磁盘上的内容。

这是适合您情况的示例

 [
 {"key": "4b6579","columns": [
       ["rid1:ssid1:","",1401469033325000],
       ["rid1:ssid1:end_date","2004-10-03 00:00:00-0700",1401469033325000],
       ["rid1:ssid1:report_date","2004-10-03 00:00:00-0700",1401469033325000],
       ["rid1:ssid1:start_date","2004-10-03 00:00:00-0700",1401469033325000], 
       ["rid1:ssid1:subset_descr","descr",1401469033325000],
       ["rid1:ssid1:x","1",1401469033325000], 
       ["rid1:ssid1:y","5.5",1401469033325000],
       ["rid1:ssid1:z","1",1401469033325000],
       ["rid2:ssid2:","",1401469938599000],
       ["rid2:ssid2:end_date", "2004-10-03 00:00:00-0700",1401469938599000],
       ["rid2:ssid2:report_date","2004-10-03 00:00:00-0700",1401469938599000],
       ["rid2:ssid2:start_date","2004-10-03 00:00:00-0700",1401469938599000], 
       ["rid2:ssid2:subset_descr","descr",1401469938599000],
       ["rid2:ssid2:x","1",1401469938599000],
       ["rid2:ssid2:y","5.5",1401469938599000],
       ["rid2:ssid2:z","1",1401469938599000]
 }
 ]

正如您在上面所看到的,分区键的值每个分区(每个 sstable)保存一次,在这种情况下,列名根本不重要,因为它是隐式给定表的。集群列的列名也不存在,因为使用 C* 时,如果不指定键的所有部分,则不允许插入。

剩下的确实有列名,这是在对行进行部分更新时需要的,这样就可以在没有其余行信息的情况下保存它。您可以想象对一行中的单个列字段进行更新,以指示这是 C* 的哪个字段当前使用列名称,但有一些票证可以将其更改为较小的表示形式。https://issues.apache.org/jira/browse/CASSANDRA-4175 https://issues.apache.org/jira/browse/CASSANDRA-4175

为了生成这个

cqlsh
CREATE TABLE mykeyspace.mytable(   id text,   report_id text,   subset_id text,   report_date timestamp,   start_date timestamp,   end_date timestamp,   subset_descr text,   x int,   y double,   z int,   PRIMARY KEY (id, report_id, subset_id) );
INSERT INTO mykeyspace.mytable (id, report_id , subset_id , report_date , start_date , end_date , subset_descr ,x, y, z) VALUES ( 'Key', 'rid1','ssid1', '2004-10-03','2004-10-03','2004-10-03','descr',1,5.5,1);
INSERT INTO mykeyspace.mytable (id, report_id , subset_id , report_date , start_date , end_date , subset_descr ,x, y, z) VALUES ( 'Key', 'rid2','ssid2', '2004-10-03','2004-10-03','2004-10-03','descr',1,5.5,1);
exit;
nodetool flush
bin/sstable2json $DATA_DIR/mytable/mykeyspace-mytable-jb-1-Data.db 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解 Cassandra 的存储开销 的相关文章

随机推荐