Sqoop Import Split by Column Тип данных

Должен ли тип данных Разделить по столбцам при импорте sqoop всегда быть числовым типом данных (целое число, bignint, числовое значение)? Разве это не может быть строка?

3 ответа

Решение

Да, вы можете разделить на любой не числовой тип данных.

Но это не рекомендуется.

ЗАЧЕМ?

Для разделения данных Sqoop запускает

SELECT MIN(col1), MAX(col2) FROM TABLE

затем разделите его по количеству картографов.

Теперь возьмите пример целого числа как --split-by колонка

Таблица имеет некоторые id столбец со значением от 1 до 100, и вы используете 4 картографов (-m 4 в вашей команде sqoop)

Sqoop получить значения MIN и MAX, используя:

SELECT MIN(id), MAX(id) FROM TABLE

ВЫХОД:

+1100

Разбить на целое число легко. Вы сделаете 4 части:

  • 1-25
  • 25-50
  • 51-75
  • 76-100

Теперь строка как --split-by колонка

Таблица имеет некоторые name столбец со значением "dev" для "sam" и вы используете 4 мапперов (-m 4 в вашей команде sqoop)

Sqoop получить значения MIN и MAX, используя:

SELECT MIN(id), MAX(id) FROM TABLE

ВЫХОД:

DEV, сэм

Теперь, как это будет разделено на 4 части. Согласно документам sqoop,

/**
   * This method needs to determine the splits between two user-provided
   * strings.  In the case where the user's strings are 'A' and 'Z', this is
   * not hard; we could create two splits from ['A', 'M') and ['M', 'Z'], 26
   * splits for strings beginning with each letter, etc.
   *
   * If a user has provided us with the strings "Ham" and "Haze", however, we
   * need to create splits that differ in the third letter.
   *
   * The algorithm used is as follows:
   * Since there are 2**16 unicode characters, we interpret characters as
   * digits in base 65536. Given a string 's' containing characters s_0, s_1
   * .. s_n, we interpret the string as the number: 0.s_0 s_1 s_2.. s_n in
   * base 65536. Having mapped the low and high strings into floating-point
   * values, we then use the BigDecimalSplitter to establish the even split
   * points, then map the resulting floating point values back into strings.
   */

И вы увидите предупреждение в коде:

LOG.warn("Generating splits for a textual index column.");
LOG.warn("If your database sorts in a case-insensitive order, "
    + "this may result in a partial import or duplicate records.");
LOG.warn("You are strongly encouraged to choose an integral split column.");

В случае примера Integer все преобразователи получат сбалансированную нагрузку (все получат 25 записей из RDBMS).

В случае строки вероятность сортировки данных меньше. Таким образом, трудно дать одинаковые нагрузки всем картографам.


В двух словах, перейдите к целому столбцу как --split-by колонка.

Да, мы можем это сделать, но это не рекомендуется из-за проблем с производительностью. поскольку мы знаем, что SQOOP запускает граничный запрос « выберите min(столбец pk / split-by), max(столбец pk / split-by) из таблицы, где условие » для расчета размера разделения для картографов. split-size = (макс. - мин.)/количество мапперов

Допустим, есть таблица под названием employee.

      id      name  age
  1       baba  20
  2       kishor 30
  3       jay    40
  ..........
  10001   pk    60

Сенарио 1:

Выполнение разделения по столбцу id

В этом случае SQOOP запустит граничный запрос select min(id),max(id) от сотрудника, чтобы вычислить размер разделения.

      min = 1
max = 100001

default no of mapper = 4

split-size = (10001-1)/4 = 25000

so each mapper will process 25000 lines of record.
mapper 1:  1 - 25000
mapper 2:  25001-50000
mapper 3:  50001-75000
mapper 4:  75001-100000

поэтому SQOOP очень легко разделить записи, если у нас есть интегральный столбец.

Сценарий 2:

Выполнение разделения по столбцу имени

В этом случае SQOOP запустит «выбрать мин. (имя), макс. (имя) из сотрудника», чтобы вычислить размер разделения.

      min = baba, max= pk

SQOOP не сможет легко вычислить размер разделения, потому что min и max имеют текстовые значения ((min-max)/no of mappers), поэтому он будет запускать класс TextSplitter для выполнения разделения, что создаст дополнительные накладные расходы и может повлиять на производительность.

Примечание. Нам нужно передать дополнительный аргумент -D org.apache.sqoop.splitter.allow_text_splitter= true , чтобы использовать класс TextSplitter.

Нет, он должен быть числовым, потому что в соответствии со спецификациями: "По умолчанию sqoop будет использовать запрос select min(), max() from для определения границ для создания разбиений". Альтернативой является использование --boundary-query, который также требует числовых столбцов. В противном случае задание Sqoop не будет выполнено. Если у вас нет такого столбца в вашей таблице, единственный обходной путь - использовать только 1 маппер: "-m 1".

Другие вопросы по тегам