Статьи

SASI Расширение возможностей вторичных индексов

Еще в 2010 году была введена новая функция для Cassandra 0.7: вторичные индексы. В отличие от индекса реляционной базы данных, это индекс, связанный со значениями столбца, который обеспечивает ключ для всех строк в таблице. Например, представьте таблицу «Пользователи». Он имеет первичный индекс как «user_id». Теперь представьте, что вы хотите получить доступ к электронной почте пользователя. Вы должны выполнить поиск по идентификатору, а затем собрать интересующее вас значение (например, по электронной почте). Это не практично с любым видом исполнения. Смотрите изображение ниже:

Screen-Shot-2016-04-03-на-9.35.28-PM

Люди могут получить нужную нам информацию за один шаг, выполнив обратную операцию. Получив электронное письмо, восстановите удостоверение личности. С точки зрения вычислений, как мы можем достичь аналогичного процесса в нашей базе данных? Вторичные индексы решают эти сценарии с помощью электронной почты, выбирая идентификатор пользователя, который действует как обратная функция запроса. Эта функция может быть мощной и практичной. Применение вторичных индексов для небольших наборов данных делает запросы чрезвычайно эффективными. Создать довольно вторичный индекс в Кассандре довольно просто:

01
02
03
04
05
06
07
08
09
10
11
CREATE TABLE users (
   userID uuid,
   firstname text,
   lastname text,
   email text,
   zip int,
   PRIMARY KEY (userID)
 );
  
CREATE INDEX users_email
  ON users (email);

Также возможно определить несколько вторичных индексов по таблице, поскольку мы не ограничены только одним.

Проблемы вторичного индекса

К сожалению, это не серебряная пуля. Поскольку вторичные индексы управляются локально, а не глобально, как обычные индексы, они могут привести к некоторым проблемам. Особенно, если мы имеем дело с большими наборами данных, содержащих разреженную и очень четкую информацию. Для нашего примера электронной почты пользователя, если у нас огромное количество пользователей. У нас может быть одинаково огромное количество писем, и все они будут уникальными. Чтобы обработать вторичный индекс в столбце «электронная почта», Кассандре пришлось бы «объединить» всю информацию, распространяемую по кольцам, поскольку этот индекс является локальным. Это может быть вредно с точки зрения производительности. Если у вас есть пять экземпляров, вам потребуется пять чтений для одного запроса, включая пять операций с диском. С другой стороны, для обычного индекса в этом нет необходимости, поскольку user_id обрабатывается глобально. По этой причине некоторые разработчики критикуют использование вторичных индексов.

Несколько стратегий для вторичных индексов были предложены

  • [1] (http://brianoneill.blogspot.com.br/2012/03/cassandra-indexing-good-bad-and-ugly.html),
  • [2] (http://blog.websudos.com/2014/08/23/a-series-on-cassandra-part-2-indexes-and-keys/),
  • [3] (http://www.slideshare.net/edanuff/indexing-in-cassandra) и
  • [4] (https://dzone.com/articles/cassandra-indexing-good-bad) — все это хорошие примеры.

Чтобы расширить этот набор, Apple недавно открыла свою собственную стратегию вторичного индекса: SSTableAttachedSecondaryIndex или просто [SASI] (https://github.com/xedin/sasi). Эта стратегия была показана чрезвычайно эффективной и мощной. Представляя надежные и гибкие запросы, SASI правильно управляет процессором, вводом-выводом и памятью, чтобы сэкономить вычислительные ресурсы.

SASI примером

Давайте рассмотрим простой пример, чтобы понять, как работает SASI. На данный момент есть поддержка Thrift и CQL3. Для произвольного пространства ключей ‘foo’:

1
2
3
4
5
cqlsh> CREATE KEYSPACE foo WITH replication = {
  'class': 'SimpleStrategy',
  'replication_factor': '1'
  };
cqlsh> USE foo;

Затем мы создаем таблицу ‘bar’:

1
2
3
4
5
6
7
8
CREATE TABLE bar (
id uuid,
fname text,
lname text,
age int,
created_at bigint,
primary key (id)
);

Мы используем команду «CREATE CUSTOM INDEX» для создания вторичного индекса с помощью SASI:

1
2
3
4
5
6
7
CREATE CUSTOM INDEX ON bar (fname) USING
'org.apache.cassandra.db.index.SSTableAttachedSecondaryIndex'
WITH OPTIONS = {
'analyzer_class':
'org.apache.cassandra.db.index.sasi.analyzer.NonTokenizingAnalyzer',
'case_sensitive': 'false'
};

Обратите внимание на конфигурацию ‘case_sensitive’: ‘false’. Это может напомнить вам о полнотекстовых инструментах поиска. Загляните в класс [Analyzer] (https://github.com/xedin/sasi/blob/master/src/java/org/apache/cassandra/db/index/sasi/analyzer/StandardA

nalyzer.java). SASI позволяет вам сделать некоторые интересные настройки для индексов. Посмотрите на следующий пример:

1
2
3
CREATE CUSTOM INDEX ON bar (lname) USING
'org.apache.cassandra.db.index.SSTableAttachedSecondaryIndex'
WITH OPTIONS = {'mode': 'SUFFIX'};

Здесь мы создаем индекс с суффиксным анализатором. Это оценивает данные по суффиксу, а не по всему термину.
Также есть режим «SPARSE»:

1
2
3
CREATE CUSTOM INDEX ON bar (created_at) USING
'org.apache.cassandra.db.index.SSTableAttachedSecondaryIndex'
WITH OPTIONS = {'mode': 'SPARSE'};

Режим «SPARSE» позволяет нам эффективно выполнять запросы по временным меткам. Если режим не объявлен, по умолчанию используется значение NORMAL, обеспечивающее только точные регистрозависимые соответствия.

Понимание основ SASI

SASI разделен на две части: индексирование и поиск. Cassandra обеспечивает различие между памятью и дисковыми ресурсами, и SASI использует это, а также только запись, неизменность и сортировку данных для правильной работы. Построенные индексы затем записываются из памяти на диск. Структуры данных SASI создаются в памяти, в то время как SSTable начинает процесс записи и сбрасывается на диск до его завершения. Это хорошо для производительности, так как для записи индексов требуется только последовательная запись на диск.

Для каждого SSTable SASI записывает один индексный файл для каждого индексированного столбца. Содержимое файла встроено в память классом [OnDiskIndexBuilder] (https://github.com/xedin/sasi/blob/master/src/java/org/apache/cassandra/db/index/sasi/disk/OnDiskIndexBuilder. Ява).

После сброса на диск информация будет прочитана [OnDiskIndex] (https://github.com/xedin/sasi/blob/master/src/java/org/apache/cassandra/db/index/sasi/disk/OnDiskIndex. .java), которая содержит оптимизированную структуру данных поиска. Создается сопоставление значения ключа для позиций SSTable, а затем после записи на диск эта информация сохраняется в памяти для ускорения доступа к индексу.

Когда мы выполняем поиск, существует другая группа классов, которая анализирует и интерпретирует индексы в древовидную структуру, оптимизирует ее и анализирует, что следует искать. Для выполнения объединения и пересечения данных в SASI есть группа интеллектуальных итераторов, таких как [RangeUnionIterator] (https://github.com/xedin/sasi/blob/master/src/java/org/apache/cassandra/db/ индекс / шаши / Utils / RangeUnionIt

erator.java), который может выполнять операции объединения для хэшей, считывая только минимум, необходимый для каждого набора, чтобы удовлетворить потребности запроса. Существует также [RangeIntersectionIterator] (https://github.com/xedin/sasi/blob/master/src/java/org/apache/cassandra/db/index/sasi/utils/RangeIntersec

tionIterator.java) для пересечений.

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

У SASI есть некоторые ограничения. Например, это требует, чтобы ваш кластер был настроен для производства LongTokens (например: Murmur3Partitioner). ByteOrderedPartitioner и RandomPartitioner не работают с SASI, и поддерживаются только Cassandra в версиях> 3.4.

Заключительные соображения

Основная цель этой статьи — дать краткое и общее представление о вторичных индексах Cassandra и представить основы SASI. Конечно, в этом инструменте еще предстоит проделать работу. Тем не менее, он зарекомендовал себя как надежная и мощная альтернатива предыдущей реализации вторичного индекса. Посетите [официальный репозиторий Github] (https://github.com/xedin/sasi) для получения подробной информации о проекте, проблемах и выпусках.

Ссылка: SASI Empowering Secondary Index от нашего партнера JCG Ханнели Таванте в блоге Planet Cassandra .