1. Таблица разделов
1.1 Концепция
Таблица в Hive соответствует указанному каталогу на HDFS, при запросе данных по умолчанию сканируется вся таблица, что отнимает много времени и производительности.
Разделен как подкаталог каталога таблицы в HDFS., данные хранятся в подкаталогах по разделам. Если запросwhere
Если условие секции включено в предложение, поиск запроса выполняется непосредственно в секции, а не по всему каталогу таблиц.Разумная структура секции может значительно повысить скорость и производительность запросов.
Здесь мы объясняем концепцию таблицы разделов, уникальную для Hive, на самом деле эта концепция очень распространена. Например, в нашей часто используемой базе данных Oracle, когда объем данных в таблице продолжает увеличиваться, скорость запроса данных будет снижаться.В это время таблица также может быть секционирована. После секционирования таблица по-прежнему является логически полной таблицей, но данные в таблице хранятся в нескольких табличных пространствах (физических файлах), поэтому при запросе данных нет необходимости каждый раз сканировать всю таблицу. Это повышает производительность запросов.
1.2 Сценарии использования
Обычно секционирование требуется при управлении крупномасштабными наборами данных, например при секционировании файлов журналов по дням, чтобы обеспечить детальное разделение данных и повысить производительность запросов.
1.3 Создайте таблицу разделов
Доступно в ульеPARTITIONED BY
предложение для создания секционированной таблицы. Таблица может содержать один или несколько столбцов разделения, и программа создает отдельный каталог данных для каждой отдельной комбинации значений в столбце разделения. Ниже мы создаем таблицу сотрудников в качестве теста:
CREATE EXTERNAL TABLE emp_partition(
empno INT,
ename STRING,
job STRING,
mgr INT,
hiredate TIMESTAMP,
sal DECIMAL(7,2),
comm DECIMAL(7,2)
)
PARTITIONED BY (deptno INT) -- 按照部门编号进行分区
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
LOCATION '/hive/emp_partition';
1.4 Загрузка данных в таблицу разделов
При загрузке данных в секционированную таблицу необходимо указать партицию, в которой находятся данные:
# 加载部门编号为20的数据到表中
LOAD DATA LOCAL INPATH "/usr/file/emp20.txt" OVERWRITE INTO TABLE emp_partition PARTITION (deptno=20)
# 加载部门编号为30的数据到表中
LOAD DATA LOCAL INPATH "/usr/file/emp30.txt" OVERWRITE INTO TABLE emp_partition PARTITION (deptno=30)
1.5 Просмотр каталога раздела
В настоящее время мы непосредственно просматриваем каталог таблицы и видим, что в каталоге таблицы есть два подкаталога, а именноdeptno=20
а такжеdeptno=30
, Это каталог раздела, а каталог раздела — это файл данных, который мы загружаем.
# hadoop fs -ls hdfs://hadoop001:8020/hive/emp_partition/
В этот момент, когда ваш оператор запросаwhere
Включатьdeptno=20
, затем перейдите в соответствующий каталог раздела для поиска вместо сканирования всей таблицы.
2. Ковшовый стол
1.1 Введение
Секционирование предоставляет подходящее решение для изоляции данных и оптимизации запросов, но не все наборы данных могут формировать разумные секции, а количество секций не лучше.Слишком много условий секционирования может привести к отсутствию данных во многих секциях. В то же время Hive ограничит максимальное количество разделов, которые могут быть созданы динамическими разделами, чтобы не перегружать файловую систему слишком большим количеством файлов разделов. По вышеуказанным причинам Hive также предоставляет более точную схему разделения данных: таблицу сегментов.
Таблица сегментов будет хешировать значение указанного столбца, брать остаток сегмента (количество сегментов) и сохранять его в соответствующем сегменте (сегменте).
1.2 Понимание таблицы сегментов
Может быть неясным понимание таблицы сегментов с концептуальной точки зрения. На самом деле, как и разделение, концепция сегментирования не уникальна для Hive. Разработчики Java могут использовать эту концепцию каждый день, потому что в Hive есть сегментация. Концепция HashMap согласуется с концепцией группировки HashMap в структуре данных Java.
При вызове метода put() HashMap для хранения данных программа сначала вызовет метод hashCode() для значения ключа для вычисления хэш-кода, затем по модулю длины массива для вычисления индекса и, наконец, сохранит данные в связанный список в позиции индекса массива.По достижении определенного порога он будет преобразован в красно-черное дерево (JDK1.8+). На следующем рисунке показана структура данных HashMap:
Изображение взято из:HashMap vs. Hashtable
1.3 Создайте таблицу сегментов
В Hive мы можем пройтиCLUSTERED BY
Укажите столбец сегментации и передайтеSORTED BY
Указывает столбец ссылки сортировки для данных в сегменте. Ниже приведен пример оператора создания таблицы сегментов:
CREATE EXTERNAL TABLE emp_bucket(
empno INT,
ename STRING,
job STRING,
mgr INT,
hiredate TIMESTAMP,
sal DECIMAL(7,2),
comm DECIMAL(7,2),
deptno INT)
CLUSTERED BY(empno) SORTED BY(empno ASC) INTO 4 BUCKETS --按照员工编号散列到四个 bucket 中
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
LOCATION '/hive/emp_bucket';
1.4 Загрузить данные в таблицу сегментов
используйте прямо здесьLoad
Оператор загружает данные в таблицу сегментов. Данные могут быть успешно загружены, но данные не будут разделены на сегменты.
Это связано с тем, что суть сегментирования заключается в том, чтобы хэшировать указанное поле и затем сохранять его в соответствующем файле, а значит, вставка данных в таблицу сегментирования должна проходить через MapReduce, а количество редюсеров должно быть равно количеству бакетов. По указанным выше причинам данные в сегментированные таблицы обычно можно вставлять только с помощью метода CTAS (CREATE TABLE AS SELECT), поскольку операция CTAS активирует MapReduce. Шаги для загрузки данных следующие:
1. Настройте принудительное группирование
set hive.enforce.bucketing = true; --Hive 2.x 不需要这一步
В версиях Hive 0.x и 1.x необходимо использовать параметрhive.enforce.bucketing = true
, что означает принудительное группирование, позволяющее программе автоматически выбирать правильное количество редукторов и группировать по столбцам для группирования в соответствии со структурой таблицы.
2. Импорт данных CTAS
INSERT INTO TABLE emp_bucket SELECT * FROM emp; --这里的 emp 表就是一张普通的雇员表
Из журнала выполнения видно, что CTAS запускает операции MapReduce, а количество редукторов совпадает с количеством бакетов, указанным при создании таблицы:
1.5 Просмотр файлов сегментов
Ведро (bucket) — это по сути конкретный файл в каталоге таблицы:
3. Совместное использование таблицы разделов и таблицы сегментов
Суть таблицы разделов и таблицы сегментов заключается в разделении данных в соответствии с разной степенью детализации, поэтому нет необходимости сканировать всю таблицу во время запроса, необходимо сканировать только соответствующий раздел или сегмент, тем самым повышая эффективность запроса. Их можно использовать в сочетании, чтобы обеспечить разумное разделение табличных данных с разной степенью детализации. Ниже приведен официальный пример, предоставленный Hive:
CREATE TABLE page_view_bucketed(
viewTime INT,
userid BIGINT,
page_url STRING,
referrer_url STRING,
ip STRING )
PARTITIONED BY(dt STRING)
CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\001'
COLLECTION ITEMS TERMINATED BY '\002'
MAP KEYS TERMINATED BY '\003'
STORED AS SEQUENCEFILE;
На этом этапе вам нужно указать раздел при импорте данных:
INSERT OVERWRITE page_view_bucketed
PARTITION (dt='2009-02-25')
SELECT * FROM page_view WHERE dt='2009-02-25';
использованная литература
Дополнительные статьи серии о больших данных см. в проекте с открытым исходным кодом GitHub.:Руководство для начинающих по большим данным