

# Copia de datos entre DynamoDB y HDFS
<a name="EMRforDynamoDB.CopyingData.HDFS"></a>

Si tiene datos en una tabla de DynamoDB, puede usar Hive para copiarlos a Hadoop Distributed File System (HDFS).

Puede ser conveniente si va a ejecutar un trabajo de MapReduce que requiere datos de DynamoDB. Si copia los datos de DynamoDB a HDFS, Hadoop puede procesarlos utilizando en paralelo todos los nodos disponibles en el clúster de Amazon EMR. Una vez que se haya completado el trabajo de MapReduce, puede escribir los resultados de HDFS a DDB.

En los ejemplos siguientes, Hive leerá y escribirá en el siguiente directorio de HDFS: `/user/hadoop/hive-test`

**nota**  
Los ejemplos de esta sección se han escrito partiendo del supuesto de que ya ha llevado a cabo los pasos en [Tutorial: Uso de Amazon DynamoDB y Apache Hive](EMRforDynamoDB.Tutorial.md) y de que ya dispone de una tabla externa en DynamoDB llamada *ddb\_features*. 

**Topics**
+ [Copia de datos mediante el formato predeterminado de Hive](#EMRforDynamoDB.CopyingData.HDFS.DefaultFormat)
+ [Copia de datos con un formato especificado por el usuario](#EMRforDynamoDB.CopyingData.HDFS.UserSpecifiedFormat)
+ [Copia de datos sin mapeo de columnas](#EMRforDynamoDB.CopyingData.HDFS.NoColumnMapping)
+ [Acceso a los datos de HDFS](#EMRforDynamoDB.CopyingData.HDFS.ViewingData)

## Copia de datos mediante el formato predeterminado de Hive
<a name="EMRforDynamoDB.CopyingData.HDFS.DefaultFormat"></a>

**Example Desde DynamoDB a HDFS**  
Use una instrucción `INSERT OVERWRITE` para escribir directamente en HDFS.  

```
INSERT OVERWRITE DIRECTORY 'hdfs:///user/hadoop/hive-test'
SELECT * FROM ddb_features;
```
El archivo de datos de HDFS tiene este aspecto:  

```
920709^ASoldiers Farewell Hill^ASummit^ANM^A32.3564729^A-108.33004616135
1178153^AJones Run^AStream^APA^A41.2120086^A-79.25920781260
253838^ASentinel Dome^ASummit^ACA^A37.7229821^A-119.584338133
264054^ANeversweet Gulch^AValley^ACA^A41.6565269^A-122.83614322900
115905^AChacaloochee Bay^ABay^AAL^A30.6979676^A-87.97388530
```
Cada campo se separa por un carácter SOH (inicio del encabezado, 0x01). En el archivo, SOH aparece como **^A**.

**Example Desde HDFS a DynamoDB**  

1. Cree una tabla externa mapeada a los datos sin formato de HDFS.

   ```
   CREATE EXTERNAL TABLE hdfs_features_unformatted
       (feature_id       BIGINT,
       feature_name      STRING ,
       feature_class     STRING ,
       state_alpha       STRING,
       prim_lat_dec      DOUBLE ,
       prim_long_dec     DOUBLE ,
       elev_in_ft        BIGINT)
   LOCATION 'hdfs:///user/hadoop/hive-test';
   ```

1. Copie los datos en DynamoDB.

   ```
   INSERT OVERWRITE TABLE ddb_features
   SELECT * FROM hdfs_features_unformatted;
   ```

## Copia de datos con un formato especificado por el usuario
<a name="EMRforDynamoDB.CopyingData.HDFS.UserSpecifiedFormat"></a>

Si desea usar un carácter separador de campos distinto, puede crear una tabla externa que esté mapeada al directorio de HDFS. Puede utilizar esta técnica para crear archivos de datos con valores separados por comas (CSV).

**Example Desde DynamoDB a HDFS**  

1. Cree una tabla de Hive externa mapeada a HDFS. Al hacerlo, asegúrese de que los tipos de datos sean coherentes con los de la tabla de DynamoDB externa.

   ```
   CREATE EXTERNAL TABLE hdfs_features_csv
       (feature_id       BIGINT,
       feature_name      STRING ,
       feature_class     STRING ,
       state_alpha       STRING,
       prim_lat_dec      DOUBLE ,
       prim_long_dec     DOUBLE ,
       elev_in_ft        BIGINT)
   ROW FORMAT DELIMITED
   FIELDS TERMINATED BY ','
   LOCATION 'hdfs:///user/hadoop/hive-test';
   ```

1. Copie los datos de DynamoDB.

   ```
   INSERT OVERWRITE TABLE hdfs_features_csv
   SELECT * FROM ddb_features;
   ```
El archivo de datos de HDFS tiene este aspecto:  

```
920709,Soldiers Farewell Hill,Summit,NM,32.3564729,-108.3300461,6135
1178153,Jones Run,Stream,PA,41.2120086,-79.2592078,1260
253838,Sentinel Dome,Summit,CA,37.7229821,-119.58433,8133
264054,Neversweet Gulch,Valley,CA,41.6565269,-122.8361432,2900
115905,Chacaloochee Bay,Bay,AL,30.6979676,-87.9738853,0
```

**Example Desde HDFS a DynamoDB**  
Con una sola instrucción de HiveQL, puede rellenar la tabla de DynamoDB usando los datos de HDFS:  

```
INSERT OVERWRITE TABLE ddb_features
SELECT * FROM hdfs_features_csv;
```

## Copia de datos sin mapeo de columnas
<a name="EMRforDynamoDB.CopyingData.HDFS.NoColumnMapping"></a>

Puede copiar los datos de DynamoDB en formato sin procesar y escribirlos en HDFS sin especificar ningún tipo de datos ni mapeo de columnas. Puede utilizar este método para crear un archivo de los datos de DynamoDB y almacenarlos en HDFS.



**nota**  
Si la tabla de DynamoDB contiene atributos de tipo Map (mapeo), List (lista), Boolean (booleano) o Null (nulo), entonces este es el único modo de usar Hive para copiar datos de DynamoDB a HDFS.

**Example Desde DynamoDB a HDFS**  

1. Cree una tabla externa asociada con la tabla de DynamoDB. Esta instrucción de HiveQL no contiene ningún mapeo `dynamodb.column.mapping`.

   ```
   CREATE EXTERNAL TABLE ddb_features_no_mapping
       (item MAP<STRING, STRING>)
   STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
   TBLPROPERTIES ("dynamodb.table.name" = "Features");
   ```

   

1. Cree otra tabla externa asociada con el directorio de HDFS.

   ```
   CREATE EXTERNAL TABLE hdfs_features_no_mapping
       (item MAP<STRING, STRING>)
   ROW FORMAT DELIMITED
   FIELDS TERMINATED BY '\t'
   LINES TERMINATED BY '\n'
   LOCATION 'hdfs:///user/hadoop/hive-test';
   ```

1. Copie los datos de DynamoDB a HDFS.

   ```
   INSERT OVERWRITE TABLE hdfs_features_no_mapping
   SELECT * FROM ddb_features_no_mapping;
   ```
El archivo de datos de HDFS tiene este aspecto:  

```
Name^C{"s":"Soldiers Farewell Hill"}^BState^C{"s":"NM"}^BClass^C{"s":"Summit"}^BElevation^C{"n":"6135"}^BLatitude^C{"n":"32.3564729"}^BId^C{"n":"920709"}^BLongitude^C{"n":"-108.3300461"}
Name^C{"s":"Jones Run"}^BState^C{"s":"PA"}^BClass^C{"s":"Stream"}^BElevation^C{"n":"1260"}^BLatitude^C{"n":"41.2120086"}^BId^C{"n":"1178153"}^BLongitude^C{"n":"-79.2592078"}
Name^C{"s":"Sentinel Dome"}^BState^C{"s":"CA"}^BClass^C{"s":"Summit"}^BElevation^C{"n":"8133"}^BLatitude^C{"n":"37.7229821"}^BId^C{"n":"253838"}^BLongitude^C{"n":"-119.58433"}
Name^C{"s":"Neversweet Gulch"}^BState^C{"s":"CA"}^BClass^C{"s":"Valley"}^BElevation^C{"n":"2900"}^BLatitude^C{"n":"41.6565269"}^BId^C{"n":"264054"}^BLongitude^C{"n":"-122.8361432"}
Name^C{"s":"Chacaloochee Bay"}^BState^C{"s":"AL"}^BClass^C{"s":"Bay"}^BElevation^C{"n":"0"}^BLatitude^C{"n":"30.6979676"}^BId^C{"n":"115905"}^BLongitude^C{"n":"-87.9738853"}
```
Cada campo comienza por un carácter STX (inicio del texto, 0x02) y termina con un carácter ETX (final del texto, 0x03). En el archivo, STX aparece como **^B** y ETX aparece como **^C**.

**Example Desde HDFS a DynamoDB**  
Con una sola instrucción de HiveQL, puede rellenar la tabla de DynamoDB usando los datos de HDFS:  

```
INSERT OVERWRITE TABLE ddb_features_no_mapping
SELECT * FROM hdfs_features_no_mapping;
```

## Acceso a los datos de HDFS
<a name="EMRforDynamoDB.CopyingData.HDFS.ViewingData"></a>

HDFS es un sistema de archivos distribuido, accesible para todos los nodos del clúster de Amazon EMR. Si usa SSH para conectarse al nodo líder, puede usar las herramientas de línea de comandos para acceder a los datos que Hive escribió en HDFS.

HDFS no es lo mismo que el sistema de archivos local del nodo líder. No se puede trabajar con los archivos y directorios de HDFS mediante los comandos de Linux estándar (tales como `cat`, `cp`, `mv` o `rm`). En lugar de ello, estas tareas se llevan a cabo usando el comando `hadoop fs`.

Los pasos siguientes se han escrito partiendo del supuesto de que ha copiado los datos de DynamoDB a HDFS por medio de uno de los procedimientos de esta sección.

1. Si tiene abierto el símbolo del sistema de Hive, salga y cambie al símbolo del sistema de Linux.

   ```
   hive> exit;
   ```

1. Muestre el contenido del directorio /user/hadoop/hive-test en HDFS. (Aquí es donde Hive ha copiado los datos de DynamoDB).

   ```
   hadoop fs -ls /user/hadoop/hive-test
   ```

   El aspecto de la respuesta debe ser parecido al siguiente:

   ```
   Found 1 items
   -rw-r--r-- 1 hadoop hadoop 29504 2016-06-08 23:40 /user/hadoop/hive-test/000000_0
   ```

   El nombre de archivo (*000000\_0*) lo genera el sistema.

1. Visualice el contenido del archivo :

   ```
   hadoop fs -cat /user/hadoop/hive-test/000000_0
   ```
**nota**  
En este ejemplo, el archivo es relativamente pequeño (aproximadamente, 29 KB). Tenga cuidado cuando utilice este comando con archivos que sean muy grandes o contengan caracteres no imprimibles.

1. (Opcional) Puede copiar el archivo de datos de HDFS al sistema de archivos local en el nodo maestro. Después de hacerlo, puede utilizar las utilidades estándar de la línea de comandos de Linux para trabajar con los datos del archivo.

   ```
   hadoop fs -get /user/hadoop/hive-test/000000_0
   ```

   Este comando no sobrescribirá el archivo.
**nota**  
El sistema de archivos local del nodo líder tiene una capacidad limitada. No utilice este comando con archivos más grandes que el espacio disponible en el sistema de archivos local.