четверг, 11 апреля 2013 г.

Встреча с специалистами HP Vertica в Москве

На этой неделе к нам в Москву прилетели специалисты от Vertica, чтобы дать базовый курс партнерам интеграторам HP по этому серверу. Фактически мы являемся первыми, кто успешно освоил и запустил проекты на Vertica в России. С учетом того, что у нас уже как год запущено и работает большое хранилище данных и базовыми знаниями нас не удивить, нам любезно предложили лично встретиться с прилетевшими специалистами и тет-а-тет и пообщаться на более углубленные темы по архитектуре Vertica. Мы с удовольствием согласились и очень признательны за встречу, на которой я узнал много нового для себя. С чем спешу и поделиться.

Оптимизация запросов к данным

Одним из вопросом меня интересовало, как Vertica использует при оптимизации выполнения запросов такие вещи, как порядок сортировки столбцов в проекциях и таблицах, а так же сегментирование и партиционирование. В документации указаны только основные моменты по указанию столбцов в сортировке. Что удалось выяснить:
  • Для более эффективного использования сортировки проекций при выполнении запросов требуется придерживаться следующих правил в порядке очередности столбцов сортировки: 
    • Первыми указывать те столбцы, которые фильтруются в запросах по равенству с константой или выражением.
    • Следующими указывать столбцы, фильтр по которым выбираем из множества значений, это может быть как оператор выбора из констант IN так и фильтрация на базе соединения с другим источником, например с помощью EXISTS или IN.
    • Последними следует указывать те столбцы, по которым идут операции больше-меньше-между.
  • Продуманная политика сегментации записей между нодами сервера может давать прирост производительности при выполнении запросов:
    • Для таблиц фактов, имеющих связи один ко многим предпочтительно делать сегментацию по одинаковому ключу записей главной и подчиненных таблиц. Это приведет к тому, что записи главных и подчиненных таблиц будут лежать на одной ноде. При выполнении запросов с соединениями этих таблиц, операции соединения будут выполнены локально на каждой ноде, что минимизирует затраты на выполнение таких операций.
    • Для часто используемых и разумных по объему таблиц измерений имеет смысл зеркалировать такие таблицы на каждую ноду, чтобы уменьшить сетевой трафик при использовании таких таблиц в операциях соединений с фактами в запросах. Здесь критичность этого правила зависит от количества серверов в кластере - чем серверов больше, тем правило актуальнее. Если у вас кластер из 100 серверов, то интенсивный обмен данными по сети между ними может привести к значительному проседанию производительности всего кластера в целом.
  • Партиционирование таблиц ускоряет выполнение OLAP запросов, использующих оконные функции. Здесь получается определенное противоречие с парадигмой хранения данных в Vertica - рекомендуется не делать партиции с частым значением ключей партиции, иначе просто может остановиться запись в хранилище за счет большой дефрагментации таблицы. Например, если партиция по кварталу уже изначально малое количество ключей партиции даже за 10 лет хранения информации, то партиция по кварталу и клиенту приведет к ошибке Vertica большого количества открытых файлов, где TM не будет успевать дефрагментировать куски поступающих данных и станет откатывать транзакции. Здесь идеальным выглядит делать партиции по разумным разрезам - например по дню. Для того, чтобы со временем жизни хранилища, число ключей партиций оставалось в разумных пределах, можно объединять партиции уже старой, не часто используемой информации с помощью функции MERGE_PARTITION.

Временные  таблицы в Vertica

Временные таблицы в Vertica свои данные хранят в RAM. Для меня, привыкшего работать с времянками в Sybase, это стало полной неожиданностью, так как в документации про это я ничего не нашел. Это означает, что с временными таблицами нужно обращаться более аккуратно и продуманно, чем в том же Sybase или MSSQL. Попытка влить в временную таблицу очень большой объем данных может привести к нехватке памяти и увода Vertica в swap. 

Как это не странно звучит с точки зрения традиционных СУБД, на Vertica получается выгоднее выполнить запрос с множеством JOIN больших таблиц, чем разложить выполнение запроса на запись промежуточных результатов по временным таблицам с их дальнейшим соединением для получения окончательного результата. Логика здесь получается простая - при выполнении всего запроса, каждая его часть в памяти займет только объем, требуемый для хранения промежуточных результатов и после его выполнения, память будет освобождена. Причем, Vertica автоматически будет скидывать промежуточные результаты на диск, если объем получается большой, чтобы не занимать всю память. При реализации раскладки промежуточных результатов на временные таблицы получается наоборот - мало того, что при вычислении записей для временных таблиц будет задействована память, она же будет еще использоваться для хранения данных таких таблиц.

Резюмируя можно сказать, что использование временных таблиц актуально только для случаев, когда объем информации в них не большой и они используются более одного раза при выполнении запросов сессии. Ну а если промежуточных данных получается слишком много и они требуются в ходе дальнейших расчетов, значит нужно создавать публичную таблицу с своим уникальным именем и удалять ее после выполнения проведения всех расчетов. Я например, для этой цели, создал себе отдельную схему в хранилище, которую использую для таких целей.

Игры с накопителями

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

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

Для случаев, когда выполнение аналитических запросов к данным хранилища критичны по времени выполнения, можно значительно ускорить выполнение запросов путем добавления на сервера кластера flash накопителей. Использование таких накопителей в Vertica прозрачно и изящно. Достаточно добавить их как storage для хранения данных базы, с помощью специальных функций Vertica протестировать их скорость доступа к данным и поиска и задать эти параметры серверу. Сервер, увидит, что у него появились несколько типов накопителей с разной скоростью и начнет это использовать следующим образом: те колонки, которые участвуют в сортировках проекций, он станет записывать и хранить на быстром носителе, а остальные на более медленном. Получается разумный баланс между требуемым объемам к быстрым накопителям, дорогим по цене и хорошей производительностью. При выполнении запроса поиск нужных записей будет произведен с быстрого накопителя, а далее основные поля прочитаны с обычного диска. Большим достоинством такого подхода я считаю тот момент, что распределение данных между разными видами накопителей происходит в Vertica автоматически, не нарушая основной тезис Vertica, как сервер с нулевым администрированием, не требующий дополнительного сопровождения.

Что ждать

Лично мне в Vertica не хватает двух вещей - это хранимых процедур на базе SQL синтаксиса с возможностью вернуть результат запроса вызывающей сессии и поддержки Java в виде внешних хранимых процедур. По первому вопросу команда Vertica так и не определилась с своим решением. А вот с поддержкой Java подтвердили, что это будет обязательно. Это уже хорошая новость.

В заключение

В заключении хотел бы сказать само впечатление о специалистах Vertica. Тут самое правильное слово будет - ответственность. Мы за день до встречи подготовили список вопросов, которые хотели бы обсудить и передали вертиковцам. Как они сами признали, вопросы были достаточно сложными, явно не из раздела RTFM, поэтому для ответов на эти вопросы им пришлось серьезно подготовиться. Мужики не стали нам рассказывать, что это не в их компетенции, что они просто приехали давать базовый курс, что наши вопросы не отражены в документации, потому что это не "бестс-практикс" и прочее прочее прочее, что я не однократно слышал от специалистов других компаний, приезжающих к нам в Россию. Просто честно подготовились, ответили и постарались максимально помочь нам понять, что и как можно улучшить и чего нужно избегать. Тоже самое можно сказать о специалистах саппорта Vertica, которые моментально в любое время дня или ночи реагировали на любые наши вопросы и проблемы, выдавая решение или же передавая найденные баги для исправления инженерам. Кстати, из трех обнаруженных мной и заявленных в саппорт багов, они были исправлены в пределах от 2 недель до 1 месяца с момента заявления и фактически закрывались сразу по выходу новой версии Vertica. Исходя из этого, ставлю команде Vertica свою оценку в 5+, так держать ребята :)

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

Отправить комментарий