hadoop - poner - clave primaria compuesta postgresql
ImportaciĆ³n de Sqoop: clave primaria compuesta y clave primaria textual (1)
Especifique la columna dividida manualmente. La columna dividida no es necesariamente igual a PK. Puede tener PK complejo y alguna columna dividida int. Puede especificar cualquier columna entera o incluso una función simple (alguna función simple como subcadena o conversión, no agregación o analítica). La columna dividida preferiblemente debe ser un número entero distribuido uniformemente .
Por ejemplo, si su columna dividida contiene pocas filas con valor -1 y 10M filas con valores 10000 - 10000000 y num-mappers = 8, entonces sqoop dividirá el conjunto de datos entre los mapeadores de manera no uniforme:
- El primer mapeador obtendrá algunas filas con -1,
- Los mapeadores del 2º al 7º obtendrán 0 filas,
- El octavo mapeador obtendrá casi 10 millones de filas,
eso dará como resultado un sesgo de datos y el octavo mapeador se ejecutará para siempre o incluso fallará. Y también tengo duplicados cuando se usa una columna dividida no entera con MS-SQL . Entonces, use una columna dividida entera. En su caso con una tabla con solo dos columnas varchar, puede
(1) agregue el sustituto int PK y úselo también como una división o
(2) divida sus datos manualmente usando una consulta personalizada con la cláusula
WHERE
y ejecute sqoop varias veces con num-mappers = 1, o
(3) aplique alguna función
determinista de no agregación entera
a su columna varchar, por ejemplo cast (substr (...) como int) o
second(timestamp_col)
o
datepart(second, date)
, etc. como columna dividida.
Pila: HDP-2.3.2.0-2950 instalado con Ambari 2.1
El esquema de base de datos de origen está en el servidor sql y contiene varias tablas que tienen clave principal como:
- Un varchar
- Compuesto: dos columnas varchar o una varchar + una columna int o dos columnas int. Hay una mesa grande con? filas que tienen tres columnas en la PK una int + dos columnas varchar
Según la documentación de 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.
La primera pregunta es: ¿Qué se espera al ''elegir manualmente una columna de división''? ¿Cómo puedo sacrificar el paquete y simplemente usar una columna o me falta algún concepto?
La tabla de SQL Server es (solo dos columnas y forman una clave primaria compuesta):
ChassiNo varchar(8) Unchecked
ECU_Name nvarchar(15) Unchecked
Continué con la importación, la tabla de origen tiene 7909097 registros :
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
Las advertencias preocupantes y las entradas y registros incorrectos del mapeador:
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.
Mesa creada:
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'';
Resultado horrible (sin errores) - PROBLEMA: 15818167 vs 7909097 (servidor sql) registros:
> 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
Sorprendentemente, obtuve una precisión o una falta de coincidencia de menos de 10 registros si la clave compuesta consistía en un int (que se usó para dividir) ¡pero todavía estoy preocupado por ellos también!
¿Cómo debo proceder?