Это расследование стоило мне первых седых волос.

Короче

Мы все привыкли работать с системами управления реляционными базами данных, и это большой опыт. Все эти базы данных, такие как Oracle, PostgreSQL, обеспечивают такую универсальность в использовании, что разработчики могут найти любую запись по любым критериям практически без усилий. Одним из наиболее важных аспектов РСУБД являются высокие показатели производительности, и для этого требуется лишь базовая настройка.

Ситуация меняется, когда мы пытаемся организовать высокую масштабируемость и доступность ваших сервисов, внедряя распределенную архитектуру или микросервисы. Очевидно, что вы выбираете Apache Hadoop и HBase в качестве файловой системы и хранилища данных, что само по себе является отличным решением и технологическим стандартом. Однако HBase не предоставляет такого продвинутого API для работы с объектами базы данных, как РСУБД. Производительность сканирования и обхода по случайному значению поля все еще намного ниже из-за распределенной файловой системы и структуры, ориентированной на столбцы. В погоне за постоянным совершенствованием мы вводим еще один инструмент в наш технологический зоопарк - Apache Phoenix в качестве оболочки SQL, а точнее OLTP для HBase.

Именно здесь возникают настоящие проблемы.

Настраивать

Для обзора базовой производительности и объяснения плана мы будем использовать 3 таблицы:

  • USER_DATA_150K (150 000 записей)
  • USER_DATA_15M (15 000 000 записей)
  • USER_DATA_30M (30 000 000 записей)

Эти таблицы имеют полностью идентичную структуру:

Обзор производительности

Выбрать по первичному ключу (REC_KEY)

SELECT REC_KEY, REC_STATE, REC_CREATE_DATE, REC_EMAIL, REC_ FIRST_NAME, REC_LAST_NAME FROM TEST.USER_DATA_XXX WHERE REC_KEY = 'xxx'

Мы уже можем заметить, что показатели эффективности для этих трех случаев в пределах допустимого. Самым впечатляющим фактом для меня являются хорошие показатели производительности операций чтения из коробки, которые показывает Apache Phoenix, хотя это больше касается HBase.

Фильтрация и сортировка по полям таблицы (REC_LAST_NAME и REC_CREATE_DATE)

Пришло время проверить нашу производительность, создав операторы выбора для полей наших таблиц. Это будет сложной задачей для HBase и Apache Phoenix из-за их внутренней структуры данных.

SELECT REC_KEY, REC_STATE, REC_CREATE_DATE, REC_EMAIL, REC_ FIRST_NAME, REC_LAST_NAME FROM TEST.USER_DATA_XXX WHERE REC_LAST_NAME = 'xxx' ORDER BY REC_MODIFY_DATE

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

  1. Мы добавили к утверждению 2 критерия.
  2. Эти критерии не являются частью первичного ключа, а являются обычными значениями полей таблицы.
  3. Apache Phoenix не знает, где могут храниться определенные записи, соответствующие этому критерию, поэтому он начинает сканирование всей таблицы вместо сканирования области.

Глобальные индексы Phoenix’s

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

  • Включить все поля в индекс. Плюсы: гарантия того, что поиск будет выполняться по таблице индекса. Минусы: Существенное снижение производительности для UPSERT и DELETE операций, размер таблицы индекса увеличивается и по умолчанию это неправильное архитектурное решение, если вы не выполните поиск по всем полям таблицы.
  • Подсказка индекса. Плюсы: легкий подход, не замечено проблем с рассинхронизацией таблицы (критическая ошибка в версии 5.0.0 и ниже: PHOENIX-4455) . Минусы: не гарантирует обход таблицы индекса.
  • Покрытый индекс. Плюсы: гарантия того, что поиск будет выполняться по индексной таблице. Минусы: размер таблицы индекса увеличивается.

Теперь мы можем применить эти 3 стратегии глобального индекса отдельно к нашей таблице to USER_DATA_15M и сравнить результаты.

Все эти манипуляции положительно повлияли на таблицу 15M и сократили время поиска в 20 (!!!) раз.

Глобальные индексы. Обзор проблем

На данный момент Apache Phoenix версии 5.0.0 имеет несколько чрезвычайно уязвимых проблем (PHOENIX-4455 и PHOENIX-3845). Из-за этих и других подобных ошибок мы не можем использовать глобальные индексы в полном объеме. Эти проблемы намного опаснее, чем может показаться, я наблюдал за ними сам и доверяю мне, такая рутина, как отладка базы данных и наблюдение, что по какой-то причине / в какой-то момент индекс и таблица не синхронизированы, ужасны. Я могу только представить, что в чьей-то производственной среде могут быть эти ошибки.

Плохие вещи.

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

Транзакции. Пожалуй, это самое спорное решение.

  • Это не способ делать большие данные, используя транзакции, вы начинаете терять производительность записи и нарушаете принцип больших данных WORM - Пишите одни, читайте много.
  • Вы должны включить Apache Tephra в качестве транзакционного сервиса в и без того интересную экосистему, что само по себе неплохая идея, но есть одно но: это проект инкубатора Apache, и с 2017 года никаких серьезных работ не проводилось, так что забудьте о любой вид поддержки.

Локальные индексы. Phoenix изменил структуру локальных индексов в версии 4.8 и выше, они не будут иметь несоответствий в таблице и индексе, однако локальные индексы не идеальны. Подумайте дважды, прежде чем использовать их повсюду из-за низкой интенсивности чтения.

Важные заметки

Вот несколько важных замечаний, которыми я хотел бы поделиться с вами, которые сделают ваш опыт работы с Apache Phoenix более продуктивным:

  • Глобальный индекс не будет использоваться Phoenix, если все столбцы, указанные в запросе, не содержатся в индексе. Локальный индекс может быть альтернативой глобальному индексу.
  • После включения всех полей во вторичный индекс и введения покрытых индексов размер таблицы индекса увеличился в 2 раза по сравнению со стратегией Index Hinting. Во многом это зависит от количества и типа полей ваших таблиц. Чтобы проверить размер таблицы индекса, выполните следующую команду в Namenode Hadoop:
$ hadoop fs -du -h hdfs://{PATH_TO_HBASE}/data/data/{SCHEMA}/{INDEX}
  • Порядковый номер полей индекса следует выбирать таким образом, чтобы он соответствовал общим шаблонам запросов - выберите наиболее часто запрашиваемый столбец или столбец, который всегда будет стоять перед каждым критерием фильтра в качестве первого и т. Д.

Заключение

Apache Phoenix - отличный инструмент, он обеспечивает такую универсальность Apache HBase. Тем не менее, необходимо приложить усилия, чтобы правильно настроить его для вашего проекта / бизнеса, особенно при наличии проблем с открытыми блокировщиками даже с последней версией Phoenix 5.0.0.

Не принимайте близко к сердцу!