Плохая ли практика иметь таблицу Cassandra с разделами из одной строки?

#cassandra #primary-key #partition

#кассандра #первичный ключ #раздел

Вопрос:

Допустим, у меня есть такая таблица

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

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)
);
  

Поле the_date будет меняться каждый следующий день, поэтому разделы в таблице будут создаваться для каждого дня.

В этом сценарии мне нужно было бы, чтобы данные the_date всегда были доступны клиенту, чтобы я мог найти запрос с помощью следующего запроса

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

Заранее благодарю вас за вашу любезную помощь!

Ответ №1:

Cassandra не создает отдельный файл для каждого раздела. Один файл SSTable может содержать несколько разделов. Разделы, состоящие только из одной строки, часто называют «тощими строками» — они не очень плохие, но могут вызвать некоторые проблемы с производительностью:

  • для доступа к таким разделам вам все равно нужно прочитать блок со сжатыми данными (по умолчанию это 64 КБ), который необходимо распаковать, чтобы прочитать эти данные. Если вы выполняете действительно произвольный доступ, такие блоки будут удалены из файлового кэша и должны быть повторно прочитаны с диска. В этом случае, возможно, полезно уменьшить размер блока
  • если у вас много таких разделов на таблицу на узел — это может сильно увеличить размер фильтра Блума, потому что в каждом разделе есть отдельная запись. Я видел некоторых клиентов, у которых были десятки гигабайт памяти, выделенных для фильтра Блума только из-за узких разделов

так что это действительно зависит от объема данных, шаблонов доступа и т.д. Это может быть хорошо или плохо, зависит от этих факторов.

Если у вас есть доступная дата, и вы хотите использовать ее как ключ раздела части — это также может быть нежелательно, потому что, если вы записываете и читаете много данных в этот день, только некоторые узлы будут обрабатывать эту нагрузку — это так называемые «горячие разделы».

Вы можете реализовать так называемую группировку, когда вы выводите ключ раздела из данных. Но это будет зависеть от доступных данных. Например, если у вас есть дата идентификатор транзакции в виде строки, вы можете создать ключ раздела как дату 1-й символ этой строки — в этом случае у вас будет N ключей раздела в день, которые распределяются между узлами, устраняя проблему горячего раздела.

См. Соответствующий документ о рекомендациях от DataStax по этой теме.

Комментарии:

1. Спасибо @Alex Ott за все предоставленные отзывы, это было очень полезно, а также предоставленная ссылка. Я подробнее проанализирую свой вариант использования, чтобы решить, использовать или нет подход с узкими строками или лучше дополнить ключ раздела другим полем, принимая во внимание, что вы упомянули о проблеме с горячими разделами,

Ответ №2:

Позвольте мне не вдаваться в разные типы ключей, но позвольте мне упомянуть и кратко объяснить два ключа, которые вы используете в своем вопросе.

ПЕРВИЧНЫЙ КЛЮЧ

Строка ДОЛЖНА иметь уникальный первичный ключ (который идентифицирует строку как то, что она относится к равенству). Первичный ключ может быть набором столбцов (как в вашем втором примере с (the_date), transaction_id ) или просто одним столбцом (как в вашем первом примере с transaction_id ). Тем не менее, как уже упоминалось, важной частью является то, что для строки первичный ключ должен быть уникальным, чтобы идентифицировать строку.

КЛЮЧ РАЗДЕЛА

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

Cassandra использует хэшированное значение (комбинированных) значений ключей разделов, чтобы определить, на каком узле (узлах) хранятся данные (или извлекаются при запросе данных).

Итак, ответ на ваш вопрос заключается в том, что совершенно нормально использовать transaction_id как первичный ключ, так и ключ раздела. И это неплохая практика, это более или менее обычная практика, если у вас есть уникальный идентификатор в ваших данных, который может храниться в одной строке и удовлетворяет ваши потребности в отношении запросов.

Дополнительная информация:

Комментарии:

1. Спасибо @Philipp за уточнение вашего ответа. Я понимаю, что, учитывая, что первичный ключ состоит только из одного столбца, в данном случае transaction_id это уникальное поле также является основным и ключом раздела, поэтому каждый раздел в этой таблице будет состоять только из одной строки, и моя главная проблема заключалась в том, является ли это каким-то образом снижением производительности для Cassandra и / или системы.хостинг ОС, возможно, для обработки нескольких файлов или чего-то еще

2. Нет, в этом случае штрафа нет (как указано в ответе). Опять же, это обычная практика и система Cassandra.