Понимание накладных расходов на хранилище Cassandra

Я читал этот раздел документов Cassandra и нашел следующее немного озадачивающим:

Определите накладные расходы столбца:

регулярный_общий_размер_столбца = размер_имя_столбца + размер_значения_столбца + 15

счетчик - 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)
);

заключается в том, что каждая строка будет содержать метаданные для имен столбцов, например, строки 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

Теперь мне кажется, что имена столбцов фиксированы с учетом этой схемы таблицы, и поэтому метаданные не должны храниться для каждой строки. Я предполагаю, что либо формулировки в документации устарели (это то же самое, что и Cassandra 1.2), либо я неправильно понимаю некоторые основные концепции, которые здесь работают.

Кто-нибудь может уточнить? Итог: мне нужно беспокоиться о длине имен моих столбцов или нет?

Мы играли осторожно и использовали односимвольные имена, где это было возможно (так что приведенные выше столбцы на самом деле были бы i, r, s, dr, ds, de, sd, ...), но это так нечеловечески нечитабельно и может сбивать с толку работать с.


person Giovanni Botta    schedule 30.05.2014    source источник
comment
На каждый столбец в Cassandra приходится 15 байт служебных данных. - это подразумевается под строкой, я прав? Итак, в каждой строке есть 15 байт накладных расходов на столбец, верно?   -  person Kozuch    schedule 05.11.2016
comment
@Kozuch да, эта часть ясна.   -  person Giovanni Botta    schedule 09.11.2016
comment
Я просто хотел бы добавить, что теперь, начиная с версии 3.x Cassandra, мы больше не наказываемся за использование длинных имен столбцов! Однако это все еще может быть проблемой для Scylla или других пользователей, которые все еще используют более старые версии формата файлов SSTable.   -  person imagnon    schedule 05.02.2019


Ответы (1)


Самый простой способ выяснить, что происходит в подобных ситуациях, - это проверить представление ваших данных в 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

Чтобы создать это

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 
person RussS    schedule 30.05.2014
comment
Сжатие на диске, очевидно, сотрет большую часть потерь из-за дублирования имен столбцов, поэтому это не имеет большого значения для дискового пространства, но для чтения это немного большая проблема. - person RussS; 30.05.2014
comment
что ты имеешь ввиду под чтением? Как я могу узнать фактический размер сжатых данных на диске? - person Giovanni Botta; 30.05.2014
comment
Когда данные фактически считываются с диска, они не будут сжаты, поэтому в вашей памяти на сервере будет указано полное имя столбца. Потраченная впустую память. Чтобы узнать размер на диске, вы можете проверить статус nodetool или просто подсчитать размер всех файлов в каталоге данных - снимки - person RussS; 30.05.2014