

# Copiar dados entre o DynamoDB e o HDFS
<a name="EMRforDynamoDB.CopyingData.HDFS"></a>

Caso tenha dados em uma tabela do DynamoDB, você poderá usar o Hive para copiar os dados para o Hadoop Distributed File System (HDFS).

Você poderá fazer isso se estiver executando um trabalho do MapReduce que exige dados do DynamoDB. Se você copiar os dados do DynamoDB para o HDFS, o Hadoop poderá processá-los, usando todos os nós disponíveis no cluster do Amazon EMR em paralelo. Quando o trabalho do MapReduce for concluído, você poderá gravar os resultados do HDFS no DDB.

Nos exemplos a seguir, o Hive irá ler e gravar no diretório HDFS a seguir: `/user/hadoop/hive-test`

**nota**  
Os exemplos nesta seção são escritos sob a premissa de que você seguiu as etapas de [Tutorial: Como trabalhar com o Amazon DynamoDB e o Apache Hive](EMRforDynamoDB.Tutorial.md) e tem uma tabela externa chamada *ddb\_features* no DynamoDB. 

**Topics**
+ [Copiar dados usando o formato padrão do Hive](#EMRforDynamoDB.CopyingData.HDFS.DefaultFormat)
+ [Copiar dados com um formato especificado pelo usuário](#EMRforDynamoDB.CopyingData.HDFS.UserSpecifiedFormat)
+ [Copiar dados sem um mapeamento de colunas](#EMRforDynamoDB.CopyingData.HDFS.NoColumnMapping)
+ [Acessar dados no HDFS](#EMRforDynamoDB.CopyingData.HDFS.ViewingData)

## Copiar dados usando o formato padrão do Hive
<a name="EMRforDynamoDB.CopyingData.HDFS.DefaultFormat"></a>

**Example Do DynamoDB para o HDFS**  
Use uma instrução `INSERT OVERWRITE` para gravar diretamente para o HDFS.  

```
INSERT OVERWRITE DIRECTORY 'hdfs:///user/hadoop/hive-test'
SELECT * FROM ddb_features;
```
O arquivo de dados do HDFS é semelhante a:  

```
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 é separado por um caractere SOH (início de cabeçalho, 0x01). No arquivo, SOH aparece como **^A**.

**Example Do HDFS para o DynamoDB**  

1. Crie uma tabela externa mapeada para os dados não formatados no 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 os dados para o DynamoDB.

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

## Copiar dados com um formato especificado pelo usuário
<a name="EMRforDynamoDB.CopyingData.HDFS.UserSpecifiedFormat"></a>

Caso deseje usar um caractere separador de campos diferente, você poderá criar uma tabela externa mapeada no diretório do HDFS. Você pode usar essa técnica para a criação de arquivos de dados com valores separados por vírgulas (CSV).

**Example Do DynamoDB para o HDFS**  

1. Crie uma tabela externa do Hive mapeada no HDFS. Ao fazer isso, certifique-se de que os tipos de dados sejam consistentes com os da tabela externa do DynamoDB.

   ```
   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 os dados do DynamoDB.

   ```
   INSERT OVERWRITE TABLE hdfs_features_csv
   SELECT * FROM ddb_features;
   ```
O arquivo de dados do HDFS é semelhante a:  

```
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 Do HDFS para o DynamoDB**  
Com uma única instrução HiveQL, você pode preencher a tabela do DynamoDB usando os dados do HDFS:  

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

## Copiar dados sem um mapeamento de colunas
<a name="EMRforDynamoDB.CopyingData.HDFS.NoColumnMapping"></a>

Você pode copiar dados do DynamoDB em um formato bruto e gravá-los no HDFS sem especificar quaisquer tipos de dados ou mapeamento de coluna. Você pode usar esse método para criar um arquivo com dados do DynamoDB e armazená-lo no HDFS.



**nota**  
Se a sua tabela do DynamoDB contém atributos do tipo Map, List, Boolean ou Null, essa é a única forma possível de usar o Hive para copiar dados do DynamoDB para o HDFS.

**Example Do DynamoDB para o HDFS**  

1. Crie uma tabela externa associada à sua tabela do DynamoDB. (Não há `dynamodb.column.mapping` nesta instrução HiveQL.)

   ```
   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. Crie outra tabela externa associada ao seu diretório 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 os dados do DynamoDB para o HDFS.

   ```
   INSERT OVERWRITE TABLE hdfs_features_no_mapping
   SELECT * FROM ddb_features_no_mapping;
   ```
O arquivo de dados do HDFS é semelhante a:  

```
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 começa com um caractere STX (início de texto, 0x02) e termina com um caractere ETX (fim de texto, 0x03). No arquivo, o caractere STX é mostrado como **^B** e o caractere ETX é mostrado como **^C**.

**Example Do HDFS para o DynamoDB**  
Com uma única instrução HiveQL, você pode preencher a tabela do DynamoDB usando os dados do HDFS:  

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

## Acessar dados no HDFS
<a name="EMRforDynamoDB.CopyingData.HDFS.ViewingData"></a>

O HDFS é um sistema de arquivos distribuído, acessível para todos os nós do cluster do Amazon EMR. Caso use o SSH para se conectar ao nó líder, você poderá usar as ferramentas de linha de comando para acessar os dados gravados pelo Hive no HDFS.

O HDFS não é a mesma coisa que o sistema de arquivos local no nó líder. Você não pode trabalhar com arquivos e diretórios no HDFS usando os comandos padrão do Linux (como `cat`, `cp`, `mv` ou `rm`). Em vez disso, você executa essas tarefas usando o comando `hadoop fs`.

As etapas a seguir são escritas sob a premissa de que você copiou os dados do DynamoDB para o HDFS usando um dos procedimentos desta seção.

1. Se você estiver no momento no prompt de comando do Hive, saia do prompt de comando do Linux.

   ```
   hive> exit;
   ```

1. Liste o conteúdo do diretório /user/hadoop/hive-test no HDFS. (Esse é o local para o qual o Hive copiou os dados do DynamoDB.)

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

   A resposta deve ter a seguinte aparência:

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

   O nome do arquivo (*000000\_0*) é gerado pelo sistema.

1. Visualize o conteúdo do arquivo :

   ```
   hadoop fs -cat /user/hadoop/hive-test/000000_0
   ```
**nota**  
Neste exemplo, o arquivo é relativamente pequeno (aproximadamente 29 KB). Tenha cuidado ao usar este comando com arquivos que são muito grandes ou contêm caracteres não imprimíveis.

1. (Opcional) Você pode copiar o arquivo de dados do HDFS para o sistema de arquivos local no nó líder. Depois de fazer isso, você pode usar os utilitários de linha de comando padrão do Linux para trabalhar com os dados no arquivo.

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

   Este comando não substituirá o arquivo.
**nota**  
O sistema de arquivos local no nó líder tem capacidade limitada. Não use este comando com arquivos maiores do que o espaço disponível no sistema de arquivos local.