Зачем нужна статистика таблиц Apache Hive и как ее собрать

Автор Категория ,
Зачем нужна статистика таблиц Apache Hive и как ее собрать

Мы уже писали, зачем нужна статистика таблиц при оптимизации SQL-запросов на примере Greenplum. Сегодня рассмотрим, как собрать статистические данные в таблицах Apache Hive, каким образом это поможет оптимизатору запросов и какие есть способы сбора статистики в этом популярном инструменте стека SQL-on-Hadoop.

Еще раз о пользе статистики для оптимизации запросов в Apache Hive

Напомним, любой оптимизатор запросов в СУБД использует статистическую информацию о количестве строк в таблице, количество файлов данных, общий размер файлов данных и формат файла. Для партиционированных таблиц числа рассчитываются для каждого раздела и агрегируются для всей таблицы. Эта статистика хранится в базе данных хранилища метаданных Hive и может легко обновляться. Если какая-либо статистика недоступна, в качестве заполнителя используется значение -1. Некоторые числа, такие как количество и общий размер файлов данных, всегда обновляются, потому что они могут быть дешево вычислены как часть коллекции метаданных блока HDFS.

На основе этой статистики оптимизатор оценивает способы формирования результатов SQL-запроса, стараясь выбрать самый эффективный план выполнения. В частности, для cost-based оптимизатора Hive статистика является входом, чтобы сравнивать различные планы выполнения запросов.

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

В Apache Hive статистика таблиц и разделов хранится в хранилище метаданных (Metastore) как для вновь созданных, так и для существующих таблиц, включая следующую информацию:

  • количество строк;
  • количество файлов;
  • размер в байтах;
  • количество разделов таблицы.

Как собрать статистику таблиц

Есть два способа вычисления статистики таблицы Hive:

  • автоматический сбор – для вновь созданных таблиц и разделов. Пользователь должен явно установить для логической переменной stats.autogather значение false, чтобы статистика не вычислялась автоматически и не сохранялась в хранилище метаданных.
  • с помощью команды ANALYZE. Для существующих таблиц и разделов пользователь может выполнить команду ANALYZE, чтобы собрать статистику и записать ее в хранилище метаданных Hive.

Способ вычисления статистики одинаков как для вновь созданных, так и для существующих таблиц. Для вновь созданных таблиц и разделов, которые заполняются с помощью команды INSERT OVERWRITE, статистика по умолчанию вычисляется автоматически. Пользователь должен явно установить для логической переменной hive.stats.autogather значение false, чтобы статистика не вычислялась автоматически и не сохранялась в MetaStore: set hive.stats.autogather=false.

Поскольку задание создания новой таблицы представляет собой операцию MapReduce, логично, что она состоит из 2-х шагов. Во время создания каждый Mapper, копируя строки из исходной таблицы в операторе FileSink, собирает статистику для строк, с которыми он сталкивается, и публикует их в Metastore. В конце задания MapReduce опубликованная статистика агрегируется и сохраняется в хранилище метаданных.

Аналогично для существующих таблиц, где создается задание только для этапа Map, и каждый Reducer при обработке таблицы в операторе TableScan собирает статистику для строк, с которыми он сталкивается.

Для существующих таблиц и разделов пользователь может выполнить команду ANALYZE, чтобы собрать статистику и записать ее в MetaStore.

ANALYZE TABLE [db_name.]tablename [PARTITION(partcol1[=val1], partcol2[=val2], …)]  
COMPUTE STATISTICS
[FOR COLUMNS]   
[CACHE METADATA]    
[NOSCAN];

Когда пользователь вводит эту команду, он может или не может указывать спецификации раздела. Если пользователь не указывает спецификации разделов, статистика собирается для таблицы, а также для всех разделов, если они есть. Если указаны определенные спецификации разделов, то статистика собирается только для них. При вычислении статистики по всем разделам их столбцы необходимо указывать. Начиная с версии 1.2.0, Hive полностью поддерживает полное имя таблицы в этой команде. Пользователь может только вычислить статистику для таблицы в текущей базе данных, если используется неквалифицированное имя таблицы.

Запросы могут не собирать статистику полностью. Например, есть параметр hive.stats.reliable, который не выполняет запросы, если статистику невозможно надежно собрать. По умолчанию это False. Для хранения временно собранной статистики используется MySQL или HBase. Также есть два подключаемых интерфейса IStatsPublisher и IStatsAggregator, которые разработчик может реализовать для поддержки любого другого хранилища.

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

Можно указать реализацию для хранения временной статистики, установив переменную hive.stats.dbclass. Например, чтобы установить HBase как реализацию временного хранилища статистики (по умолчанию jdbc: derby или fs, в зависимости от версии Hive), пользователь должен выполнить следующую команду: set hive.stats.dbclass=hbase;

В случае JDBC-реализации для сохранения временной статистики (Derby или MySQL) пользователь должен указать соответствующую строку подключения к базе данных, установив переменную hive.stats.dbconnectionstring. Также пользователь должен указать соответствующий драйвер JDBC, установив переменную hive.stats.jdbcdriver.

set hive.stats.dbclass=jdbc:derby;
set hive.stats.dbconnectionstring=”jdbc:derby:;databaseName=TempStatsStore;create=true”;
set hive.stats.jdbcdriver=”org.apache.derby.jdbc.EmbeddedDriver”;

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

В заключение отметим, что табличная статистика – это не самый точный способ посчитать количество строк. Оператор COUNT(*) в SQL-запросе даст точное число. Но если 100%-ная точность не нужна, а достаточно приблизительной оценки размера таблицы, статистика отлично подойдет для этого. Также есть быстрый способ получить COUNT(*) для полной таблицы или некоторых ее разделов, используя оператор EXPLAIN непосредственно перед запросом. Пользователи HUE могут вызвать эту команду, нажав одноименную кнопку в GUI. При этом не будет выполняться само MapReduce-задание, но результат получится почти мгновенно, т.к. количество строк берется из статистики таблицы Hive. О том, как работать с пользовательскими функциями в этой NoSQL-СУБД, зарегистрировать и обновить собственную UDF, читайте в нашей новой статье.

Освоить все тонкости работы с Apache Hive для эффективной аналитики больших данных вам помогут специализированные курсы в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Источники

  1. https://cwiki.apache.org/confluence/display/hive/statsdev
  2. https://medium.com/analytics-vidhya/get-hive-count-in-seconds-7efcb07c65d8
  3. https://dwgeek.com/hive-analyze-table-command-table-statistics.html/