Ответы:
Разделение данных часто используется для горизонтального распределения нагрузки, это дает преимущество в производительности и помогает в логической организации данных. Пример : если мы имеем дело с большой employee
таблицей и часто выполняем запросы с WHERE
предложениями, которые ограничивают результаты определенной страной или отделом. Для более быстрого ответа на запрос таблица Hive может быть PARTITIONED BY (country STRING, DEPT STRING)
. Таблицы секционирования меняют структуру хранилища данных в Hive, и теперь Hive будет создавать подкаталоги, отражающие структуру секционирования, например
... / сотрудники / страна = ABC / DEPT = XYZ .
Если запрос ограничен для сотрудника из country=ABC
, он будет сканировать только содержимое одного каталога country=ABC
. Это может значительно повысить производительность запросов, но только если схема разделения отражает общую фильтрацию. Функция секционирования очень полезна в Hive, однако дизайн, который создает слишком много секций, может оптимизировать некоторые запросы, но быть вредным для других важных запросов. Другой недостаток - слишком много разделов - это большое количество файлов и каталогов Hadoop, которые создаются без необходимости, и накладные расходы для NameNode, поскольку он должен хранить все метаданные для файловой системы в памяти.
Группирование - это еще один метод разделения наборов данных на более управляемые части. Например, предположим, что таблица, используемая date
в качестве раздела верхнего уровня и раздела employee_id
второго уровня, приводит к слишком большому количеству небольших разделов. Вместо этого, если мы сгруппируем таблицу сотрудников и будем использовать ее employee_id
в качестве столбца сегментирования, значение этого столбца будет хешироваться по заданному пользователем числу в сегменты. Записи с одинаковыми значениями employee_id
всегда будут храниться в одной корзине. Предполагая, что количество employee_id
намного больше, чем количество сегментов, в каждом сегменте будет их много employee_id
. При создании таблицы вы можете указать какCLUSTERED BY (employee_id) INTO XX BUCKETS;
где XX - количество ведер. Ковширование имеет несколько преимуществ. Количество сегментов фиксировано, поэтому оно не зависит от данных. Если две таблицы разделены employee_id
, Hive может создать логически правильную выборку. Группирование также помогает в выполнении эффективных соединений на стороне карты и т. Д.
В предыдущих объяснениях отсутствуют некоторые детали. Чтобы лучше понять, как работает разделение и сегментирование, вы должны посмотреть, как данные хранятся в кусте. Допустим, у вас есть стол
CREATE TABLE mytable (
name string,
city string,
employee_id int )
PARTITIONED BY (year STRING, month STRING, day STRING)
CLUSTERED BY (employee_id) INTO 256 BUCKETS
тогда улей будет хранить данные в иерархии каталогов, например
/user/hive/warehouse/mytable/y=2015/m=12/d=02
Итак, вы должны быть осторожны при разделении, потому что, если вы, например, разделите по employee_id и у вас есть миллионы сотрудников, в вашей файловой системе будут миллионы каталогов. Термин « мощность » относится к числу возможных значений поля может иметь. Например, если у вас есть поле «страна», стран в мире около 300, поэтому количество элементов будет ~ 300. Для поля типа «timestamp_ms», которое изменяется каждую миллисекунду, количество элементов может составлять миллиарды. В общем, при выборе поля для разделения оно не должно иметь большого количества элементов, потому что в результате в вашей файловой системе будет слишком много каталогов.
С другой стороны, кластеризация, также известная как сегментирование, приведет к фиксированному количеству файлов, поскольку вы указываете количество сегментов. Что улей будет делать, так это брать поле, вычислять хэш и назначать запись этому ведру. Но что произойдет, если вы используете, скажем, 256 сегментов, а поле, в котором вы ведете сегмент, имеет низкую мощность (например, это штат США, поэтому может быть только 50 различных значений)? У вас будет 50 сегментов с данными и 206 сегментов без данных.
Кто-то уже упоминал, как разделы могут значительно сократить объем запрашиваемых данных. Итак, в моем примере таблицы, если вы хотите запрашивать только с определенной даты вперед, разделение по годам / месяцам / дням значительно сократит количество операций ввода-вывода. Я думаю, что кто-то также упомянул, как сегментирование может ускорить объединение с другими таблицами, которые имеют точно такое же сегментирование , поэтому в моем примере, если вы объединяете две таблицы с одним и тем же идентификатором employee_id, улей может выполнять объединение ведро за ведром (даже лучше если они уже отсортированы по employee_id, так как он собирается объединить части, которые уже отсортированы, что работает в линейном времени, также известном как O (n)).
Таким образом, сегментирование хорошо работает, когда поле имеет высокую мощность и данные равномерно распределены по сегментам. Разделение работает лучше всего, когда мощность поля разделения не слишком велика.
Кроме того, вы можете разделить на несколько полей в порядке (год / месяц / день - хороший пример), в то время как вы можете сегментировать только одно поле .
Я думаю, что опаздываю с ответом на этот вопрос, но он продолжает появляться в моей ленте.
Navneet дал отличный ответ. Добавляем к нему визуально.
Разделение помогает в удалении данных, если оно используется в предложении WHERE, где сегментирование помогает организовать данные в каждом разделе в несколько файлов, так как один и тот же набор данных всегда записывается в одном сегменте. Очень помогает при соединении столбцов.
Предположим, у вас есть таблица с пятью столбцами: name, server_date, some_col3, some_col4 и some_col5. Предположим, вы разбили таблицу на server_date и разбили столбец имени на 10 сегментов, ваша файловая структура будет выглядеть примерно так, как показано ниже.
Здесь server_date = xyz - это раздел, а 000 файлов - это сегменты в каждом разделе. Сегменты рассчитываются на основе некоторых хэш-функций, поэтому строки с именем = Sandy всегда будут находиться в одном сегменте.
Разбиение улья:
Разделение делит большой объем данных на несколько срезов в зависимости от значения столбца (столбцов) таблицы.
Предположим, вы храните информацию о людях со всего мира, разбросанных по более чем 196 странам, с охватом около 500 крор записей. Если вы хотите запросить людей из определенной страны (города Ватикана), при отсутствии разделения вам нужно отсканировать все 500 крор записей, даже чтобы получить тысячи записей о стране. Если вы разбиваете таблицу по странам, вы можете точно настроить процесс запросов, просто проверив данные только для одного раздела страны. Раздел Hive создает отдельный каталог для значений столбцов.
Плюсы:
Минусы:
Ковширование улья:
При сегментации данные разбиваются на более управляемые или равные части.
При разбиении на разделы можно создать несколько небольших разделов на основе значений столбцов. Если вы выбираете сегментирование, вы ограничиваете количество сегментов для хранения данных. Это число определяется в скриптах создания таблиц.
Pros
Cons
Прежде чем углубляться Bucketing
, нам нужно понять, что это Partitioning
такое. В качестве примера возьмем приведенную ниже таблицу. Обратите внимание, что в приведенном ниже примере я привел только 12 записей для понимания начального уровня. В сценариях реального времени у вас могут быть миллионы записей.
РАЗДЕЛЕНИЕ
---------------------
Partitioning
используется для получения производительности при запросе данных. Например, в приведенной выше таблице, если мы напишем приведенный ниже sql, ему необходимо просканировать все записи в таблице, что снижает производительность и увеличивает накладные расходы.
select * from sales_table where product_id='P1'
Чтобы избежать полного сканирования таблицы и читать только относящиеся к ним записи, product_id='P1'
мы можем разделить (разбить файлы таблицы куста) на несколько файлов на основе product_id
столбца. Таким образом, файл таблицы улья будет разделен на два файла, один с, product_id='P1'
а другой с product_id='P2'
. Теперь, когда мы выполняем вышеуказанный запрос, он будет сканировать только product_id='P1'
файл.
../hive/warehouse/sales_table/product_id=P1
../hive/warehouse/sales_table/product_id=P2
Синтаксис создания раздела приведен ниже. Обратите внимание, что мы не должны использовать product_id
определение столбца вместе с несекционированными столбцами в синтаксисе ниже. Это должно быть только в partitioned by
пункте.
create table sales_table(sales_id int,trans_date date, amount int)
partitioned by (product_id varchar(10))
Минусы : мы должны быть очень осторожны при разметке. То есть его не следует использовать для столбцов, в которых количество повторяющихся значений очень мало (особенно столбцов с первичным ключом), поскольку это увеличивает количество секционированных файлов и увеличивает накладные расходы для Name node
.
BUCKETING
------------------
Bucketing
используется для преодоления того, cons
что я упоминал в разделе о разделах. Это следует использовать, когда в столбце очень мало повторяющихся значений (пример - столбец первичного ключа). Это похоже на концепцию индекса по столбцу первичного ключа в СУБД. В нашей таблице мы можем взять Sales_Id
столбец для сегментирования. Это будет полезно, когда нам нужно запросить sales_id
столбец.
Ниже приведен синтаксис сегментации.
create table sales_table(sales_id int,trans_date date, amount int)
partitioned by (product_id varchar(10)) Clustered by(Sales_Id) into 3 buckets
Здесь мы дополнительно разделим данные на несколько файлов поверх разделов.
Поскольку мы указали 3
сегменты, каждый из них разделен на 3 файла product_id
. Он внутренне использует, modulo operator
чтобы определить, в каком ведре sales_id
следует хранить каждый из них. Например, для product_id='P1'
, то sales_id=1
будет храниться в 000001_0 файла (т.е. 1% 3 = 1), sales_id=2
будет храниться в 000002_0 файле (то есть, 2% 3 = 2), sales_id=3
будет храниться в 000000_0 файле (т.е. 3% 3 = 0) и т. Д.
hashCode()
строки в качестве хеш-функции? Может ли программист выбрать хеш-функцию?
Здесь есть отличные отзывы. Я хотел бы сделать его кратким, чтобы запомнить разницу между разделами и корзинами.
Обычно вы разбиваете на менее уникальный столбец. И ведро по самой уникальной колонке.
Пример, если вы рассматриваете население мира с указанием страны, имени человека и его биометрического идентификатора в качестве примера. Как вы можете догадаться, поле страны будет менее уникальным столбцом, а биометрический идентификатор будет наиболее уникальным столбцом. Поэтому в идеале вам нужно разделить таблицу по странам и разделить ее по биометрическому идентификатору.
Использование разделов в таблице Hive настоятельно рекомендуется по следующей причине:
Пример :-
Предположим, что входной файл (100 ГБ) загружен в таблицу temp-hive-table и содержит банковские данные из разных географических регионов.
Таблица улья без перегородки
Insert into Hive table Select * from temp-hive-table
/hive-table-path/part-00000-1 (part size ~ hdfs block size)
/hive-table-path/part-00000-2
....
/hive-table-path/part-00000-n
Проблема с этим подходом заключается в том, что он будет сканировать все данные для любого запроса, который вы запускаете в этой таблице. Время отклика будет большим по сравнению с другими подходами, в которых используются разделы и сегментирование.
Таблица улья с перегородкой
Insert into Hive table partition(country) Select * from temp-hive-table
/hive-table-path/country=US/part-00000-1 (file size ~ 10 GB)
/hive-table-path/country=Canada/part-00000-2 (file size ~ 20 GB)
....
/hive-table-path/country=UK/part-00000-n (file size ~ 5 GB)
Плюсы - здесь можно быстрее получить доступ к данным, когда дело доходит до запроса данных для конкретных географических транзакций. Минусы - вставку / запрос данных можно улучшить, разделив данные внутри каждого раздела. См. Вариант сегментирования ниже.
Стол-улей с перегородками и ведрами
Примечание. Создайте таблицу улья ..... с "CLUSTERED BY (Partiton_Column) в 5 сегментов"
Insert into Hive table partition(country) Select * from temp-hive-table
/hive-table-path/country=US/part-00000-1 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-2 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-3 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-4 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-5 (file size ~ 2 GB)
/hive-table-path/country=Canada/part-00000-1 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-2 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-3 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-4 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-5 (file size ~ 4 GB)
....
/hive-table-path/country=UK/part-00000-1 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-2 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-3 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-4 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-5 (file size ~ 1 GB)
Плюсы - Быстрая вставка. Более быстрый запрос.
Минусы - группирование приведет к созданию большего количества файлов. В некоторых конкретных случаях может быть проблема со многими небольшими файлами
Надеюсь, это поможет !!