了解Cassandra的存储开销

Gio*_*tta 6 cql cassandra cql3 cassandra-2.0

我一直在阅读Cassandra文档的这一部分,发现以下有点令人费解:

确定列开销:

regular_total_column_size = column_name_size + column_value_size + 15

counter - expiring_total_column_size = column_name_size + column_value_size + 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)
);
Run Code Online (Sandbox Code Playgroud)

是每一行将包含列名,如琴弦的元数据report_date,start_date,end_date,等及其类型与数据一起.但是,我不清楚表中的每一行可以有不同的列名是什么意思.这听起来不对我,因为上面的架构是完全静态的,即如果我尝试编写,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
Run Code Online (Sandbox Code Playgroud)

现在,在我看来,在给定此表模式的情况下,列名称是固定的,因此不需要每行存储元数据.我猜测文档中的措辞是否过时(它与Cassandra 1.2相同)或者我在这里误解了一些核心概念.

任何人都可以澄清一下吗?一句话:我是否要担心列名称的长度?

我们一直在打它的安全和使用单个字符的名称在可能的情况(所以上面列实际上是i,r,s,dr,ds,de,sd,...),但它是如此非人可读取,然后是混乱的工作.

Rus*_*ssS 9

找出这种情况下发生的事情的最简单方法是检查数据的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]
 }
 ]
Run Code Online (Sandbox Code Playgroud)

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

虽然剩下的东西确实有列名,但是这需要对行进行部分更新,以便可以保存它而不需要其余的行信息.您可以想象对行中单个列字段的更新,以指示哪个字段是C*当前使用列名称,但是有票据将此更改为更小的表示. 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 
Run Code Online (Sandbox Code Playgroud)