Apache Hive
Hive — SQL-слой поверх Hadoop/HDFS: пишете HQL (почти как SQL), а запросы превращаются в MapReduce/Spark-задачи. Классика warehouse-аналитики.
1. Что такое Hive
Hive хранит метаданные таблиц в Hive Metastore (обычно отдельная БД), а сами данные — на HDFS (или S3). Запрос компилируется в задачу: классически MapReduce, современней — Tez/Spark.
Сегодня Hive вытесняется Spark SQL и Presto, но метастор и HQL-опыт остаются важными.
2. Схема типов запросов
| Инструмент | Тип работы |
|---|---|
| Hive | ETL и пакетные batch-задачи |
| Presto/Trino | интерактивные запросы (OLAP) |
| Spark SQL | гибрид: batch + streaming + ML |
3. Основные команды HQL
SHOW DATABASES;
USE analytics;
CREATE TABLE events (
ts TIMESTAMP,
user_id INT,
event STRING
)
PARTITIONED BY (dt STRING)
STORED AS PARQUET;
SHOW TABLES;
DESCRIBE events;4. Загрузка данных
INSERT INTO TABLE events PARTITION (dt='2026-09-05')
SELECT ts, user_id, event FROM staging;
LOAD DATA INPATH 'hdfs:///input/events.csv'
INTO TABLE events PARTITION (dt='2026-09-05');Внешние таблицы (EXTERNAL) не удаляют данные при DROP — удобно для данных в S3.
5. Запросы
SELECT
dt,
count(*) AS n,
count(DISTINCT user_id) AS users
FROM events
WHERE event = 'buy' AND dt >= '2026-09-01'
GROUP BY dt
ORDER BY n DESC;Оконные функции, CTE, join — поддерживаются, как в обычном SQL (см. SQL).
6. Партиционирование
Партиция — папка в HDFS по колонке (dt, country): запросы по партициям читают только нужные файлы. Эффект сильнее на больших данных, чем индексы.
SET hive.exec.dynamic.partition=true с проекцией через SELECT.7. Bucketing
CREATE TABLE events_bucketed (
...same columns...
)
CLUSTERED BY (user_id) INTO 16 BUCKETS
STORED AS ORC;Bucket'и фиксируют порядок строк по хешу колонки — ускоряют джойны и sampling.
8. Оптимизация
- Фильтры по партициям обязательны: запрос без WHERE по dt прочитает всё.
- Маленькие файлы — беда HDFS: используй компакцию (INSERT OVERWRITE) и большие файлы Parquet/ORC.
- Векторизация:
SET hive.vectorized.execution.enabled=true.
9. Metastore и интеграции
Hive Metastore — общий каталог для всей экосистемы: таблицы, созданные в Hive, видны в Spark SQL, Presto, схемы для Zeppelin.
10. Лучшие практики
- ETL намеренно пиши в партиции, а не в одну большую таблицу.
- Используй компакцию и партиционирование до того, как данные «расползлись».
- Для интерактивной аналитики выбирай Presto, для тяжёлых пакетов — Hive/Spark.
11. ACID и транзакции в Hive
Долгое время Hive считался чисто пакетным инструментом без поддержки транзакций. Начиная с Hive 3 ситуация изменилась: таблицы, хранящиеся в формате ORC с параметром transactional=true, поддерживают операции INSERT, UPDATE и DELETE с частичной изоляцией.
Механика выглядит так:
- изменения записываются дельта-файлами, а не переписыванием всей таблицы;
- команда COMPACT периодически сливает дельты в базовый файл;
- версии строк отслеживаются скрытой колонкой
ROW__ID.
ALTER TABLE events COMPACT 'major';
SHOW TRANSACTIONS;
SHOW COMPACTIONS;12. Пользовательские функции: UDF, UDAF, UDTF
Когда встроенных функций не хватает, пишут собственные расширения. В Hive их три типа:
| Тип | Что делает | Один вызов |
|---|---|---|
| UDF | одна строка → одно значение | my_clean_string() |
| UDAF | группа строк → одно значение | my_median() |
| UDTF | одна строка → несколько строк | my_explode_json() |
Быстрый путь без компиляции — скрипты через TRANSFORM:
ADD FILE mapper.py;
SELECT TRANSFORM (event, user_id)
USING 'python3 mapper.py'
AS (event STRING, clean_id INT)
FROM events;Скомпилированный JAR подключается командами:
ADD JAR /tmp/my-udf.jar;
CREATE TEMPORARY FUNCTION clean AS
'com.example.udf.CleanString';13. Диагностика и план запроса
Перед оптимизацией полезно понять, во что Hive превратит ваш запрос. Команда EXPLAIN показывает логический и физический план исполнения, включая количество Map/Reduce-стадий.
EXPLAIN SELECT dt, count(*)
FROM events
WHERE dt >= '2026-09-01'
GROUP BY dt;Оптимизатор принимает решения по статистике, поэтому её нужно собирать после массовых загрузок:
ANALYZE TABLE events COMPUTE STATISTICS;
ANALYZE TABLE events PARTITION (dt)
COMPUTE STATISTICS FOR COLUMNS;- в плане ищи предупреждения о полном сканировании партиций;
- для Tez профиль выполнения смотри в логах Application Master;
- после каждой массовой загрузки обновляй статистику автоматически.
14. Работа в YARN и планировщиках
Задачи Hive исполняются как приложение YARN. Ресурсы кластера делятся планировщиками: Capacity Scheduler (по умолчанию) и Fair Scheduler. Понимание очередей важно, когда ваши запросы конкурируют с запросами других команд.
SET mapreduce.job.queuename=analytics;
SET hive.exec.parallel=true;
SET hive.exec.parallel.thread.number=8;
SET mapreduce.reduce.memory.mb=4096;| Параметр | Эффект |
|---|---|
| mapreduce.job.queuename | очередь, откуда брать ресурсы |
| hive.exec.parallel | независимые стадии бегут одновременно |
| mapreduce.reduce.memory.mb | лимит памяти редьюсеров |
15. Работа с JSON и вложенными типами
Логи и выгрузки из API почти всегда приходят в JSON. Hive умеет хранить вложенные структуры как есть — STRUCT, ARRAY и MAP, — а разбирать JSON-строки помогают встроенные функции.
SELECT
get_json_object(payload, '$.user.id') AS user_id,
json_tuple(payload, 'event', 'price')
FROM events;Для массива внутри строки удобен LATERAL VIEW explode() — одна строка превращается во много:
SELECT tag, count(*) AS cnt
FROM events
LATERAL VIEW explode(tags) t AS tag
GROUP BY tag;| Тип | Синтаксис | Доступ |
|---|---|---|
| STRUCT | struct<id:int> | col.id |
| ARRAY | array<string> | col[0] |
| MAP | map<string,int> | col['key'] |
get_json_object на огромных таблицах без фильтра: парсинг Regex-ом выполняется на каждой строке и обходит партиции.16. Облачные хранилища и внешние таблицы
В современных деплоях данные лежат не в HDFS, а в объектном хранилище — S3, ADLS или GCS. Внешняя таблица позволяет читать их без копирования на кластер.
CREATE EXTERNAL TABLE events (
dt STRING,
event STRING
)
STORED AS PARQUET
LOCATION 's3a://analytics/events';| Хранилище | Протокол | Особенность |
|---|---|---|
| AWS S3 | s3a:// | самый распространённый |
| Azure Data Lake | abfss:// | интеграция с ADLS Gen2 |
| Google Cloud | gs:// | через GCS коннектор |
17. Потоковая загрузка: Kafka и микро-батчи
Пакетный Hive медленно реагирует на события, поэтому «горячие» данные сначала попадают в Kafka, а затем льются в Hive микро-батчами.
-- Spark Structured Streaming в Hive-таблицу
df.writeStream
.format("hive")
.option("table", "events_stream")
.outputMode("append")
.trigger(Trigger.ProcessingTime("1 minute"))
.start();Микро-батч раз в 1–5 минут сглаживает нагрузку и даёт точность «почти реального времени» без сложностей полноценного стриминга.
- партиционируйте по дате события — очистка старых данных станет тривиальной;
- дедупликация по ключу события обязательна: повторные поставки из Kafka — норма;
- контролируйте лаг с помощью мониторинга consumer-групп.
18. Безопасность: Ranger, Kerberos и шифрование
Данные в Hive часто чувствительны: доступ должен быть и по гранулярности, и по журналированию. Стандартный стек — Apache Ranger + Kerberos.
- Kerberos — аутентификация: кто вообще имеет право подключиться;
- Apache Ranger — авторизация: какие таблицы/колонки видит конкретный пользователь;
- Sentinel / HDFS ACL — защита файлов на уровне хранилища.
-- пример политики Ranger:
-- пользователь analyst может SELECT из db1.events,
-- но не из db1.payments19. Форматы файлов и сжатие: ORC, Parquet, Avro
То, как Hive хранит данные, влияет на скорость и объём сильнее, чем большинство настроек запросов. Современный дефолт — колоночные форматы ORC и Parquet: они читают только нужные колонки и хорошо сжимаются.
CREATE TABLE events (
user_id BIGINT, url STRING, ts TIMESTAMP
)
STORED AS ORC
TBLPROPERTIES ('orc.compress'='SNAPPY');- ORC — хорошая компрессия и встроенные статистики, дефолт для Hive;
- Parquet — открытый стандарт, удобный для Spark и других движков;
- Avro — схема хранится прямо в файле, идеален для событийных потоков;
- Snappy — быстрее, Gzip — компактнее; выбирайте по сценарию чтений.
20. Стратегии джойнов: MapJoin, Sort Merge и Skew
Джойн — самая дорогая операция в Hive. Движок выбирает стратегию сам, но понимание вариантов помогает ускорить запросы и предсказать, где возникнет узкое место.
| Стратегия | Когда | Особенность |
|---|---|---|
| MapJoin | маленькая таблица | загружается в память маппера |
| Sort Merge | обе таблицы большие | требует сортировки по ключу |
| Skew Join | «горячие» ключи | изолирует поляризованные значения |
SET hive.auto.convert.join=true;
SET hive.optimize.skewjoin=true;
-- принудительная подсказка MapJoin:
SELECT /*+ MAPJOIN(dim) */ ...
FROM fact f JOIN dim d ON f.dim_id = d.id;21. Дата и время в HQL: функции и форматирование
Даты в Hive хранятся как DATE или TIMESTAMP, а строки часто приходят в произвольных форматах. Функции преобразования и арифметики экономят часы ручной возни с данными.
SELECT current_timestamp(),
from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm'),
to_date('2026-09-19 10:00:00'),
datediff('2026-09-19', '2026-01-01'),
date_add('2026-09-19', 7); -- плюс 7 дней- unix_timestamp / from_unixtime — обмен с эпохой и парсинг строк по формату;
- to_date, year, month, day — извлекают части даты;
- datediff, months_between — разницы в днях и месяцах;
- date_format — гибкое форматирование для отчётов и витрин.
22. Автоматизация Hive: beeline-скрипты и PyHive
Повседневные задачи — пересчёт витрин, обновление партиций, отправка отчётов — легко оборачиваются в сценарии поверх стандартного клиента beeline.
beeline -u jdbc:hive2://hs2:10000/default \
-f daily_refresh.sql --hivevar date=2026-09-19
-- внутри daily_refresh.sql
INSERT OVERWRITE TABLE mart.daily
PARTITION (dt = '${hivevar:date}')
SELECT ... FROM events WHERE ts = '${hivevar:date}';- --hivevar передаёт параметры без правки SQL — скрипт переиспользуем;
- запуск через bash -e прерывает пайплайн при любой ошибке шага;
- PyHive и impyla позволяют вести ETL из Python-кода и оркестраторов.
Что дальше
Интерактивная аналитика по тем же данным — в уроке Presto, визуальный слой — Zeppelin, движок — Spark.