Buscar

TECNOLOGIA PARA BIG DATA

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 56 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 56 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 56 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

MBA EM GESTÃO DE INOVAÇÃO, TECNOLOGIA E EMPREENDEDORISMO
MODULO 3
TECNOLOGIA PARA BIG DATA
1 - Introdução a Big Data
Ao analisarmos as notícias e tendências do mundo da tecnologia da informação podemos perceber que existe um termo que está sendo repetido com muita frequência: "Big Data". Esse é um campo de estudo empolgante, que engloba vários aspectos tecnológicos nem sempre bem compreendidos. Nesta unidade, você será apresentado a conceitos que envolvem esse maravilhoso mundo e que serão importantes para a compreensão do funcionamento de seu ecossistema. 
A primeira impressão que o termo Big Data nos passa é que é uma tecnologia para trabalhar com grande volume de dados. Essa ideia é, em parte, verdadeira, mas esse campo abrange muito mais do que isso.
Sistemas comerciais e da área científica vêm trabalhando com grandes volumes de dados há muito tempo. Algumas áreas da ciência, como a astronomia, geologia e meteorologia, produzem um volume enorme de dados que são processados com precisão há muito tempo, muito antes do termo Big Data surgir. Big Data não deve ser definido - apenas - em número de terabytes ou petabytes. A quantidade de bytes pode mudar dependendo do tipo de dados, do setor em que a tecnologia está sendo aplicada ou da própria evolução da  tecnologia. É interessante notar, entretanto, que um estudo da empresa de pesquisa IDC aponta que até 2025 teremos produzido 175 zettabytes de bytes, isso equivale a 175 trilhões de gigabytes.
Dilúvio de dados
Para que possamos entender melhor o que significa esse volume de dados fazemos, no quadro abaixo, uma analogia  de bytes convertido em grãos de arroz. Nessa analogia, um byte é equivalente a um grão de arroz. 
 
	Byte
	1 grão de arroz
	Kilobyte
	Uma xícara de arroz
	Megabyte
	Oito sacos de arroz
	Gigabyte
	Um container de arroz
	Terabyte
	Dois navios cargueiros
	Petabyte
	Suficiente para cobrir a cidade de Campinas.
	Exabyte
	Suficiente para cobrir os estados de Minas Gerais, Rio de Janeiro, Espírito Santo e São Paulo.
	Zettabyte
	Preenche o oceano Pacífico.
Quadro 1 – Analogia entre bytes e grãos de arroz.
Fonte: Adaptado de WELLMAN (2013).
Outro desafio com que o Big Data lida é a variedade de fontes de dados. Apenas 10% (dez por cento) dos dados disponíveis são estruturados, isto é, estão no formato tradicional de tuplas (linhas ou registros) em um banco de dados, os outros 90% (noventa por cento) dos dados estão em formato não-estruturados, sendo que esses últimos são provenientes de várias fontes como: contratos, formulários, imagens, manuais, raios-x, e-mails, PDFs, mensagens instantâneas, documentos, páginas da WEB, áudio e vídeo.
Figura 01 – A maioria dos dados disponíveis são não-estruturados
Tratar grandes volumes de dados e grande variedade de dados nos leva a perguntar: qual é o tempo de resposta desse ambiente? Quanto tempo estamos dispostos a esperar por uma resposta do sistema? É comum que as respostas a essas perguntas seja "o mais rápido possível, de preferência instantaneamente".
Segundo o McKinsey Global Institute (2011), Big Data refere-se:  “ao conjunto de dados cujo tamanho está além da capacidade de análise, captura, armazenamento e gerenciamento de uma ferramenta desenvolvida por um software típico” (McKINSEY GLOBAL INSTITUTE, 2011, p.27).
Os V’s do Big Data
Podemos dizer, então, que Big Data trata de grandes volumes de dados (Volume), com informações vindas de diversas fontes (Variedade) e produzem respostas rápidas (Velocidade). Nesta unidade, iremos considerar apenas estes três requisitos.
Para abordar os três requisitos que definimos para esta unidade, precisamos nos colocar questões que pertencem a dois aspectos que envolvem Big Data:
Declaração de problema: Como processar Big Data usando o estado-da-arte da tecnologia atual sem “estourar” o limite de tempo e o orçamento?
Onde está o "gargalo" do processamento? A velocidade das CPUs está cada vez maior, mas a velocidade de acesso a disco ou a volumes de discos convencionais, ainda é lenta. O aumento da velocidade de CPU não beneficia muito os programas que têm necessidade de acessar grandes volumes de dados.
Em 2000, Eric Brewer, em sua palestra na Universidade de Berkeley, em São Francisco, nos Estados Unidos,(checar ortografia) propôs o teorema CAP. Essencialmente o teorema afirma que em qualquer sistema distribuído stateful é preciso escolher entre 
 - Consistency (consistência forte). Todos os nós veem os mesmos dados ao mesmo tempo.
 - Availability (alta disponibilidade). Toda solicitação recebe uma resposta, seja ela bem-sucedida ou não. 
- Network Partition Tolerance (tolerância a particionamento dos dados na rede). O sistema continua funcionando mesmo que mensagens sejam perdidas ou parte do sistema falhe.
Entre essas três propriedades, somente duas podem ser garantidas ao mesmo tempo
Lembramos que sistemas de banco de dados tradicionais possuem consistência forte e alta disponibilidade, mas não trabalham muito bem com tolerância a particionamento dos dados na rede. Já o sistema de bancos de dados não-relacionais são sistemas altamente tolerantes a falhas, desde que exista um grande número de servidores suportando o sistema, fornecem disponibilidade, mas apenas consistência eventual.
Em relação à tolerância a particionamento, veremos como ela pode ser fornecida pelo  Hadoop Distributed File System (HDFS). O Hadoop Distributed File System (HDFS) é um sistema de arquivos altamente tolerante a falhas, projetado para executar em hardware, padrão de baixo custo. O HDFS disponibiliza acesso de alto rendimento para os dados do aplicativo e é adequado para aplicativos com grandes conjuntos de dados. 
Segundo a Hadoop, “Hadoop é um storage confiável e um sistema analítico” [2014], composto por duas partes essenciais:
-Hadoop Distributed Filesystem (HDFS), sistema de arquivos distribuído e confiável, responsável pelo armazenamento dos dados.
-Hadoop MapReduce, responsável pela análise e processamento dos dados. 
Uma curiosidade: o nome “Hadoop” veio do elefante de pelúcia que pertencia ao filho do criador, Doug Cutting.
Vamos entender melhor uma dessas duas partes essenciais, o MapReduce?
Segundo a IBM [2009], MapReduce é um “Modelo de programação que permite o processamento de dados massivos em um algorítmo paralelo e distribuído, geralmente em um cluster de computadores” (IBM, 2009, p. 2). MapReduce é baseado nas operações de Map e Reduce de linguagens funcionais como o LISP. Ele trata os dados como um conjunto de pares <Key, Value> (chave/valor).  As operações de entrada leem os dados e geram os pares <Key, Value> e o usuário fornece duas funções Map e Reduce, que são chamadas em tempo de execução.
Em uma operação típica de Map, o nó principal recebe os dados, divide em partes menores e envia aos outros nós para serem processados. Ao final do processamento estes nós devolvem o resultado ao nó principal. O nó principal o obtêm uma lista de pares <Key, Value>, processa os pares e gera um conjunto de pares <Key, Value> intermediário. O nó principal, então, repassa o valor intermediário para a função Reduce. Cada par é processado em paralelo.
Em uma operação típica de Reduce, o nó principal combina as respostas obtidas pelos outros nós gerando o resultado final do processamento. O nó principal processa todos os valores associados com a mesma <Key> e o nó principal mescla os valores para formar um conjunto de valores possivelmente menor. Geralmente, apenas um valor de saída de 0 ou 1 é produzido a cada chamada Reduce. Os valores intermediários são fornecidos à função Reduce do usuário por um iterador, o que permite identificar listas de valores que são grandes demais para a memória.
 
Atividade extra
Nome da atividade: Onde usar Big Data?
Suponha que que você recebeu um arquivo em formato texto com o tamanho de 1 gigabyte (1 GB). Esse arquivo pode ser aberto por um software de planilha eletrônica como, por exemplo, o Microsoft Excel. O tempo gasto para abrir esse arquivo é de quinze (15) minuto.
Baseado nesse cenário, você recomendaria o uso de ferramentasde Big Data para processar esse arquivo? Escreva um texto justificando sua escolha.
2 - Introdução a HDFS
Para (APACHE, 2018), o Hadoop Distributed File System (HDFS) é um sistema de arquivos altamente tolerante a falhas projetado para executar em hardware padrão de baixo custo. Estende a capacidade de armazenamento de uma única máquina distribuindo os dados, de forma redundante, em um cluster de computadores de baixo custo.
É possível imaginar o HDFS como uma camada de software sobre um sistema de arquivos nativos. Cabe ressaltar, no entanto, que, devido a natureza complexa de um sistema de arquivos distribuídos, o HDFS oferece um complexidade maior do que sistemas de arquivos tradicionais. Para simplificar o seu uso, o Hadoop generaliza a camada de armazenagem permitindo que interaja tanto com os sistemas locais quanto outros tipos de armazenagem.
O HDFS disponibiliza acesso de alto rendimento para os dados do aplicativo e é adequado para aplicativos com grandes conjuntos de dados. Algumas de suas características (BENGFORT, 2016):
· Pouco eficiente para acesso aleatório.
· Otimizado pra leituras de grandes arquivos.
· É mais eficiente com um número reduzido de arquivos grandes do que com muitos arquivos pequenos.
· Implementa o padrão WORM (Write Once, Read Many), ou escreva uma vez, leia várias vezes. 
Namenode
Como dito anteriormente, o HDFS também trabalha com a arquitetura MASTER/SLAVE. Os serviços MASTER é denominado de NameNode (APACHE, 2018).
Segundo (BENGFORT, 2016) o acesso aos dados por uma aplicação é sempre começa pelo acesso ao NameNode.
Figura 3 – Aplicação acessando NameNode Fonte: Autor (2018), baseado em descrição de (APACHE, 2018).
O NameNode é o nó mestre. Nele são armazenados os metadados dos arquivos, a localização de cada arquivo no cluster, a estrutura da árvore de diretórios do sistema e o mapa dos chunks dos DataNodes (APACHE, 2018). 
Para (APACHE, 2018), é responsabilidade do NameNode efetuar o rebalanceamento dos dados, caso algum dos nós apresente falha. A verificação dos nós é feita através de um mecanismo denominado heartbeat (batida do coração).
O heartbeat nada mais é que um conjunto de dados contendo uma lista de todos os blocos de dados de um nó. Por padrão, a cada três segundos os nós que contêm os dados enviam o heartbeat para o NameNode, caso algum dos nós falhe em enviar esse conjunto de dados por mais de dez (10) minutos, o Master indica que aquele nó está indisponível (dead ou morto) e bloqueia a réplica dos chunks de dados para ele; o NameNode agenda, então, a criação de uma réplica dos dados que existiam no nó morto em outro nó (APACHE, 2018).  
 O arquivo de configuração core-site.xml fica disponível em todos o nós do cluster permitindo que todos nós saibam a localização do NameNode. Por padrão esse arquivo é apenas para leitura e fica em conf/core-site.xml. A property fs.defaultFS especifica a localização (url) do NameNode. O código abaixo pode ser usado para exibir o conteúdo do arquivo.
 
	cd /etc/hadoop/conf
cat core-site.xml 
Código Fonte 1 – Sequencia de comandos de sistema para exibir o conteúdo do arquivo core-site.xml. 
Fonte: Autor (2018).
A imagem mostra uma imagem parcial do conteúdo do arquivo.
Figura 4 – Conteúdo parcial do arquivo core-site.xml.
Fonte: Autor (2018).
Datanode
Dentro da arquitetura MASTER/SLAVE, o serviço SLAVE é denominado de DataNode (APACHE, 2018).
Segundo (BENGFORT, 2016), os dados reais são armazenado no DataNode seguindo as instruções do NameNode.
Figura 5 – NameNode acessando dados no DataNode Fonte: Autor (2018), baseado em descrição de (APACHE, 2018).
A aplicação cliente inicialmente requisita ao NameNode que localize os dados no disco. O NameNode informa a aplicação cliente uma lista de DataNodes que contêm os dados, o cliente fará uma solicitação dos blocos de dados que necessita ao DataNote. 
Para (APACHE, 2018), é responsabilidade do DataNode gerenciar o armazenamento de dados do sistema. Ele executar a operação de leitura e gravação conforme as instruções da aplicação cliente e bloqueia a criação, exclusão e replicação conforme as instruções enviadas pelo NameNode. Também é sua responsabilidade enviar heartbeats a intervalos pré-determinados para o NameNode.
O arquivo de configuração hdfs-site.xml possui a property dfs.datanode.name.dir que especifica onde o DataNode pode armazenar arquivos e blocos localmente. O código abaixo pode ser usado para exibir o conteúdo do arquivo.
 
	cd /etc/hadoop/conf
cat hdfs-site.xml
Código Fonte 2 – Sequencia de comandos de sistema para exibir o conteúdo do arquivo hdfs-site.xml. 
Fonte: Autor (2018).
Chunks ou Blocos
Segundo (APACHE, 2018), o HDFS divide grandes arquivos em pedaços menores conhecidos como Blocos ou Chunks, são a menor unidade de dados em um sistema de arquivos.
Os arquivos são divididos em blocos que, normalmente, tem entre 64 MB ou 128 MB, o tamanho dos blocos é configurável. Isso permite que arquivos grandes possam ser separados e distribuídos em diversas máquinas. Os blocos são replicados entre vários DataNodes, usando o fator de replicação três (3), isto é, os blocos são replicados em três DataNodes distintos minimizando, com isso, a possibilidade de perda de dados.
O NameNode tem controle de quais são os blocos que compões um arquivo e em quais DataNodes eles serão armazenados. O NameNode recebe relatório de bloco do DataNode periodicamente para manter o fator de replicação. Se um bloco estiver super-replicado / sub-replicado, o NameNode adiciona ou exclui as réplicas conforme necessário.
Operações Básicas do HDFS
O HDFS possui o mesmo conjunto básico de instruções que qualquer outro sistema operacional. Com comandos shell podemos, por exemplo, mover um arquivo, criar um diretório, alterar permissões ou exibir o conteúdo de um arquivo presente em clusters HDFS.
Todos os comandos são invocados pelo script /bin/hdfs ou /bin/hadoop. Dessa forma podemos usar os comandos shell tanto com o comando hadoop quanto com o comando hdfs, ambos executam as mesmas operações. A segunda sintaxe (hdfs) é específica para o sistema de arquivos do HDFS enquanto a segunda (hadoop) mais genérica, permitindo o uso de outros sistemas de arquivos como, por exemplo, o sistema de arquivos local, WebHDFS, S3 FS e o próprio HDFS (APACHE, 2018).
O exemplo abaixo exibe a versão do HADOOP.
 
	
hadoop version
Código Fonte 3 – Exemplo de uso do comando hadoop. 
Fonte: APACHE (2018).
O exemplo abaixo também exibe a versão do HADOOP.
 
	hdfs version
 
Código Fonte 4 – Exemplo de uso do comando hdfs. 
Fonte: APACHE (2018).
Ambos os comandos produzem o mesmo resultado. A diferença entre os comando é que o comando hadoop funciona com vários sistemas de arquivos, incluindo o HDFS, enquanto o comando hdfs funciona apenas com o HDFS.
INVOCANDO O HELP
É possível chamar um arquivo de ajuda para os comandos do sistema operacional. A sintaxe geral é:
 
	hadoop fs –help <cmd>
 
ou
 
hdfs dfs –help <cmd>
Código Fonte 5 – Sintaxe geral do comando help. 
Fonte: APACHE (2018).
Onde:
<cmd> é o comando do qual queremos obter ajuda. Exemplo:
 
	
hadoop fs –help ls
ou
 
hdfs dfs –help ls
 
Código Fonte 6 – Exemplo de uso do comando help. 
Fonte: APACHE (2018).
No exemplo estamos mostrando como obter ajuda para o uso do comando ls. Mais adiante veremos a função do comando ls.
Caso omitamos o <cmd> obteremos uma listagem completa do arquivo de ajuda.
 
	
hadoop fs –help
ou
 
hdfs dfs –help
Código Fonte 7 – Obtendo listagem completa do arquivo de ajuda. 
Fonte: APACHE (2018).
 
	
hadoop fs –ls
ou
hdfs dfs –ls
 
Código Fonte 8 – Exemplo de uso do comando ls. 
Fonte: APACHE (2018).
O comando pode ser completado por parâmetros.
 
	Parâmetro
	Função
	-C
	Exibe apenas os caminhos de arquivos e diretórios.
	-d
	Os diretórios são listados como arquivos simples.
	-h
	Formata os tamanhos dos arquivos de forma legível.
	-q
	Imprimir ? em vez de caracteres não imprimíveis.
	-R
	Lista recursivamente subdiretórios encontrados.
	-t
	Classifica a saída por hora da modificação (maisrecente primeiro).
	-S
	Ordena a saída por tamanho de arquivo.
	-r
	Inverte a ordem de classificação.
	-u
	Use o tempo de acesso em vez do tempo de modificação para exibição e classificação.
Quadro 2 – Parãmetros do comando ls.
Fonte: APACHE (2018).
Exemplo:
 
	
hadoop fs –ls –R
ou
hdfs dfs –ls -R
 
Código Fonte 9 – Exemplo de uso do comando ls com o parâmetro –R. 
Fonte: APACHE (2018).
Neste exemplo estamos mostrando como obter uma lista de arquivos e diretórios recursivamente.
COPIANDO ARQUIVOS DO SISTEMA DE ARQUIVOS LOCAL PARA O HDFS
É possível copiar um arquivo do sistema de arquivos local para o HDFS com o comando copyFromLocal.
 
 
	 
hadoop fs –copyFromLocal /home/dados/dados.csv dados.csv
ou
hdfs dfs –copyFromLocal /home/dados/dados.csv dados.csv
 
Código Fonte 10 – Exemplo de uso do comando copyFromLocal. 
Fonte: APACHE (2018).
Neste exemplo estamos copiando um arquivo de nome dados.csv que está no caminho /home/dados do sistema de arquivos local para um arquivo de mesmo nome no sistema de arquivos HDFS. 
COPIANDO ARQUIVOS DO HDFS PARA O SISTEMA DE ARQUIVOS
É possível copiar um arquivo do sistema de arquivos HDFS para o sistema de arquivos local com o comando copyToLocal.
	hadoop fs –copyToLocal dados.csv /home/dados/dados.csv
ou
hdfs dfs –copyFromLocal dados.csv /home/dados/dados.csv 
Código Fonte 11 – Exemplo de uso do comando copyToLocal. 
Fonte: APACHE (2018).
Neste exemplo estamos copiando um arquivo de nome dados.csv que está no sistema de arquivos HDFS para o caminho /home/dados do sistema de arquivos local em um arquivo de mesmo nome. 
COPIANDO ARQUIVOS DO HDFS PARA O HDFS
É possível copiar arquivos dentro do sistema de arquivos HDFS com o comando cp. Esse comando copia um arquivo ou diretório de uma origem identificada no comando para um destino identificado no comando.
 
	
hadoop fs –cp dados.csv teste/dados.csv 
ou
 
hdfs dfs –cp dados.csv teste/dados.csv 
 
Código Fonte 12 – Exemplo de uso do comando cp. 
Fonte: APACHE (2018).
Neste exemplo estamos copiando um arquivo de nome dados.csv que está no sistema de arquivos HDFS para o diretório teste do próprio sistema de arquivos HDFS, neste caso estamos mantendo o mesmo nome do arquivo. 
MOVENDO ARQUIVOS DO HDFS PARA O HDFS
É possível mover arquivos dentro do sistema de arquivos HDFS com o comando mv. Esse comando move um arquivo ou diretório de uma origem identificada no comando para um destino identificado no comando.
 
	
hadoop fs –mv teste1/dados.csv teste2/dados.csv 
ou
 
hdfs dfs –mv teste1/dados.csv teste2/dados.csv 
 
Código Fonte 13 – Exemplo de uso do comando mv. 
Fonte: APACHE (2018).
Neste exemplo estamos movendo um arquivo de nome dados.csv que está no sistema de arquivos HDFS no diretório teste1 para o diretório teste2 do próprio sistema de arquivos HDFS, neste caso estamos mantendo o mesmo nome do arquivo. 
EXIBINDO O CONTEÚDO DE UM ARQUIVO DO HDFS
É possível exibir o conteúdo de um arquivos presente no sistema de arquivos HDFS com o comando cat. Esse comando exibe o conteúdo de um arquivo na console ou na stdout.
 
	
hadoop fs –cat teste2/dados.csv 
ou
 
hdfs dfs –cat teste2/dados.csv 
 
Código Fonte 14 – Exemplo de uso do comando cat. 
Fonte: APACHE (2018).
Neste exemplo estamos exibindo o conteúdo de um arquivo de nome dados.csv que está no sistema de arquivos HDFS no diretório teste2. 
CRIANDO DIRETÓRIOS EM UM SISTEMA DE ARQUIVOS HDFS
É possível criar diretórios no sistema de arquivos HDFS com o comando mkdir. Esse comando cria um diretório no caminho informado.
 
	
hadoop fs –mkdir teste2 
 
ou
 
 
hdfs dfs –mkdir teste2 
 
Código Fonte 15 – Exemplo de uso do comando mkdir. 
Fonte: APACHE (2018).
Neste exemplo estamos criando o diretório teste2. 
REMOVENDO DIRETÓRIOS OU ARQUIVOS EM UM SISTEMA DE ARQUIVOS HDFS
É possível remover arquivos ou diretórios do sistema de arquivos HDFS com o comando rm. Esse comando apaga um arquivo ou diretório no caminho informado.
 
	
hadoop fs –rm teste2/dados.csv 
ou
 
hdfs dfs –rm teste2/dados.csv 
 
Código Fonte 16 – Exemplo de uso do comando rm. 
Fonte: APACHE (2018).
Neste exemplo estamos removendo o arquivo de nome dados.csv que está no diretório teste2. Para remover um diretório é necessário o uso do parâmetro –r, também.
 
	
hadoop fs –rm –r teste2 
ou
 
hdfs dfs –rm –r teste2 
 
Código Fonte 17 – Exemplo de uso do comando rm com o parâmetro –r. 
Fonte: APACHE (2018).
Neste exemplo estamos removendo o diretório teste2. Todo o conteúdo presente no diretório será removido, também.
 
Atividade extra
Nome da atividade: O que é um sistema de arquivos?
O HDFS é um sistema de arquivos. O HDFS é um dos diversos sistemas de arquivos disponíveis no mercado, maiores informações podem ser encontradas em https://pt.wikipedia.org/wiki/Sistema_de_ficheiros. 
Pesquise na internet o que é um sistema de arquivos e escreva um breve resumo explicando o que éntendeu sobre o assunto.
3 - Introdução a MapReduce
Para (HANSON, 2013), MapReduce é um “modelo de programação que permite o processamento de dados massivos em um algoritmo paralelo e distribuído, geralmente em um cluster de computadores”. O MapReduce foi proposto em um paper pela Google em 2004 como um modelo abstrato de programação, atualmente é largamente usado dentro do modelo de processamento de dados distribuído.
Segundo (BENGFORT, 2016), o MapReduce (MR) foi o primeiro e principal framework computacional usado pelas aplicações para acesso ao HADOOP. É simples, e ficar, projetado trabalhar em cluster e tolerante a falhas. Baseado nas operações de Map e Reduce de linguagens funcionais como o LISP, permite que várias tarefas independentes efetuem operações em parte dos dados locais, agregando-as após o processamento. 
Em linguagens funcionais, os processamentos unitários são avaliados stateless, sendo assim, as funções dependem unicamente de suas entradas, são fechadas e não compartilham estados. A transferência dos dados é feita entre as funções de forma que a saída de uma função é enviada para servir de entrada para outra de maneira totalmente independente (APACHE, 2018).
A operação de MapReduce é dividido em duas operações básicas (Hanson, 2013):
· Map e 
· Reduce.
MAP
Para (APACHE, 2018), os dados não são processados como listas ou coleções, a coordenação do processamento é feitas com pares de chave-valor <Key/Value>.  A função de MAP aceita a entrada de uma série de pares chave-valor <Key/Value> como entrada, processa cada par individualmente e gera um conjunto de pares chave-valor <Key/Value> intermediário. As solicitações de busca são encaminhadas para no NameNode do HADOOP inicia um grande número de processos de MAP e REDUCE. Uma vez que a operação MapReduce para uma chave de pesquisa específica é concluída, o NameNode retorna o valor de saída ao servidor que, por sua vez, o retorna ao cliente.
Normalmente, é durante a operação de mapeamento que os dados são analisados. Isso ocorre nessa fase porque a função MAP consegue ver cada elemento do conjunto de dados. Durante o processamento, os pares chave-valor <Key/Value> são testados, caso atendam a condição de busca, o par é enviado para a saída da função, caso não atendam a condição de busca, o par é ignorado. (BENGFORT, 2016).
mapper (filename, file-contents):
  for each word in file-contents:
    emit (word, 1)
Código Fonte 18 – Exemplo função MAP definida pelo usuário. 
Fonte: IBM (2013).
A função MAP do exemplo é parte de uma solução para contar cada palavra de um dado arquivo. Ela analisa todas as palavras de um conjunto de palavras e retorna o valor um (1) para cada palavra encontrada.
REDUCE
Para (BENGFORT, 2016), ao término da operação de MAP, os pares chave-valor <Key/Value> gerados são agrupados de acordo com a chave e enviados como entrada da função de REDUCE de cada chave. A função REDUCE é aplicada a entrada de dados e gera um único valor agregado por par chave-valor <Key/Value>. 
reducer (word, values):
  sum = 0
  for each value in values:
    sum = sum + value
  emit (word, sum)
Código Fonte 19 – Exemplofunção REDUCE definida pelo usuário. 
Fonte: IBM (2013).
A função REDUCE do exemplo é parte de uma solução para contar cada palavra de um dado arquivo. Ela soma todas as contagens emitidas para uma palavra específica e devolve a soma para a aplicação. 
EXEMPLO DE MAPREDUCE EM MONGODB.
Neste exemplo iremos criar uma coleção denominada BICHOS usando o MongoDB. Usaremos uma operação de MapReduce para contar quantos animais de cada tipo existem em nossa coleção.
     db.bichos.insert({_id:1,tags:['cao','gato']});
     db.bichos.insert({_id:2,tags:['gato']});
     db.bichos.insert({_id:3,tags:['rato','gato','cao']});
     db.bichos.insert({_id:4,tags:['gato','rato','cao']});
     db.bichos.insert({_id:5,tags:['cao','gato','cao']});
     db.bichos.insert({_id:6,tags:['cao','gato','cao']});
     db.bichos.insert({_id:7,tags:['zebra','macaco','galo']});
     db.bichos.insert({_id:8,tags:['hipopotamo']});
     db.bichos.insert({_id:9,tags:[]})
Código Fonte 20 – Criação da coleção BICHOS no MongoDB. 
Fonte: MongoDB (2018).
No exemplo, estamos criando a coleção BICHOS, com nove (9) entradas. As entradas podem ter de nenhum animal até três animais. 
A função MAP irá ler os dados e retornar o valor 1 (um) para cada animal encontrado.
     m = function(){
        this.tags.forEach(
           function(z){
                emit( z , { count : 1 } );
            }
       );
    };
Código Fonte 21 – Criação função MAP para a coleção BICHOS no MongoDB. 
Fonte: MongoDB (2018).
No exemplo, a função MAP (m) executa um laço e lê todos os dados da coleção. Cada palavra encontrada é transformada em um para chave-valor com a palavra encontra e o valor 1 (um).
Vejamos a função Reduce.
    r = function( key , values ){
        var total = 0;
        for ( var i=0; i<values.length; i++ )
             total += values[i].count;
        return { count : total };
        };
Código Fonte 22 – Criação função REDUCE para a coleção BICHOS no MongoDB. 
Fonte: MongoDB (2018).
No exemplo, a função REDUCE (r) varre os pares chave-valor gerados pela função MAP e soma os valores das chaves iguais.
Vamos executar as funções.
     res = db.bichos.mapReduce(m, r, { out : "saida" } );
     db.saida.find()
Código Fonte 23 – Execução do MAPREDUCE para a coleção BICHOS no MongoDB. 
Fonte: MongoDB (2018).
No exemplo excutamos a função de MAP m e a função REDUCE r, o resultado é enviado para coleção SAIDA. O conteúdo da coleção saída é exibido pela segunda linha de comandos do exemplo.
 
Atividade extra
Nome da atividade: Onde usar MapReduce?
MapReduce é um modelo de programação desenhado para processar grandes volumes de dados em paralelo, dividindo o trabalho em um conjunto de tarefas independentes. Programas MapReduce são escritos em um determinado estilo influenciado por construções de programação funcionais, especificamente expressões idiomáticas para listas de processamento de dados. Este módulo explica a natureza do presente modelo de programação e como ela pode ser usada para escrever programas que são executados no ambiente Hadoop.
Pesquise na internet pelo nome das empresas que adotaram Hadoop MapReduce. Baseado na sua pesquisa responda: “mapreduce é muito utilizado?”.
4 - Introdução a SQOOP
Uma das fontes de Big Data são os sistemas tradicionais que interagem com bancos de dados relacionais ou RDBMS, na sigla em inglês. 
Muitas vezes, os sistemas de armazenamento e de análise de dados do Big Data precisaram de uma ferramenta para interagir com os servidores de banco de dados relacional. Os dados precisam ser exportados de um sistema de bancos de dados relacional para um ambiente Big Data ou importados deste para um RDBMS. O Sqoop ocupa esse espaço no ecossistema do Hadoop fornecendo interação viável entre o servidor de banco de dados relacional e o HDFS do Hadoop
O Sqoop Apache Project é um utilitário de software livre de movimentação de dados de Hadoop para banco de dados baseado em JDBC. 
Sqoop foi criado em 2010 em um hackathon na Cloudera. Em 2011 foi disponibilizado como software livre. Em 2012 tornou-se um dos projetos top-level da Apache Software Foundation.
O Apache Sqoop pode ser útil  quando se deseja utilizar ferramentas de Big Data para o processamento de bases relacionais, para a integração de bases relacionais e mainframes com dados já presentes no Hadoop para o arquivamento dos dados no Hadoop.
Por padrão, o Sqoop utiliza JDBC (Java Database Connectivity) para se conectar aos bancos e, por esse motivo, acredita-se que ele é compatível com uma grande quantidade de bancos de dados, uma vez que os fornecedores implementam essa API. 
No entanto, o Sqoop não garante a compatibilidade e a performance com todos os bancos que possuem conectores JDBC devido às formas de implementação dessa API e a ligeiras diferenças que possam existir na sintaxe SQL de cada banco.
Importação de dados
O Sqoop realiza a importação dos dados em arquivos de texto 
–as-textfile 
arquivos Sequence File 
–as-sequencefile 
Avro 
–as-avrodatafile 
Parquet
–as-parquetfile 
Na importação para arquivos textuais, cada registro do banco se tornará uma linha no arquivo de destino onde cada coluna é delimitada por padrão pela vírgula ou outro separador definido pelo usuário por meio do argumento –fields-terminated-by.
O formato de texto delimitado é ideal quando não estão sendo importados dados binários.
Problema: O texto “As armas e os barões assinalados, que da ocidental praia Lusitana” pode apresentar problemas na importação caso o delimitador padrão (a vírgula) seja usado. 
Podemos resolver esse problema com o operador --fields-terminated-by.
Na importação para arquivos textuais, cada registro do banco se tornará uma linha no arquivo de destino onde cada coluna é delimitada por padrão pela vírgula ou outro separador definido pelo usuário por meio do argumento --fields-terminated-by.
Por padrão, o Sqoop importará os dados para o HDFS em um diretório de mesmo nome da tabela de origem. Esse diretório de destino pode ser alterado por meio do argumento --warehouse-dir, tendo como parâmetro um diretório qualquer. Dentro do diretório especificado serão criados outros diretórios com o nome da tabela de origem contendo os arquivos com os respectivos dados importados. Uma outra opção é o argumento --target-dir seguido do caminho completo para o diretório de destino desejado
sqoop import 
--connect jdbc:oracle:thin:@localhost:1521/orcl 
--username MOVIEDEMO --password welcome1 
--table ACTIVITY --target-dir etl/input/dados
import – indica uma operação de importação
connect - recebe como parâmetro o endereço do servidor seguido pelo nome do banco de dados e o número da porta, quando necessário.
username – indica o nome do schema 
password – indica a senha do usuário
table – indica o nome da tabela
target-dir – indica a localização dos novos arquivos importados.
Nos exemplos, a senha é passada por meio do argumento --password.  Apesar de essa ser uma forma muito simples de autenticação com o banco relacional, ela é também a maneira menos segura. Outra opção seria por meio do argumento --password-file, que recebe como parâmetro um arquivo que contém a senha. Pode-se ainda restringir as permissões de acesso a esse arquivo concedendo restrições de leitura apenas para o proprietário do arquivo (chmod 400) Uma terceira opção seria por meio do argumento -P, que solicitará a senha mediante o console a cada execução do Sqoop.
O Sqoop é capaz de paralelizar o processo de importação, distribuindo a consulta SQL por meio dos nós do seu cluster. Para isso, ele precisa saber qual coluna da tabela a ser importada deve ser utilizada para dividir os dados de origem e quantos processos deverão ser utilizados em paralelo. O mais adequado é a utilização de uma coluna que possua valores uniformemente distribuídos e que possa ser passada para o Sqoop por meio do argumento --split-by. Quando não informada a coluna, o Sqoop tenta escolher por si só; e por padrão ele escolhe geralmente a chave primária da tabela.
Exportação de Dados
Exportar significa enivar dados de volta do HDFS para o bancode dados RDBMS. A tabela de destino deve existir no banco de dados de destino. Os arquivos que são fornecidos como entrada para o Sqoop contêm registros, chamados de linhas na tabela. Esses são lidos e analisados ​​em um conjunto de registros e delimitados com delimitador especificado pelo usuário.
A operação padrão é inserir todo o registro dos arquivos de entrada na tabela do banco de dados usando a instrução INSERT. No modo de atualização, o Sqoop gera a instrução UPDATE que substitui o registro existente no banco de dados.
Sintaxe
Exemplo:
Vamos dar um exemplo dos dados do funcionário em arquivo, no HDFS. Os dados do funcionário estão disponíveis no arquivo aluno_data no diretório 'aluno /' no HDFS. Os dados aluno_ são os seguintes.
 01, Maria, 01, 10, Aprov  
 02, Pedro, 01, 9, Aprov  
 03, Julia, 02, 8, Aprov  
 04, Tereza, 02, 7, Aprov  
 05, Teresa, 01, 8, Aprov  
 06, Lara, 02, 9, Aprov  
É obrigatório que a tabela a ser exportada seja criada manualmente e esteja presente no banco de dados de onde deve ser exportada.
A consulta a seguir é usada para criar a tabela 'aluno' na linha de comando do mysql.
$ mysql
mysql> USE db;
mysql> CREATE TABLE aluno ( 
   rm INT NOT NULL PRIMARY KEY, 
   nome VARCHAR(30), 
   sala VARCHAR(30),
   media INT,
   situacao VARCHAR(20));
O comando a seguir é usado para exportar os dados da tabela (que está no arquivo aluno_data no HDFS) para a tabela de funcionários no banco de dados db do servidor de banco de dados Mysql.
$ sqoop export \
--connect jdbc:mysql://localhost/db \
--username root \
--table aluno \ 
--export-dir /aluno/aluno_data
O comando a seguir é usado para verificar a tabela na linha de comando do mysql.
mysql>select * from aluno;
Se os dados fornecidos forem armazenados com sucesso, você poderá encontrar a tabela a seguir com os dados fornecidos dos funcionários.
+----+---------+-------+-------+--------+
| RM | Nome    | Sala | Media |Situação|
+----+---------+-------+-------+--------+
| 01 | Maria   | 01 | 10 | Aprov  |
| 02 | Pedro   | 01 | 9 | Aprov  |
| 03 | Julia   | 02 | 8 | Aprov  |
| 04 | Tereza  | 02 | 7 | Aprov  |
| 05 | Teresa  | 01 | 8 | Aprov  |
| 06 | Lara    | 02 | 9 | Aprov  |
+----+---------+-------+-------+--------+
 
Atividade extra
Nome da atividade: Onde usar SQOOP?
Suponha que você possua uma tabela com cerca de dez milhões de linha em seu banco de dados relacional. Você gostaria de enviar os dados dessa tabela para o HDFS usando o SQOOP. 
Baseado nesse cenário, escreva o comando que você usaria para fazer a transferencia dos dados do RDBMS para o HDFS.
5 - Introdução a PIG
O Apache Pig é uma abstração sobre o MapReduce. É uma ferramenta / plataforma usada para analisar conjuntos maiores de dados que os representam como fluxos de dados. O porco é geralmente usado com o Hadoop; podemos executar todas as operações de manipulação de dados no Hadoop usando o Apache Pig.
Para escrever programas de análise de dados, o Pig fornece uma linguagem de alto nível, conhecida como Pig Latin. Essa linguagem fornece vários operadores, usando os quais os programadores podem desenvolver suas próprias funções para leitura, gravação e processamento de dados.
Para analisar dados usando o Apache Pig, os programadores precisam escrever scripts usando o idioma latino do Pig. Todos esses scripts são convertidos internamente em tarefas Map e Reduce. O Apache Pig possui um componente conhecido como Pig Engine que aceita os scripts do Pig Latin como entrada e converte esses scripts em tarefas do MapReduce.
  O Apache Pig possui diversos recursos, como:
· Grande conjunto de operadores - fornece muitos operadores para executar operações como join, sort e filter.
· Facilidade de programação - O Pig Latin é semelhante ao SQL e é fácil escrever um script Pig se você é bom em SQL.
· Facilidades de otimização - As tarefas no Apache Pig otimizam sua execução automaticamente, para que os programadores precisem se concentrar apenas na semântica da linguagem.
· Extensibilidade - Usando os operadores existentes, os usuários podem desenvolver suas próprias funções para ler, processar e gravar dados.
· UDF's - O Pig fornece a facilidade de criar funções definidas pelo usuário em outras linguagens de programação, como Java, e invocá-las ou incorporá-las nos scripts do Pig.
· Manipula todos os tipos de dados - o Apache Pig analisa todos os tipos de dados, tanto estruturados quanto não estruturados. Ele armazena os resultados no HDFS.
Modelo de dados
Pig Latin é o idioma usado para analisar dados no Hadoop usando o Apache Pig. O modelo de dados do Pig é totalmente aninhado (fully nested). Uma relação é a estrutura mais externa do modelo de dados Pig Latin. Uma relação também é uma bag. Uma bag é uma coleção de tuplas. Uma tupla é um conjunto ordenado de campos. Um campo pode ser visto como um dado.
Ao processar dados usando o Pig Latin, as statements (instruções) são as construções básicas. Essas statements funcionam como relações. Eles incluem expressions e schemas. Toda statements termina com um ponto-e-vírgula (;). Os statements realizam várias operações usando operadores fornecidos pela Pig Latin.
    Excetuando LOAD e STORE, durante a execução de todas as operações, as statements do Pig Latin tomam uma relação como entrada e produzem outra relação como saída.
    Assim que você inserir uma instrução Load no shell Grunt, sua verificação semântica será realizada. Para ver o conteúdo do esquema, você precisa usar o operador Dump . Somente após executar a operação de dump, a tarefa MapReduce para carregar os dados no sistema de arquivos será executada.
O exemplo a seguir é uma statements do Pig Latin, que carrega dados para o Apache Pig.
grunt> Student_data = LOAD 'alunos.txt' USING PigStorage(',')as 
   ( rm:int, primeiro:chararray, sobrenome:chararray, fone:chararray, cidade:chararray );
Tipos de dados
O Pig Latin aceita vários tipos de dados, alguns deles estão listados abaixo
Tipo de dados, descrição e exemplo
int         Representa um número inteiro de 32 bits assinado.
long            Representa um número inteiro de 64 bits assinado.
float           Representa um ponto flutuante de 32 bits.
double          Representa um ponto flutuante de 64 bits.
chararray       Representa uma matriz de caracteres (string) no formato Unicode UTF-8.
Bytearray Representa uma matriz de bytes (blob).
boolean   Representa um valor booleano.
datatime Representa uma data e hora.
Biginteger Representa um Java BigInteger.
Bigdecimal Representa um Java BigDecimal
Tipos Complexos
Tuple Uma tupla é um conjunto ordenado de campos.
bag Uma bag é uma coleção de tuplas.
Map Um mapa é um conjunto de pares de valores-chave.
Valores Nulos
Os valores para todos os tipos de dados acima podem ser NULL. O Apache Pig trata valores nulos de maneira semelhante ao SQL.
Um nulo pode ser um valor desconhecido ou um valor inexistente. É usado como um espaço reservado para valores opcionais. Esses nulos podem ocorrer naturalmente ou podem ser o resultado de uma operação.
Operadores Aritméticos
Operador Descrição 
+ Adição - Adiciona valores em ambos os lados do operador
- Subtração - Subtrai o operando do lado direito do operando do lado esquerdo
* Multiplicação - multiplica valores nos dois lados do operador
/ Divisão - Divide o operando esquerdo pelo operando direito
% Módulo - Divide o operando da mão esquerda pelo operando da mão direita e retorna o restante.
Operadores de Comparação
Operador Descrição
== Igual - Verifica se os valores de dois operandos são iguais ou não; se sim, então a condição se torna verdadeira.
!= Diferente - Verifica se os valores de dois operandos são iguais ou não. Se os valores não forem iguais, a condição se tornará verdadeira.
> Maior que - Verifica se o valor do operando esquerdo é maior que o valor do operando direito. Se sim, então a condição se torna verdadeira.
< Menor que - Verifica se o valor do operando esquerdo é menor que o valor do operando direito. Se sim, então a condição se torna verdadeira.
> = Maior que ou igual a - Verifica se ovalor do operando esquerdo é maior que ou igual ao valor do operando direito. Se sim, então a condição se torna verdadeira.
<= Menor que ou igual a - Verifica se o valor do operando esquerdo é menor ou igual ao valor do operando direito. Se sim, então a condição se torna verdadeira.
Manipulando dados no Pig Latin
No sistema de arquivo local, abra um termina, execute o editor de texto gedit para criar um arquivo de nome alunos.csv com o seguinte conteúdo:
gedit alunos.csv
1,Humberto,Silva,36,929451722,Aracaju
2,Rita,Tavares,38,946330236,Belem
3,Sandra,Miranda,38,956924691,Belmonte
4,Edson,Martins,36,952739850,Araraquara
5,Maria,Miragaia,31,963367817,Bariri
6,Rosa,Drauzio,35,988782874,Barra
7,Ana,Camargo,35,908371955,Campinas
8,Henrique,Oz¢rio,37,901876944,Bocaina
9,Bianka,Estrada,38,928699387,Capela
10,Mauricio,Pimentel,36,929817835,Colmeia
11,Airton,Borges,21,928713908,Aracaju
12,Izilda,Duque,19,922449888,Belem
13,Gabriela,Assis,29,906956556,Belmonte
14,Queren,Machado,32,963144094,Araraquara
15,Fernanda,Ono,18,981533693,Bariri
16,Nicole,Kim,33,933061205,Barra
17,Ralf,Forte,30,926772832,Campinas
18,Elise,Valente,27,950888146,Bocaina
19,Thais,Berg,26,933694061,Capela
20,Sandro,Franca,22,923226439,Colmeia
21,Viviane,Key,21,965003873,Aracaju
22,Matilda,Crew,28,936825726,Belem
23,Tereza,Carmo,26,912316641,Belmonte
24,Renato,Honda,25,971658609,Araraquara
25,Andre,Nildo,25,964046602,Bariri
26,Pedregunda,Rocha,34,961898155,Barra
27,Pietra,Horta,38,938700355,Campinas
28,Sidney,Norte,31,983087084,Bocaina
29,Darcy,Costa,26,926634477,Capela
30,Leandro,Duna,29,966032007,Colmeia
Onde:
Coluna 1 – Código do aluno
Coluna 2 – Nome do aluno
Coluna 3 – Sobrenome do aluno
Coluna 4 – Idade do aluno
Coluna 5 – Telefone do aluno
Coluna 6 – Cidade do aluno
Salve e feche o editor de texto após o término da digitação
No sistema de arquivo local, abra um termina, execute o editor de texto gedit para criar um arquivo de nome estado.csv com o seguinte conteúdo:
gedit estado.csv
1,Aracaju,SE
2,Belem,PA
3,Belmonte,MG
4,Araraquara,SP
5,Bariri,AM
6,Barra,RJ
7,Campinas,SP
8,Bocaina,MS
9,Capela,GO
10,Colmeia,MT
Onde:
Coluna 1 – Código sequencial
Coluna 2 – Nome da cidade
Coluna 3 – UF
Salve e feche o editor de texto após o término da digitação
Em um terminal, execute o comando abaixo para que o pig seja executado localmente.
pig –x local
Crie uma relação denominada dados_alunos com os dados do arquivo alunos.csv.
dados_alunos = LOAD 'alunos.csv' USING PigStorage(',') as (cod:int, nome:chararray, sobrenome:chararray, idade:int, fone:chararray, cidade:chararray);
Use o comando dump para exibir o conteúdo da relação dados_alunos. 
dump dados_alunos;
Use o comando illustrate para exibir uma amostra da relação dados_alunos. 
illustrate dados_alunos;
Crie uma relação denominada dados_estado com os dados do arquivo estado.csv. 
dados_estado = LOAD 'estado.csv' USING PigStorage(',') as (cod:int, cidade:chararray, uf:chararray);
Use o comando dump para exibir o conteúdo da relação dados_estado.
dump dados_estado;
Use o comando illustrate para exibir uma amostra da relação dados_estado.
 illustrate dados_estado;
Crie uma nova relação denominada dados_agrupados. Essa nova relação deve conter os dados da relação dados_alunos agrupados por idade. 
dados_agrupados = GROUP dados_alunos by idade;
Use o comando describe para exibir a estrutura da relação. 
describe dados_agrupados;
Use o comando illustrate para exibir uma amostra da relação dados_agrupados.
illustrate dados_agrupados;
Crie uma nova relação denominada múltiplas_colunas. Essa nova relação deve conter os dados da relação dados_alunos agrupados por idade e por cidade. 
multiplas_colunas = GROUP dados_alunos by (idade, cidade);
Use o comando illustrate para exibir uma amostra do conteúdo da relação multiplas_colunas.
illustrate multiplas_colunas
Crie uma nova relação denominada todas_colunas. Essa nova relação deve conter os dados da relação dados_alunos agrupados por todas as colunas da relação. 
todas_colunas = GROUP dados_alunos by all;
Use o comando illustrate para exibir uma amostra desta nova relação.
illustrate todas_colunas
Crie uma nova relação denominada duas_relacoes. Essa nova relação deve conter os dados da relação dados_alunos e da relação dados_estado  agrupados pelo nome da cidade. 
duas_relacoes = COGROUP dados_alunos by cidade, dados_estado by cidade;
Exiba uma mostra da nova relação
illustrate duas_relacoes;
No sistema de arquivo local, abra um termina, execute o editor de texto gedit para criar um arquivo de nome empregado.csv com o seguinte conteúdo:
gedit empre ado.csv
1,Sandra,10
2,Edson,10
3,Rita,20
4,Bianka,10
5,Humberto,20
6,Rosa,10
7,Thais,20
8,Winna,30
9,Paulo,30
10,Antonio,20
11,Fatima,50
Onde:
Coluna 1 – Número do funcionário
Coluna 2 – Nome do funcionário
Coluna 3 – Código do departamento
Salve e feche o editor de texto após o término da digitação
No sistema de arquivo local, abra um termina, execute o editor de texto gedit para criar um arquivo de nome departamento.csv com o seguinte conteúdo:
gedit departamento.csv
10,Comercial,AM
20,Pesquisa,MS
30,Jogos,SE
40,Suporte,DF
Onde:
Coluna 1 – Código do departamento
Coluna 2 – Nome do departamento
Coluna 3 – UF do departamento
Salve e feche o editor de texto após o término da digitação
Crie uma relação denominada empregado que deverá conter os dados do arquivo empregado.csv e outra relação denominada departamento que deverá conter os dados do arquivo departamento.csv.
empregado = LOAD 'empregado.csv' USING PigStorage (',') as (cod:int, nome:chararray, dept:int);
departamento = LOAD 'departamento.csv' USING PigStorage (',') as (dept:int, nome:chararray, uf:chararray);
Una os dados das relações empregado e departamento usando a instrução JOIN. Use o código de departamento para unir as relações. 
dados_join = JOIN empregado by dept, departamento by dept;
Una os dados das relações empregado e departamento usando a instrução LEFT OUTER JOIN. Use o código de departamento para unir as relações. 
dados_join = JOIN empregado by dept LEFT OUTER, departamento by dept;
Una os dados das relações empregado e departamento usando a instrução RIGHT OUTER JOIN. Use o código de departamento para unir as relações. 
dados_join = JOIN empregado by dept RIGHT OUTER, departamento by dept;
Una os dados das relações empregado e departamento usando a instrução FULL OUTER JOIN. Use o código de departamento para unir as relações. 
dados_join = JOIN empregado by dept FULL OUTER, departamento by dept;
Execute o comando abaixo para dividir a relação dados_aluno em duas. A primeira é denominada de dados_s1 e a segunda de dados_s2. Aquela conterá os alunos com idade abaixo de 23 anos e esta conterá os alunos com idade acima de 35 anos.
SPLIT dados_alunos into dados_s1 if idade<23, dados_s2 if idade>35;
dump dados_s1;
dump dados_s2;
Execute o comando abaixo para unir os dados da relação dados_s1 e dados_s2 em uma relação denominada dados_u1.
dados_u1 = UNION dados_s1, dados_s2;
dump dados_u1;
Crie uma nova relação apenas com os dados da cidade de Campinas. Leia os dados da relação dados_alunos e crie a relação dados_campinas.
dados_campinas = FILTER dados_alunos by cidade == 'Campinas';
Crie uma nova relação denominada proj_camp a partir dos dados da relação dados_campinas. Nesta nova relação somente deverão existir os campo idade, nome e cidade. 
proj_camp = FOREACH dados_campinas GENERATE idade, nome, cidade;
Crie uma nova relação denominada ordenado_camp a partir dos dados da relação proj_camp. Ordene dos dados de forma que os alunos mais jovens sejam listados em primeiro lugar e os menos jovens por último. 
ordenado_camp = ORDER proj_camp BY idade;
Armazene o conteúdo da relação ordenado_camp no disco local usando o comando abaixo:
STORE ordenado_camp INTO '/home/oracle/Downloads/campinas.csv' USING PigStorage(',');
Atividade extra
Nome da atividade: Onde usar PIG?
Suponha que exista um arquivo em formato texto com o tamanho de 1 gigabyte (1 GB) no ambiente HADOOP HDFS. Esse arquivo pode ser aberto por um software de planilha eletrônicacomo, por exemplo, o Microsoft Excel e contêm os dados de venda da empresa no país inteiro. No arquivo existe uma coluna com a Unidade da Federação (estado) indicando onde a operação foi feita . O tempo gasto para abrir esse arquivo é de quinze (15) minuto. Você precisa ler esse arquivo, remover todos os dados da Unidade da Federação que sejam do estado de São Paulo (SP) e gerar um novo arquivo sem os dados de São Paulo.
Baseado nesse cenário, você recomendaria o uso da ferramenta de APACHE PIG para processar esse arquivo? Escreva um texto justificando sua escolha.
6 - Introdução a HIVE
Para (APACHE, 2018), o APACHE HIVE é um software para data warehouse desenvolvido sobre o APACHE HADOOP. Desenvolvido inicialmente pelo FACEBOOK foi encampado pela fundação APACHE com o nome de APACHE HIVE. Utilizado por várias empresas, incluindo a NETFLIX e a AMAZON no produto AMAZON ELASTIC MAPREDUCE. 
 Usa uma interface similar ao SQL para consultar bancos de dados e arquivos integrado ao HADOOP. Fornece funções de consulta, aglutinação, agregação e análise que permite associar schemas estruturados a dados no HDFS. O HIVE permite que desenvolvedores que dominem SQL usem o ambiente HADOOP sem que eles precisem trabalhar com JAVA ou alguma outra API do MAPREDUCE. Apesar de usar SQL, o HIVE é definido como uma camada de acesso a dados armazenados no HDFS e não é considerado um Sistema Gerenciador de Banco de Dados, ou SGBD (BENGFORT, 2016).
O HIVE QUERY LANGUAGE, ou HQL, é o dialeto SQL oferecido pelo HIVE. As instruções em HQL são transformados, internamente, em tarefas, ou jobs, pelo execution engine e gerenciados pelo YARN evitando, assim, que o desenvolvedor tenha que criar Jobs MapReduce para acessar os dados dos HDFS. Suporta instruções de (APACHE, 2018):
• DDL, ou Data Definition Language, aceitando comandos como CREATE DATABASE, CREATE SCHEMA e CREATE TABLE.
• DML, ou Data Manipulation Language, aceitando comandos como INSERT, UPDATE e LOAD. 
• Consulta a dados com operações como o SELECT.
• Funções definidas pelo usuário.
CLI, ou Command Line Interface, do HIVE.
Segundo (APACHE, 2018), o HIVE possui uma interface de linha de comando, ou command line interface (CLI), que acompanha a instalação do produto. Para iniciar a CLI basta abrir um terminal onde o produto foi instalado e digitar:
    hive
Código Fonte 25 – Iniciando a CLI do HIVE. 
Fonte: APACHE (2018).
É possível listar o arquivo de ajuda do HIVE digitando o comando abaixo no terminal:
hive -H
Código Fonte 26 – Listando o arquivo de ajuda da CLI do HIVE. 
Fonte: APACHE (2018).
CREATE DATABASE
Segundo (APACHE, 2018),  a sintaxe para criação de um banco de dados ou de um schema no HIVE é similar a da criação de bancos de dados ou schema do modelo relacional. 
CREATE DATABASE banco;
ou
CREATE SCHEMA banco;
Código Fonte 27 – Exemplo de criação de banco de dados no HIVE. 
Fonte: APACHE (2018).
No exemplo está sendo criado um banco de dados de nome BANCO. Os metadados contendo a definição do banco de dados são armazenados em um repositório denominado metastore.  Ocorrerá um erro caso já exista um banco de dados com o mesmo nome do banco que está sendo criado, para evitar esse erro, é possível testar a existência do banco no momento da criação.
CREATE DATABASE IF NOT EXISTS banco;
     Código Fonte 28 – Exemplo de teste de existência do banco antes da criação no HIVE. 
Fonte: APACHE (2018).
É possível produzir uma lista com o nome de todos os bancos criados até o momento.
SHOW DATABASES;
     Código Fonte 29 – Lista todos os bancos presentes no HIVE. 
Fonte: APACHE (2018).
O comando também pode ser executado por um programa, o exemplo abaixo mostra o uso de JDBC com o comando CREATE DATABASE;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
public class HiveCreateDb {
   private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      Class.forName(driverName);
      Connection con = DriverManager.getConnection("jdbc:hive://localhost:10000/default", "", "");
      Statement stmt = con.createStatement();
      stmt.executeQuery("CREATE DATABASE banco");
      System.out.println(“Banco criado.”);
      con.close();
   }
}
Código Fonte 30 – Criação de um banco HIVE com JDBC. 
Fonte: TUTORIALSPOINT (2013), adaptado.
DROP DATABASE
Segundo (APACHE, 2018), a sintaxe para eliminar um banco de dados ou de um schema no HIVE é similar ao da remoção de bancos de dados ou  schema do modelo relacional. 
DROP DATABASE IF EXISTS banco;
Código Fonte 31 – Remoção de um banco HIVE.
Fonte: APACHE (2018), adaptado.
A opção CASCADE pode ser utilizada para eliminar as tabelas existentes no banco de dados, caso elas existam, antes de apagar o banco de dados. 
DROP DATABASE IF EXISTS banco CASCADE;
Código Fonte 31 – Remoção de um banco HIVE com a opção CASCADE.
Fonte: APACHE (2018), adaptado.
O banco de dados também pode ser removido através do uso da palavra-chave SCHEMA. 
DROP SCHEMA banco;
Código Fonte 33 – Remoção de um banco HIVE com DROP SCHEMA.
Fonte: APACHE (2018), adaptado.
O comando também pode ser executado por um programa, o exemplo abaixo mostra o uso de JDBC com o comando DROP DATABASE.
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
public class HiveDropDb {
   private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      Class.forName(driverName);
         Connection con = DriverManager.getConnection("jdbc:hive://localhost:10000/default", "", "");
      Statement stmt = con.createStatement();
      stmt.executeQuery("DROP DATABASE banco");
      System.out.println(“Banco Removido.”);
      con.close();
   }
}
Código Fonte 34 – Remoção de um banco HIVE com JDBC. 
Fonte: TUTORIALSPOINT (2013), adaptado.
Tipo de Dados
Segundo (APACHE, 2018), os principais tipos de dados no HIVE são divididos em numéricos, texto, data, tempo, complexos.
Entre os tipos de dados para armazenar valores numéricos destacamos:
• TINYINT, é um campo com 1 (um) byte, inteiro, com sinal. Pode ser usado para armazenar valores que vão de -128 até 127.
• SMALLINT, é um campo com 2 (dois) bytes, inteiro, com sinal. Pode ser usado para armazenar valores que vão de -32.768 até 32.767.
• INT, é um campo com 4 (quatro) bytes, inteiro, com sinal. Pode ser usado para armazenar valores que vão de -2.147.483.648 até 2.147.483.647.
• BIGINT, é um campo com 8 (oito) bytes, inteiro, com sinal. Pode ser usado para armazenar valores que vão de -9.223.372.036.854.775.808 até 9.223.372.036.854.775.807.
• FLOAT, é um campo com 4 bytes, precisão simples, com ponto flutuante.
• DOUBLE é um campo com 8-byte, precisão dupla,  com ponto flutuante.
• DECIMAL (precisão, escala). Por padrão, assume o valor 0 (zero) ser a escala não for definida e 10 (dez) se a precisão não for definida. Limitado a 38 dígitos. 
Entre os tipos de dados para armazenar tempo e data destacamos:
• TIMESTAMP armazena datas no formato ANO-MÊS-DIA HORA:MINUTO:SEGUNDO:FRAÇÃODESEGUNDO (yyyy-mm-dd hh:mm:ss.fffffffff), com precisão de nove casas na  fração de segundo.
• DATE armazena datas no formato ANO-MÊS-DIA (yyyy-mm-dd).
• INTERVAL armazena intervalos de tempo em segundo / minutos / dias / meses / anos.
Entre os tipos de dados para armazenar texto, destacamos:
• STRING, usado para armazenar literais. Pode ser delimitado por aspas simples (‘) ou aspas duplas (“).
• VARCHAR, texto de tamanho variável. Pode ter até 65.535 caracteres.
• CHAR, texto de tamanho fixo. Pode ter até 65.535 caracteres.
Entre os tipos de dados complexos do HIVE, destacamos:
• ARRAY, usado para vetores de elementos do mesmo tipo.
• MAP, usado para coleções de chave-valor. 
• STRUCT, usado para registros que encapsulam campos nomeados e qualquer tipo de dados primitivos.
• UNIONTYPE, usado para coleções de tipo de dadosheterogêneos.
Entre os outros tipos de dados do HIVE, destacamos:
• BOOLEAN
• BINARY
CREATE TABLE
Segundo (APACHE, 2018), o comando CREATE TABLE cria uma tabela com o nome fornecido. Ocorrerá um erro caso já exista uma tabela com o mesmo nome da tabela que está sendo criada, para evitar esse erro, é possível testar a existência da tabela no momento da criação com o comando IF NOT EXISTS. Em sua forma mais simples, o comando CREATE TABLE aceita um nome para a tabela e a definição de suas colunas.
CREATE TABLE IF NOT EXISTS TESTE
(CODIGO SMALLINT,
 ANO INT,
 UF CHAR(2)
 POPULACAO INT);
Código Fonte 35 – Criação de uma tabela HIVE. 
Fonte: APACHE (2018), adaptado.
O exemplo cria a tabela de nome TESTE, caso ela ainda não exista no banco de dados. A tabelas possui quatro colunas: CODIGO, ANO, UF e POPULACAO.
Caso queira exibir o nome das tabelas existentes em seu banco de dados, use o comando SHOW TABLES.
SHOW TABLES;
Código Fonte 36 – Exibindo as tabelas do banco de dados. 
Fonte: APACHE (2018), adaptado.
Os dados do HIVE são armazenados no sistema de arquivos HDFS, ou outro semelhante, sendo assim, o comando CREATE TABLE possui cláusulas opcionais, como a cláusula ROW FORMAT. ROW FORMAT informa ao HIVE como ler cada linha do arquivo e mapeá-la para nossas tabelas (BENGFORT, 2016). 
CREATE TABLE IF NOT EXISTS TESTE
(CODIGO SMALLINT,
 ANO INT,
 UF CHAR(2)
 POPULACAO INT)
 ROW FORMAT DELIMITED 
 FIELDS TERMINATED BY '\t'
;
Código Fonte 37 – Criação de uma tabela HIVE com ROW FORMAT. 
Fonte: APACHE (2018), adaptado.
No exemplo, estamos informando que os dados estão em um arquivo onde os campos estão separados por um caractere de tabulação. Vejamos outro exemplo.
CREATE TABLE IF NOT EXISTS TESTE
(CODIGO SMALLINT,
 ANO INT,
 UF CHAR(2)
 POPULACAO INT)
 ROW FORMAT DELIMITED 
 FIELDS TERMINATED BY ',' 
 LINES TERMINATED BY '\n' 
 STORED AS TEXTFILE
;
Código Fonte 38 – Criação de uma tabela HIVE com ROW FORMAT e STORED AS. 
Fonte: APACHE (2018), adaptado.
No exemplo, estamos informando que os dados estão em um arquivo onde os campos estão separados por uma vírgula, as linhas estão separadas por uma quebra de linha em um arquivo de texto simples.
LOAD DATA
Segundo (APACHE, 2018), o HIVE não verifica os dados para garantir que esteja compatível com a definição da tabela. Normalmente retorna valores nulos para os campos ausentes ou que não tenham correspondência com os tipos de dados carregados. O comando de carga de dados é o LOAD DATA, permitindo carga massiva de dados em operações batch. O comando INSERT pode ser usado para incluir dados individuais.
INSERT INTO TABLE teste 
       VALUES 
             (1, 2010, 'SP', 41252160),
             (2, 2010, 'MG', 19595309)
Código Fonte 39 – Exemplo de INSERT em tabela HIVE. 
Fonte: APACHE (2018), adaptado.
No exemplo estamos inserindo dois registros na tabela teste. A sintaxe é bem similar a dos bancos de dados relacionais. O comando LOAD DATA é usado para carga de arquivos em lote.
LOAD DATA LOCAL 
    INPATH '/tmp/censo.csv' 
    OVERWRITE 
    INTO TABLE teste;
Código Fonte 40 – Exemplo de LOAD em tabela HIVE. 
Fonte: APACHE (2018), adaptado.
No exemplo estamos lendo os dados presentes no arquivo CENSO.CSV e carregando-os na tabela TESTE. A opção OVERWRITE garante que todos os dados existentes na tabela serão apagados e substituídos pelo conteúdo do arquivo. Caso essa opção não for usada, os dados serão adicionados a tabela.
SELECT
Segundo (APACHE, 2018), o HIVE permite que analisemos os dados executando consultas HQL, eliminando boa parte do trabalho de criar uma função mapper, uma função reducer e configurar o job que o irá executar.
O HIVE permite operações de consulta, classificação, agrupamento, entre outras. 
SELECT * 
  FROM teste
WHERE ano = 2010;
Código Fonte 41 – Operação de consulta a tabela HIVE com filtro pelo ano. 
Fonte: APACHE (2018), adaptado.
No exemplo consultamos todos os dados da tabela TESTE onde os dados sejam do ano de 2010.
SELECT ano, SUM (populacao)
  FROM teste
 GROUP BY ano;
Código Fonte 42 – Operação de consulta a tabela HIVE agrupado pelo ano. 
Fonte: APACHE (2018), adaptado.
No exemplo, apresentamos a soma da população agrupada pelo ano.
 
Atividade extra
Nome da atividade: Onde usar HIVE?
Suponha que exista um arquivo em formato texto estruturado com o tamanho de 1 gigabyte (1 GB) armazenado em ambiente HADOOP HDFS. Você gostaria de consultar o conteúdo desse arquivo mas conhece apenas comandos SQL.
Baseado nesse cenário, que ferramenta de  Big Data poderia ser usada para consultar os dados desse arquivo? Escreva um texto justificando sua escolha.
7 - Introdução a HBase
Desde 1970, o RDBMS é a solução para problemas relacionados ao armazenamento e manutenção de dados. Após o advento do big data, as empresas perceberam o benefício do processamento de big data e começaram a optar por soluções como o Hadoop.
O Hadoop usa o sistema de arquivos distribuído para armazenar big data e o MapReduce para processá-lo. O Hadoop se destaca no armazenamento e processamento de grandes dados de vários formatos, como arbitrários, semi ou mesmo não estruturados.
No entanto, o Hadoop pode executar apenas o processamento em lote e os dados serão acessados ​​apenas de maneira sequencial. Isso significa que é preciso pesquisar em todo o conjunto de dados, mesmo nos trabalhos mais simples.
Um grande conjunto de dados quando proc O HBase é um banco de dados orientado a colunas distribuído, construído sobre o sistema de arquivos Hadoop. É um projeto de código aberto e é escalável horizontalmente.
O HBase é um modelo de dados semelhante ao BigTable do Google, projetado para fornecer acesso aleatório rápido a grandes quantidades de dados estruturados. Ele aproveita a tolerância a falhas fornecida pelo Hadoop File System (HDFS). É parte do ecossistema do Hadoop que fornece acesso aleatório de leitura / gravação em tempo real aos dados no Hadoop File System.
Modelo de dados do HBase
Uma linha individual é acessada por meio de sua ROWKEY. É composta por uma ou mais famílias de colunas. Cada família de colunas tem um ou mais qualificadores de coluna. Cada coluna pode ter uma ou mais versões.  Para acessar um dado individual, é necessário saber sua ROWKEY, família de coluna, qualifica Ao projetar um modelo de dados do HBase, é útil pensar em como os dados serão acessados. 
Você pode acessar os dados do HBase de duas maneiras: Através de sua chave de linha ou através de uma varredura de tabela para um intervalo de ROWKEY e através de processamento em lote usando MAP-REDUCE.
Os registros no HBase são armazenadas de acordo com a ordem das chaves da linha.  Este é um princípio fundamental do HBase e é também utilizado no design do esquema.  As chaves são ordenadas obedecendo a ordem lexicográfica com comparações da esquerda para a direita.
Executando operações de CRUD com HBase shell
Vamos iniciar o HBase shell e criar uma tabela HBase, incluir, consultar e  apagar dados da tabela.
A tabela a ser criada é a tabela aluno com a seguinte estrutura
Inicie o HBase com o comando
 
hbase shell
 
Explore a ajuda aos comando com o comando “help”:
 
help 'create'
help 'describe'
help 'put'
help 'get'
help 'scan'
help 'count'
help 'delete'
help 'deleteall'
 
Crie a tabela “aluno”:
 
create 'aluno', {NAME=>'identificacao'}, {NAME=>'historico'}
 
Observação: caso cometa algum erros, apague a tabela com os comandos:
disable 'aluno'
drop 'aluno'
 
Use o comando “describe” para exibir a estrutura da tabela:
 
describe 'aluno'
 
Use o comando “put” incluir dados na tabela:
 
put 'aluno', 'RM1234', 'identificacao:nome', 'Sandra'   
 
Use o comando “get” para exibir os dados do aluno RM1234 :
 
get 'aluno', 'RM1234' 
 
Insira mais alguns dados na tabela aluno:
 
put 'aluno', 'RM1234', 'identificacao:sobrenome', 'Puga'
put 'aluno', 'RM1234', 'historico:disciplina', 'Banco de Dados'
put 'aluno', 'RM1234', 'historico:nota', '10.0'   
 
Use o comando “get” para exibir os dados do aluno RM1234 :
 
get 'aluno', 'RM1234' 
 
Use o comando “get” para exibir os dados de uma família decolunas do aluno RM1234 :
 
get 'aluno', 'RM1234', {COLUMNS=>['identificacao']} 
 
Use o comando “get” para exibir os dados de uma coluna específica do aluno RM1234 :
 
get 'aluno', 'RM1234', {COLUMNS=>['identificacao:sobrenome']} 
 
Use o comando “alter” para armazenar mais versões da família de colunas “histórico” :
 
alter 'aluno', NAME => 'historico', VERSIONS => 5 
 
Use o comando “describe” para exibir a estrutura da tabela:
 
describe 'aluno'
 
Use o comando “put” para incluir mais algumas notas para o aluno RM1234 :
 
put 'aluno', 'RM1234', 'historico:nota', '9.5'   
put 'aluno', 'RM1234', 'historico:nota', '9.0'   
put 'aluno', 'RM1234', 'historico:nota', '8.5'   
put 'aluno', 'RM1234', 'historico:nota', '8.5'   
 
Use o comando “get” para exibir os dados da coluna “histórico” do aluno RM1234 :
 
get 'aluno', 'RM1234', {COLUMNS=>['historico:nota']} 
 
Use o comando “get” para exibir todas as versões da coluna “histórico” do aluno RM1234 :
 
get 'aluno', 'RM1234', {COLUMNS=>['historico:nota'], VERSIONS => 5} 
 
Insira mais alguns dados na tabela aluno:
 
put 'aluno', 'RM2345', 'identificacao:nome', 'Henrique'
put 'aluno', 'RM2345', 'identificacao:sobrenome', 'Poyatos'
put 'aluno', 'RM2345', 'historico:disciplina', 'Java'
put 'aluno', 'RM3456', 'identificacao:nome', 'Rita'
put 'aluno', 'RM3456', 'identificacao:sobrenome', 'Rodrigues'
put 'aluno', 'RM3456', 'historico:disciplina', 'SQL'
put 'aluno', 'RM3456', 'historico:nota', '10.0'
put 'aluno', 'RM2345', 'historico:nota', '10.0'
put 'aluno', 'RM4567', 'historico:nota', '10.0'
put 'aluno', 'RM5678', 'historico:nota', '10.0'
put 'aluno', 'RM1234', 'historico:nota', '9.5'
put 'aluno', 'RM1234', 'historico:disciplina', 'Modelagem de Banco'   
 
Use o comando “scan” para obter todas linhas e colunas de uma tabela :
 
scan 'aluno'
 
Use o comando “scan” para obter todas linhas da família de colunas “identificação” :
 
scan 'aluno', {COLUMNS=>['identificacao']}
 
Use o comando “scan” para obter todas as versões da coluna “nota” :
 
scan 'aluno', {COLUMNS=>['historico:nota'], VERSIONS => 5}
 
Use o comando “count” para obter o número de linhas de uma tabela:
 
count 'aluno'
 
Use o comando “get” para exibir os dados do aluno RM1234 :
 
get 'aluno', 'RM1234' 
 
Use o comando “delete” para apagar a coluna “sobrenome” do aluno RM1234 :
 
delete 'aluno', 'RM1234', 'identificacao:sobrenome'
get 'aluno', 'RM1234' 
 
Use o comando “deleteall” para apagar todos os dados do aluno RM1234 :
 
deleteall 'aluno', 'RM1234'
get 'aluno', 'RM1234'
 
Atividade extra
Nome da atividade: Onde usar HBase?
Sua empresa trabalha com RDBMS Oracle para armazenar e consultar dados de uso de clientes de provedores de serviços de comunicação (Communication Services Providers), informações em tempo real de sensores, dados de comportamento de usuários em sites e dados de monitoração de sites e sistemas. A empresa ainda não trabalha com um ambiente Big Data.
Baseado nesse cenário, você recomendaria o uso de Hbase para substituir o RDBMS Oracle? Escreva um texto justificando sua escolha.
8 - Introdução a MongoDB
O banco de dados Non-Rel MongoDB é orientado a documento e seu nome deriva da palavra inglesa humongous, que pode ser traduzido para gigantesco. Desenvolvido na linguagem C++, um mesmo servidor com MongoDB pode armazenar vários bancos. É desprovido de esquema (“schema free” ou “schemaless”) e trabalha com BSON (Bynary JSON). Para nossa melhor compressão o quadro 1 apresenta uma comparação entre os conceitos usados no banco de dados relacional Oracle e o banco orientado a documentos.
 
	Oracle (RDBMS)
	MongoDB (documento)
	Database
	Database
	Instância de Banco de Dados
	Instância MongDB
	Esquema
	Banco de Dados
	Tabela, View
	Coleção
	Tupla
	Documento (JSON, BSON)
	Coluna
	Campo ou Field
	ROWID / Primary Key
	_id
	Junção
	DBRef (Embedded Document)
	Foreign Key
	Reference
	Partição
	Shard
	Select
	Método find
	Insert
	Método insert
	Update
	Método update
	Delete
	Método remove
Quadro 1 – Comparação entre os termos usados no RDBMS Oracle e NonRel MongoDB
Primeiro acesso
Uma forma simples de acessar o IDE do MongoDb é através do site https://www.tutorialspoint.com/mongodb_terminal_online.php. Todo acesso é feito através do navegador do seu computador ou dispositivo móvel. Não é necessário cadastro para utilizar o ambiente.
O comando show dbs; exibe uma listagem dos databases existentes. Dependendo da instalação, o banco vazio local tem 0.078GB pré-alocado. Esse espaço é pré-alocado por razões de desempenho e para garantir espaço sequencial para persistência. O banco local é criado durante a instalação do software e seus arquivos ficam na pasta data criada anteriormente.
Uma característica dos bancos de dados não relacionais é a facilidade de uso. Não existe, por exemplo, o comando create database, o banco é criado no momento em que é criado uma coleção. Para entrar em um banco específico é utilizado o comando use. O nome do banco não pode conter uma cadeia vazia, um ponto ou palavra reservada. Exemplo: use banco;
É importante definirmos Coleção: O MongoDB armazena dados na forma de documentos. Os documentos são armazenados em formato <chave:valor>. Uma coleção é um conjunto de documentos. A coleção só é criada quando o primeiro documento é inserido. O exemplo efetua a contagem de documentos de uma coleção, acrescenta um documento a coleção, efetua nova contagem e lista todos os seus documentos.
db.biblioteca.count();
db.biblioteca.insert({Nome:’Banco de Dados’, Autor:’Sandra Puga’});
db.biblioteca.count();
db.biblioteca.find();
db.biblioteca.find({Autor: “Sandra Puga”});
db.biblioteca.find({Autor: “Sandra Puga”}).pretty();   
Operações CRUD
O método insert insere um documento a uma coleção. A operação irá criar a coleção caso ela não exista. A operação retorna um objeto WriteResult com o status da operação. A sintaxe é db.collection.insert() onde db indica uma operação do banco, collection é o nome da coleção e insert() é o método usado para incluir documentos em uma coleção.
A operação de insert  cria o atributo _id. É um índice único (unique index) criado durante a criação de uma coleção. É sempre o primeiro campo de um documento. Se o campo _id não for o primeiro em um documento, o servidor move o campo para o início. Cada documento inserido possui seu próprio _id. Cada _id é único. Normalmente um _id é um tipo de dado ObjectId do BSON com 12 bytes. 4 bytes indicam o timestamp da criação do objeto. 3 bytes identificam a máquina. 2 bytes mostram o identificador (id) do processo. 3 bytes contador, iniciado com um valor aleatório. Ordenar por _id é o equivalente a ordenar por data de criação. O método getTimestamp() acessa a data de criação do objeto. É possível atribuir valores a um atributo _id, mas o valor não pode ser repetido. O comportamento é similar uma chave primária em um RDBMS. Pode conter qualquer tipo de dados BSON, com exceção de array. Expressões regulares são desaconselhadas nesse campo em casos de replicação.
O método db.coleção.find() lista os registros de uma coleção e retorna um array com os objetos da coleção, mesmo que a coleção tenha apenas um objeto. Os dados são retornados em um cursor implícito e é preciso interar o cursor para acessar o documento. Se o cursor não for atribuído a uma variável usando a palavra-chave var o cursor fará 20 iterações automaticamente. O método db.coleção.findOne() retorna apenas o primeiro objeto encontrado. Usa-se find() para listagem de registros e findone() para consulta de registros. Uma consulta vazia ({}) retorna todos os documentos de uma coleção. Não especificar uma consulta é o equivalente a uma consulta vazia. db.coleção.find() é equivalente a db.coleção.find({}). É possível efetuar uma consulta por igualdade {<campo>: <valor>}. Neste caso serão listados todos os campos com o valor especificado. Exemplo: 
db.biblioteca.find(); 
db.biblioteca.find({Autor: “Sandra Puga”});
O método find() trabalha com operadores aritméticos de comparação $lt (menor que), $lte (menor ou igual), $gt (maior que),$gte (maior ou igual). O quadro 2 compara o uso com comandos SQL tradicionais para facilitar a compreensão de seu uso.
 
	SQL
	MongoDB
	SELECT * FROM users
	db.users.find()
	SELECT * FROM users WHERE age = 33
	db.users.find({age: 33})
	SELECT * FROM users WHERE age > 33 
	db.users.find({age: {$gt: 33}})
	SELECT * FROM users WHERE age >= 33 
	db.users.find({age: {$gte: 33}})
	SELECT * FROM users WHERE age < 33
	db.users.find({age: {$lt: 33}})
	SELECT * FROM users WHERE age <= 33
	db.users.find({age: {$lte: 33}})
Quadro 2 – Comparação dos operadores aritméticos do SQL com o MongoDB
 
	SQL
	MongoDB
	UPDATE users SET age = 33 WHERE name = ‘Bob’
	db.users.update({name: “Bob”}, {$set: {age: 33}}, {multi: true})
	UPDATE users SET age = age + 2 WHERE name = ‘Bob’
	db.users.update({name: “Bob”}, {$inc: {age: 2}}, {multi: true})
O quadro 3 compara o uso dos operadores com comandos SQL tradicionais para facilitar a compreensão:
 
 
 
	SQL
	MongoDB
	SELECT * FROM users 
WHERE age > 33 AND age < 40
	db.users.find({age: {$gt: 33, $lt: 40}})
	SELECT * FROM users 
WHERE age = 32 AND name = ‘Bob’
	db.users.find({age: 32, name: “Bob”})
	SELECT * FROM users 
WHERE age = 33 OR name = ‘Bob’
	db.users.find({$or:[{age:33}, {name:“Bob”}]})
	SELECT * FROM users 
WHERE age >= 32 AND 
(name = ‘Bob’ OR job=‘Salesman’)
	db.users.find(age: {$gte:32}, $or: [{name: “Bob"}, {job: “Salesman"}] })
Quadro 3 – Comparação dos operadores lógicos do SQL com os do MongoDB
O método update() modifica um ou mais documentos em uma coleção. Pode modificar um campo específico ou substituir um documento existente. Se o parâmetro multi estiver ligado (TRUE), atualiza todos os documentos que atendam o critério de seleção. Se o parâmetro multi estiver desligado (FALSE), atualiza apenas um documento. Possui operadores para facilitar as operações de atualização como $set, modifica o conteúdo de um campo específico, se o campo não existir, um novo campo será adicionado ao documento; $inc, incrementa o conteúdo de um campo; $unset, remove um campo de um documento; $rename, altera o nome de um campo em um documento. O quadro 4 compara o uso dos operadores com comandos SQL tradicionais para facilitar a compreensão.
 
	SQL
	MongoDB
	UPDATE users SET age = 33 WHERE name = ‘Bob’
	db.users.update({name: “Bob”}, {$set: {age: 33}}, {multi: true})
	UPDATE users SET age = age + 2 WHERE name = ‘Bob’
	db.users.update({name: “Bob”}, {$inc: {age: 2}}, {multi: true})
Quadro 4 – Comparação entre os comandos de atualização do SQL com os do MongoDB
O método remove() remove os dados de uma coleção. A coleção continua existindo, mesmo sem dados. A sintaxe geral é db.collection.remove( <query>, <justOne> ) onde <query> específica os critérios de deleção. Para apagar todos os documentos de uma coleção basta especificar um documento vazio ({}). <justOne> define que será apagado apenas um documento. O parâmetro deve ser configurado para true ou 1. O quadro 5 compara o uso dos operadores com comandos SQL tradicionais para facilitar a compreensão.
 
	SQL
	MongoDB
	DELETE FROM users WHERE name = ‘Bob’
	db.users.remove({name: “Bob”})
Quadro 5 – Comparação entre os comando de deleção do SQL com os do MongoDB
 
Atividade extra
Nome da atividade: Onde usar MongDB?
Suponha que  você está trabalhando em uma empresa que irá instalar o MongoDB pela primeira vez para testar o produto.
Baseado nesse cenário, pesquise como você poderia instalar o MongoDB em seu computador? Escreva um roteiro explicando os passos que executou para essa tarefa.
01
Segundo Eric Brewer, o teorema CAP afirma que em sistemas distribuídos é preciso escolher duas propriedades entre:
1. Consistência, Alta Disponibilidade, Particionamento.
2. Consistência, Atomicidade, Periodicidade.
3. Atomicidade, Consistência, Isolamento.
4. Isolamento, Atomicidade, Durabilidade.
5. Durabilidade, Atomicidade, Consistência.
Em 2000, Eric Brewer, em sua palestra na universidade de Berkely, propôs o teorema CAP. Essencialmente o teorema afirma que em qualquer sistema distribuído stateful é preciso escolher entre
Consistency (consistência forte). Todos os nós veem os mesmos dados ao mesmo tempo.
Availability (alta disponibilidade). Toda solicitação recebe uma resposta, seja ela bem-sucedida ou não.
Network Partition Tolerance (tolerância a particionamento dos dados na rede). O sistema continua funcionando mesmo que mensagens sejam perdidas ou parte do sistema falhe.
02
Tolerância a particionamento dos dados na rede é a propriedade que permite que
1. o sistema continue funcionando mesmo que mensagens sejam perdidas ou parte do sistema falhe.
2. todos os nós vejam os mesmos dados ao mesmo tempo.
3. toda solicitação receba uma resposta, seja ela bem-sucedida ou não.
4. em sistemas multiusuário, várias transações possam acessar simultaneamente o mesmo registro.
5. Nenhuma das anteriores.
Nesta questão estamos fazendo referência a propriedade Network Partition Tolerance ou tolerância a particionamento dos dados na rede. Em um ambiente de tecnologia da informação, essa propriedade indica que sistema continue funcionando mesmo que mensagens sejam perdidas ou parte do sistema falhe.
03
Consistência dos dados é a propriedade que permite que
1. o sistema continue funcionando mesmo que mensagens sejam perdidas ou parte do sistema falhe.
2. todos os nós vejam os mesmos dados ao mesmo tempo.
3. toda solicitação receba uma resposta, seja ela bem-sucedida ou não.
4. em sistemas multiusuário, várias transações possam acessar simultaneamente o mesmo registro.
5. vários cálculos possam ser executados ao mesmo tempo, operando sob o princípio de que grandes problemas, geralmente, podem ser divididos em problemas menores, que, então, são resolvidos concorrentemente.
Nesta questão estamos fazendo referência a propriedade Consistency ou consistência forte. Em um ambiente de tecnologia da informação, essa propriedade indica que todos os nós veem os mesmos dados ao mesmo tempo. Neste caso, o termo nó é usado para indicar um computador ou terminal conectado a uma rede.
01
Qual é o formato de entrada padrão em sistema de arquivos HADOOP HDFS?
1. Não há formato de entrada padrão. O desenvolvedor pode especificar qualquer formato de arquivo.
2. XML. O formato de entrada padrão é XML. Se necessário, o desenvolvedor pode especificar outros formatos de entrada de arquivo.
3. JAR. O formato de entrada padrão é JAR. Se necessário, o desenvolvedor pode especificar outros formatos de entrada de arquivo.
4. Arquivo sequencial. O formato de entrada padrão é arquivo-texto sequencial. Os dados precisam ser pré-processados antes de serem usados como formato de entrada padrão.
5. O formato de entrada padrão é TextInputFormat com deslocamento de bytes como uma chave e linha inteira como um valor.
O HADOOP HDFS pode processar qualquer formato de arquivo portanto, não há formato de entrada padrão.
02
Das afirmações abaixo, qual é verdadeira sobre um cliente acessando dados em um sistema de arquivos HADOOP HDFS?
1. Acessa o namenode apenas para obter a localização dos blocos.
2. Acessa os dados apenas para obter os dados que serão lidos.
3. Acessa o datanode para obter a localização dos blocos.
4. Acessa os dados no namenode e bloqueia (lock) a localização do namenode.
5. Recebe os dados através do namenode.
O cliente acessa o namenode para obter a localização dos bloco nos datanodes.
03
O comando hadoop fs –copyFromLocal é usado para:
1. Copiar um arquivo ou diretório do sistema de arquivos local para o HDFS.
2. Copiar um arquivo ou diretório do HDFS para o sistema de arquivos local.
3. Copiar um arquivo ou diretório do HDFS para outro arquivo ou diretório do HDFS.
4. Copiar um arquivo ou diretório do sistema de arquivos local para o sistema de arquivos local.
5. Mover um arquivo ou diretório do HDFS para o sistema de arquivos local.
O comando é usado para copiar um arquivo ou diretório do sistema local para o HDFS.
01
A função MAP trabalha com com pares:
1. Tuplas-registros.
2. Chave-valor.
3. Tupla-chave.
4. Tupla-valor.
5. Registro-tupla.

Outros materiais