Подтвердить что ты не робот

Как работают вторичные индексы в Кассандре?

Предположим, что у меня есть семейство столбцов:

CREATE TABLE update_audit (
  scopeid bigint,
  formid bigint,
  time timestamp,
  record_link_id bigint,
  ipaddress text,
  user_zuid bigint,
  value text,
  PRIMARY KEY ((scopeid, formid), time)
  ) WITH CLUSTERING ORDER BY (time DESC)

С двумя вторичными индексами, где record_link_id - столбец с высокой производительностью:

CREATE INDEX update_audit_id_idx ON update_audit (record_link_id);

CREATE INDEX update_audit_user_zuid_idx ON update_audit (user_zuid);

Согласно моим знаниям, Cassandra создаст две скрытые семейства столбцов, например:

CREATE TABLE update_audit_id_idx(
    record_link_id bigint,
    scopeid bigint,
    formid bigint,
    time timestamp
    PRIMARY KEY ((record_link_id), scopeid, formid, time)
);

CREATE TABLE update_audit_user_zuid_idx(
    user_zuid bigint,
    scopeid bigint,
    formid bigint,
    time timestamp
    PRIMARY KEY ((user_zuid), scopeid, formid, time)
);

Вторичные индексы Cassandra реализуются как локальные индексы, а не распределяются как обычные таблицы. Каждый node хранит только индекс для хранящихся в нем данных.

Рассмотрим следующий запрос:

select * from update_audit where scopeid=35 and formid=78005 and record_link_id=9897;
  • Как этот запрос выполнит "под капотом" в Кассандре?
  • Как будет влиять на показатель производительности столбца с высокой мощностью (record_link_id)?
  • Будет ли Cassandra касаться всех узлов для вышеуказанного запроса? Почему?
  • Какие критерии будут выполняться сначала, base table partition_key или вторичный индекс partition_key? Как Кассандра пересечет эти два результата?
4b9b3361

Ответ 1

select * from update_audit where scopeid=35 and formid=78005 and record_link_id=9897;

Как вышеупомянутый запрос будет работать внутри кассандры?

По существу, все данные для раздела scopeid=35 и formid=78005 будут возвращены, а затем отфильтрованы индексом record_link_id. Он будет искать запись record_link_id для 9897 и попытаться сопоставить записи, соответствующие строкам, возвращаемым там, где scopeid=35 и formid=78005. Будет возвращено пересечение строк для ключей раздела и индексных ключей.

Как индекс столбца высокой мощности (record_link_id) повлияет на производительность запроса для вышеуказанного запроса?

Индексы высокой мощности существенно создают строку для (почти) каждой записи в основной таблице. На производительность влияет, потому что Cassandra предназначена для последовательного чтения результатов запроса. Индексный запрос существенно заставляет Cassandra выполнять произвольные чтения. По мере увеличения мощности вашего индексированного значения увеличивается время, необходимое для поиска запрашиваемого значения.

Будет ли cassandra касаться всех узлов для вышеуказанного запроса? Почему?

Нет. Он должен касаться только node, который отвечает за раздел scopeid=35 и formid=78005. Индексы также хранятся локально, содержат только те записи, которые действительны для локального node.

создание индекса по столбцам с высокой производительностью будет самой быстрой и лучшей моделью данных

Проблема заключается в том, что подход не масштабируется и будет медленным, если update_audit - большой набор данных. MVP Richard Low имеет отличную статью о вторичных индексах (The Sweet Spot для вторичной индексации Cassandra), и особенно в этом пункте:

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

...

На практике это означает, что индексирование наиболее полезно для возвращения десятков, может быть, сотен результатов. Имейте это в виду, когда вы затем рассмотрите использование вторичного индекса.

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

Edit

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

Это будет зависеть от того, насколько широки ваши ряды. Трудная вещь о чрезвычайно низких показателях мощности, заключается в том, что% возвращаемых строк обычно больше. Например, рассмотрим таблицу с широкими рядами users. Вы ограничиваете ключом раздела в своем запросе, но есть еще 10 000 строк. Если ваш индекс находится на чем-то вроде gender, вашему запросу придется отфильтровать около половины этих строк, что не будет работать хорошо.

Вторичные индексы, как правило, лучше всего работают (из-за отсутствия лучшего описания) "середина дороги". Используя приведенный выше пример широкоформатной таблицы users, индекс на country или state должен работать намного лучше, чем индекс на gender (если предположить, что большинство из этих пользователей не все живут в одном и том же страны или штата).

Ответ 2

В Cassandra возможно использовать запрос только с вторичным индексом 2.x

выберите * из update_audit, где record_link_id = 9897;

Но это сильно влияет на выборку данных, поскольку она считывает все разделы в распределенной среде. Данные, полученные этим запросом, также несовместимы и не могут быть ретранслированы на нем.

Предложение:
Использование вторичного индекса считается DIRT-запросом из представления модели данных NoSQL.

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