Импорт Sqoop: составной первичный ключ и текстовый первичный ключ

Стек: установлен HDP-2.3.2.0-2950 с использованием Ambari 2.1.

Исходная схема БД находится на сервере sql и содержит несколько таблиц, которые имеют первичный ключ как:

  • Варчар
  • Составной — два столбца varchar или один varchar + один столбец int или два столбца int. Есть большой стол с ? строки, которые имеют три столбца в PK один int + два столбца varchar

Согласно документации Sqoop:

Sqoop cannot currently split on multi-column indices. If your table has no index column, or has a multi-column key, then you must also manually choose a splitting column.

Первый вопрос: что ожидается от «ручного выбора столбца разделения» - как я могу пожертвовать pk и просто использовать один столбец, или мне не хватает какой-то концепции?

Таблица SQL Server (только два столбца, и они образуют составной первичный ключ):

ChassiNo    varchar(8)  Unchecked
ECU_Name    nvarchar(15)    Unchecked

Я продолжил импорт, исходная таблица содержит 7909097 записей:

sqoop import --connect 'jdbc:sqlserver://somedbserver;database=somedb' --username someusname --password somepass --as-textfile --fields-terminated-by '|&|'  --table ChassiECU --num-mappers 8  --warehouse-dir /dataload/tohdfs/reio/odpdw/may2016 --verbose

Тревожные предупреждения и неправильные входные данные и записи картографа:

16/05/13 10:59:04 WARN manager.CatalogQueryManager: The table ChassiECU contains a multi-column primary key. Sqoop will default to the column ChassiNo only for this job.
16/05/13 10:59:08 WARN db.TextSplitter: Generating splits for a textual index column.
16/05/13 10:59:08 WARN db.TextSplitter: If your database sorts in a case-insensitive order, this may result in a partial import or duplicate records.
16/05/13 10:59:08 WARN db.TextSplitter: You are strongly encouraged to choose an integral split column.
16/05/13 10:59:38 INFO mapreduce.Job: Counters: 30
        File System Counters
                FILE: Number of bytes read=0
                FILE: Number of bytes written=1168400
                FILE: Number of read operations=0
                FILE: Number of large read operations=0
                FILE: Number of write operations=0
                HDFS: Number of bytes read=1128
                HDFS: Number of bytes written=209961941
                HDFS: Number of read operations=32
                HDFS: Number of large read operations=0
                HDFS: Number of write operations=16
        Job Counters
                Launched map tasks=8
                Other local map tasks=8
                Total time spent by all maps in occupied slots (ms)=62785
                Total time spent by all reduces in occupied slots (ms)=0
                Total time spent by all map tasks (ms)=62785
                Total vcore-seconds taken by all map tasks=62785
                Total megabyte-seconds taken by all map tasks=128583680
        Map-Reduce Framework
                Map input records=15818167
                Map output records=15818167
                Input split bytes=1128
                Spilled Records=0
                Failed Shuffles=0
                Merged Map outputs=0
                GC time elapsed (ms)=780
                CPU time spent (ms)=45280
                Physical memory (bytes) snapshot=2219433984
                Virtual memory (bytes) snapshot=20014182400
                Total committed heap usage (bytes)=9394716672
        File Input Format Counters
                Bytes Read=0
        File Output Format Counters
                Bytes Written=209961941
16/05/13 10:59:38 INFO mapreduce.ImportJobBase: Transferred 200.2353 MB in 32.6994 seconds (6.1235 MB/sec)
16/05/13 10:59:38 INFO mapreduce.ImportJobBase: Retrieved 15818167 records.

Создал таблицу:

CREATE EXTERNAL TABLE IF NOT EXISTS ChassiECU(`ChassiNo` varchar(8),
`ECU_Name` varchar(15)) ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'  LOCATION '/dataload/tohdfs/reio/odpdw/may2016/ChassiECU';

Ужасный результат (без ошибок) --ПРОБЛЕМА: записи 15818167 против 7909097 (сервер sql):

 > select count(1) from ChassiECU;
Query ID = hive_20160513110313_8e294d83-78aa-4e52-b90f-b5640268b8ac
Total jobs = 1
Launching Job 1 out of 1
Tez session was closed. Reopening...
Session re-established.
Status: Running (Executing on YARN cluster with App id application_1446726117927_0059)
--------------------------------------------------------------------------------
        VERTICES      STATUS  TOTAL  COMPLETED  RUNNING  PENDING  FAILED  KILLED
--------------------------------------------------------------------------------
Map 1 ..........   SUCCEEDED     14         14        0        0       0       0
Reducer 2 ......   SUCCEEDED      1          1        0        0       0       0
--------------------------------------------------------------------------------
VERTICES: 02/02  [==========================>>] 100%  ELAPSED TIME: 6.12 s
--------------------------------------------------------------------------------
OK
_c0
15818167

Удивительно, но я получил либо точное, либо несоответствие менее 10 записей, если составной ключ состоял из int (который использовался для разделения), но я все еще опасаюсь этого!

Как мне поступить?


person Kaliyug Antagonist    schedule 13.05.2016    source источник
comment
Привет. Из вашего требования я понимаю, что вы просто хотите переместить содержимое ChassiECU в Hive для таблицы с многотипным составным ключом. Вместо --table <table name> option вы можете использовать --query select * from ChassiECU where \$CONDITIONS" и выбрать один из ключевых столбцов (предпочтительно с наименьшей кардинальностью) в опции --split-by <column>. Также проверьте разделители столбцов в sqoop import и тот, который используется в hive DDL.   -  person Kfactor21    schedule 14.05.2016
comment
Одним из других вариантов было бы создание представления, если это возможно, поверх вашей таблицы с новым ключевым столбцом, содержащим конкатенированные значения всех ваших ключевых столбцов в один столбец. Затем это можно использовать в импорте sqoop.   -  person Kfactor21    schedule 14.05.2016
comment
Информация о столе. добавлено, я не уверен, применимы ли предложенные вами предложения к таблице, можете ли вы проверить?   -  person Kaliyug Antagonist    schedule 16.05.2016


Ответы (1)


Укажите разделенный столбец вручную. Столбец разделения не обязательно равен PK. У вас может быть сложный PK и некоторый столбец int Split. Вы можете указать любой целочисленный столбец или даже простую функцию (какую-нибудь простую функцию, такую ​​как подстрока или преобразование, а не агрегацию или аналитику). Разделение столбца предпочтительно должно быть равномерным целым числом.

Например, если ваш разделенный столбец содержит несколько строк со значением -1 и 10 миллионов строк со значениями 10000 - 10000000 и num-mappers=8, тогда sqoop разделит набор данных между картографами неравномерно:

  • 1-й маппер получит несколько строк с -1,
  • со 2-го по 7-й маппер получит 0 строк,
  • 8-й маппер получит почти 10 миллионов строк,

это приведет к перекосу данных, и 8-й картограф будет работать вечно или даже выйдет из строя. И я также получил дубликаты при использовании нецелочисленного разделения столбца с MS-SQL. Итак, используйте целочисленный разделенный столбец. В вашем случае с таблицей только с двумя столбцами varchar вы можете либо

(1) добавить суррогатный int PK и использовать его также как разбиение или

(2) разделите ваши данные вручную, используя пользовательский запрос с предложением WHERE, и несколько раз запустите sqoop с num-mappers=1, или

(3) примените некоторую детерминированную целочисленную функцию без агрегации к столбцу varchar, например, cast(substr(...) as int) или second(timestamp_col) или datepart(second, date) и т. д. в качестве разделенного столбца. Для Teradata вы можете использовать номер AMP: HASHAMP (HASHBUCKET (HASHROW (string_column_list))), чтобы получить целочисленный номер AMP из списка нецелочисленных ключей и полагаться на распределение TD между AMP. Я использовал простые функции напрямую как разделенные, не добавляя их в запрос в качестве производного столбца.

person leftjoin    schedule 23.05.2016
comment
@iliketocode Я хочу использовать 3-й параметр в моей команде sqoop в параметре split-by. Есть ли какая-либо документация для --split-by с функцией sql, на которую я могу сослаться? так как я получаю сообщение о том, что столбец не найден, если я даю его так: разделить на приведение (order_number как int), я также использовал одинарные кавычки, и это та же ошибка - person Krish; 08.07.2018
comment
@Krish Лучше задайте свой вопрос не в комментарии и предоставьте свой код, чтобы сообщество могло помочь. Должно работать и, возможно, ошибка в каком-то другом месте. - person leftjoin; 08.07.2018
comment
его уже там с помощью функции sql"> stackoverflow.com/questions/51217677/ - person Krish; 09.07.2018
comment
@leftjoin .. хороший вопрос и действительно отличный ответ - person vikrant rana; 27.05.2019