Grandes Volumes de Dados Big Data em Java: Exemplo de Aplicação com Hadoop e Twitter Márcio Antônio Slivak1, Edson A. Oliveira Junior2 Resumo. Com a velocidade que a Internet cresce a cada dia, tornou-se imprescindível encontrar maneiras de trabalhar com todo o volume de dados gerados diariamente. O Apache Hadoop surge como uma forma de atender a demanda de tratamento de grandes volumes de dados (Big Data). Este artigo apresenta um exemplo de aplicação do Hadoop para a extração e manipulação de tweets da rede social Twitter. Para tanto, uma aplicação Java foi desenvolvida para confrontar tweets relacionados às manifestações ocorridas no Brasil em setembro de 2013. Palavras-chave: Big Data, Java, HDFS, Apache Hadoop, Apache Pig, Extração de Informação. Abstract. With the speed that the Internet is growing every day, it became imperative to find ways to work with the large volumes of data generated daily. The Apache Hadoop emerges as a way to fulfill the demand of handling large volumes of data (Big Data). This paper presents an application example of Hadoop for the extraction and manipulation of the social network Twitter tweets. Therefore, a Java application was developed to confront tweets related to riots occurred in Brazil in September 2013. Keywords: Big Data, Java, HDFS, Apache Hadoop, Apache Pig, Information Extraction. 1. Introdução A era atual é marcada pela grande quantidade de dados gerados por empresas e usuários de internet. São gerados petabytes [1] de informações diariamente. Não somente informações em banco de dados estruturados como SQL, mas a maioria em formato não estruturado, como postagens, e-mails, fotos, vídeos e outros. Isso dificulta bastante ou, até mesmo, impossibilita a indexação e utilização de tais dados [2,3]. O termo Big Data refere-se ao gigantesco volume de dados gerados atualmente, a sua variedade, à velocidade em que os dados vêm sendo gerados, à urgência para acessar os resultados e aos métodos utilizados para tratar o seu conteúdo, extraindo e filtrando os dados para transformá-los em informações úteis às pessoas, empresas ou organizações [4]. Neste artigo é abordado o Apache Hadoop [5] o mais popular sistema para tratar Big Data, mostrando sua instalação e configuração, bem como um exemplo de aplicação para a extração e tratamento de informações provenientes de mensagens postadas na rede social Twitter [6]. 1 Aluno do curso de especialização em Desenvolvimento de Sistemas para Web – Universidade Estadual de Maringá (UEM) - Av. Colombo, 5790 – Bloco C56 – Maringá – PR – Brasil – [email protected] m 2 Departamento de Informática – Universidade Estadual de Maringá (UEM) - Av. Colombo, 5790 – Bloco C56 – Maringá – PR – Brasil - [email protected] 1 Este artigo está estruturado da seguinte maneira: a Seção 2 apresenta as tecnologias adotadas para o desenvolvimento do trabalho; a Seção 3 mostra as etapas básicas do processo de instalação do ambiente de trabalho para desenvolvimento e testes com o Apache Hadoop; a Seção 4 apresenta um exemplo de aplicação do Hadoop com o Twitter e a Seção 5 apresenta as conclusões e trabalhos futuros. Informações adicionais sobre o processo de instalação e configuração do ambiente para Big Data estão disponíveis nos apêndices deste artigo. 2. Tecnologias Adotadas 2.1. Oracle Virtual Box A Oracle Virtual Box [7] é uma máquina virtual de código aberto, capaz de emular máquinas x86 e AMD64/Intel64 em sistemas Windows, Linux e Mac OS. Fácil de instalar e configurar é distribuída gratuitamente sob os termos da licença GNU General Public License (GPL) versão 2 [8]. O Virtual Box foi usado para criar as máquinas virtuais que executaram o Apache Hadoop [10]. 2.2. Sistema Operacional Ubuntu O Ubuntu [9] é um sistema operacional de código aberto, baseado em Linux, disponível gratuitamente para instalação em computadores pessoais e servidores, fácil de instalar e usar. O Ubuntu Server foi o sistema operacional instalado nas máquinas virtuais que serviu de base para a instalação do Apache Hadoop [10]. 2.3. Apache Hadoop O Apache Hadoop [10] é um framework de código aberto Java para processamento e análise de grande volume e variedade de dados que são processados e armazenados em várias máquinas que podem ter hardware comum. A filosofia do Hadoop é dividir para conquistar, ou seja, divide o trabalho para vários servidores, cada um faz seu trabalho e devolve parte da resposta, essas respostas juntas fornecem o resultado final. O Apache Hadoop serviu de base para o armazenamento de dados dentro do HDFS (Sistema de Arquivo Distribuído do Hadoop) e também processou esses dados. 2.4. Apache Pig Apache Pig é uma linguagem de procedimentos de alto nível para auxiliar e facilitar a consulta a grande volumes de dados semiestruturados. Reduz consideravelmente a complexidade de desenvolvimento, pois disponibiliza uma linguagem parecida com o SQL que é convertida automaticamente em tarefas de mapeamento e redução (MapReduce) no Apache Hadoop [11]. Apache Pig foi usado para facilitar o envio de instruções e consultas ao Apache Hadoop para processar os dados contidos no sistema de arquivos distribuídos HDFS. 2 3. Instalação do Ambiente de Testes 3.1. Instalação e configuração da máquina virtual e do sistema operacional O Hadoop pode ser instalado diretamente na máquina hospedeira quando o sistema é baseado em Linux ou Mac OS, mas se for instalado diretamente na máquina hospedeira, não é possível clonar as máquinas virtuais para fazer os nós escravos que serão abordados ao decorrer deste artigo. Por isso a necessidade de instalar em máquinas virtuais. Este artigo utilizou o Oracle Virtual Box, mas nada impede a utilização de outros sistemas de virtualização. Para instalar o Apache Hadoop, criar uma nova máquina virtual conforme as seguintes instruções: Na tela de criação de máquina virtual (Create Virtual Machine): a) Nomear a máquina virtual como: ‘mestre’; b) Escolher o tipo: Linux, versão: Ubuntu 64; c) Escolher o tamanho da memória: 1024MB mínimo; Na tela de criar disco rígido virtual (Create Virtual Disk): Tamanho de arquivo: 20GB; Tipo de disco rígido: VMDK (Virtual Machine Disk); Armazenamento no disco rígido físico: Alocado Dinamicamente Marcar, opcionalmente, dividir em arquivos menores de que 2GB (obrigatório quando o sistema de arquivos é FAT32); e) Instalar o Ubuntu Server na máquina virtual, nomear a máquina como ‘mestre’. a) b) c) d) 3.2. Configurações Iniciais do Ubuntu Server Após instalar o Ubuntu Server, deve-se configurá-lo conforme as seções a seguir. 3.2.1. Criando usuário e grupo dedicado para o Hadoop Esta etapa não é obrigatória, mas é recomendada, pois auxilia na organização e segurança da instalação do Hadoop, isolando a instalação dos demais aplicativos instalados na máquina [12]. Para criar o grupo e usuário dedicado para o Hadoop, deve-se executar os seguintes comandos no console: $ sudo addgroup hadoop $ sudo adduser --ingroup hadoop hduser 3.2.2. Configurando SSH O Hadoop utiliza o protocolo SSH (Secure Shell) para comunicação entre a máquina mestre e as máquinas escrevas. Para isso é necessário configurar uma conexão SSH para o usuário ‘hduser’ na máquina local (localhost), criando uma chave pública SSH para o usuário ‘hduser’, conforme passos a seguir. a) Conectado como ‘hdadm’, executar o seguinte comando para instalar o SSH Server. $ sudo apt-get install openssh-server b) Conectar-se como hduser $ su – hduser c) Criar a chave SSH, que não terá senha para que não seja obrigatório digitar senha para cada acesso aos nós. $ ssh-keygen -t rsa -P "" 3 d) Habilitar o acesso a SSH para a máquina local com a chave criada $ cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys e) Testar a conexão SSH e armazenamento de host confiável. $ ssh -vvv localhost Se a conexão falhar, verificar a configuração do SSH com o seguinte comando conectado com o usuário ‘hdadm’: $ sudo nano /etc/ssh/sshd_config Procurar pela linha que começa com ‘PubkeyAuthentication’, se encontrada certificar-se que exista um ‘yes’ à frente dela (havendo um ‘no’, trocar por ‘yes’), se não for encontrada a linha, criá-la no fim do arquivo seguido de ‘yes’. Acrescentar o usuário ‘hduser’ à linha ‘AllowUsers’. Se a linha não existir, criar a linha ‘AllowUsers hduser’. Depois de feitas as alterações grave-as apertando ‘Ctrl+X’. Tentar conectar via SSH novamente. 3.2.3. Desabilitar conexão IPVA6 Edite o arquivo de configuração /etc/sysctl.conf, usando o seguinte comando como usuário ‘hdadm’ [12]: $ sudo nano /etc/sysctl.conf Acrescente ao final do arquivo as seguintes linhas e grave a alteração, pressionando ‘Ctrl+X’. net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 Execute o comando abaixo para verificar se a alteração funcionou, o resultado deve ser obrigatoriamente ‘1’, desabilitado. Caso ‘0’ ainda está habilitado. $ cat /proc/sys/net/ipv6/conf/all/disable_ipv6 3.2.4. Instalação da biblioteca nss-mdns Esta biblioteca é necessária para que as máquinas mestre e escravas possam se comunicar por meio de nomes, usando o domínio ‘.local ’ [14]. Para instalá-la executar o seguinte comando: $ sudo apt-get install libnss-mdns 3.2.5. Instalação do Java 7 no Ubuntu via PPA A instalação do Java é pré-requisito obrigatório para a instalação e execução do Apache Hadoop, entretanto o instalador do Java não consta na lista de instalação padrão do Ubuntu, para fazê-lo é necessário executar os comandos a seguir [12, 15]: $ $ $ $ sudo sudo sudo sudo apt-get install python-software-properties add-apt-repository ppa:webupd8team/java apt-get update apt-get install oracle-java7-installer 3.3. Instalação e Configuração do Apache Hadoop Para baixar e instalar o Apache Hadoop deve-se executar os comandos abaixo no terminal como usuário ‘hdadm’. Isso fará com que a pasta ‘/home/hdadm’ seja acessada, depois executar o comando ‘wget’ para baixar o arquivo hadoop-1.2.1-bin.tar.gz (ou mais recente e estável) para pasta ‘home’, depois extrair o conteúdo do arquivo usando ‘tar’, 4 mover o diretório extraído para a pasta ‘/usr/local/hadoop’ e, por fim, deve-se atribuir permissão ao usuário ‘hduser’ para executar na pasta [12]. $ $ $ $ $ cd ~ wget sudo sudo sudo http://ftp.unicamp.br/pub/apache/hadoop/core/stable/hadoop -1.2.1-bin.tar.gz tar xzf hadoop-1.2.1-bin.tar.gz mv hadoop-1.2.1 /usr/local/hadoop chown -R hduser:hadoop /usr/local/hadoop 3.3.1 Variáveis de ambiente Para facilitar o uso do Hadoop é necessário configurar algumas variáveis de ambiente Linux, para isso é necessário acrescentar algumas linhas ao arquivo de configuração do terminal ‘/home/hduser/.bashrc’ [12], primeiro deve-se executar: $ sudo nano /home/hduser/.bachrc Ir até o final do arquivo, acrescentar as seguintes linhas e salvar o arquivo pressionando ‘Ctrl+X’: export HADOOP_HOME=/usr/local/hadoop export JAVA_HOME=/usr/lib/jvm/java-7-oracle export PATH=$PATH:$HADOOP_HOME/bin 3.3.2 Configurando os arquivos do Hadoop As configurações do Hadoop são armazenadas em arquivos de texto e XMLs dentro da pasta ‘/usr/local/hadoop/conf’, a descrição de cada arquivo de configuração pode ser consultada na Tabela 1 a seguir [16]: Tabela 1: Arquivos de Configuração do Hadoop. Arquivo hadoop-env.sh Descrição Contém configurações de variáveis de ambiente usadas nos scripts do Hadoop. core-site.xml Contém configurações do núcleo do Hadoop, como opções relacionadas à Entrada/Saída (I/O) comuns para o HDFS e MapReduce. hdfs-site.xml Contém configurações dos serviços de HDFS: o namenode, o namenode secundário, e os datanodes. mapred-site.xml Contém configurações para os serviços de MapReduce: o jobtrack er e os task track ers Contém uma lista de máquinas que são mestres, executam namenode secundários, uma máquina por linha. masters slaves Contém uma lista de máquinas que são escravas, executam datanode e task track er, uma máquina por linha. hadoop-met Contém propriedades que controlam como as métricas são publicadas no Hadoop. Contém propriedades para o sistema de arquivo de logs, log de auditoria do namenode, log de tarefas para os processos do task track er. log4j.properties Neste artigo foram usados somente os seguintes arquivos de configuração: coresite.xml, mapred-site.xml, hdfs-site.xml, masters e slaves, os demais arquivos de configurações permaneceram com as configurações padrões, não foram alterados. 5 3.3.2.1. Editando arquivo /usr/local/hadoop/conf/hadoop-env.sh Executar o comando abaixo para editar o arquivo hadoop-env.sh: $sudo nano /usr/local/hadoop/conf/hadoop-env.sh Substituir a linha existente da variável de ambiente do caminho Java iniciada por: ‘#export JAVA_HOME=’, pela linha abaixo, do caminho do Java que foi instalado anteriormente [12]: export JAVA_HOME=/usr/lib/jvm/java-7-oracle 3.3.2.2. Editando arquivo /usr/hadoop/conf/core-site.xml Acrescentar o texto do Quadro 1 entre <configuration> e </configuration> no arquivo core-site.xml [12]. A propriedade hadoop.tmp.dir determina o local no qual o Hadoop gravará seus arquivos de trabalho e a propriedade fs.default.name contém o endereço e porta na qual o sistema de arquivo HDFS será executado. <property> <name>hadoop.tmp.dir</name> <value>/home/hduser/hadoop</value> <description>Diretório de trabalho do Hadoop</description> </property> <property> <name>fs.default.name</name> <value>hdfs://mestre.local:54310</value> <description>Determina o endereço e porta para o sistema de arquivos HDFS </description> </property> Quadro 1: Trecho de código XML para inserir no arquivo /usr/hadoop/conf/core -site.xml 3.3.2.3. Editando arquivo /usr/hadoop/conf/mapred-site.xml Acrescentar o texto do Quadro 2 entre <configuration> e </configuration> no arquivo mapred-site.xml [12]. A propriedade mapred.job.tracker determina o local no qual será executado o rastreador de tarefas, jobtracker. <property> <name>mapred.job.tracker</name> <value>mestre.local:54311</value> <description>Determina o endereço e a porta onde o rastreador de tarefas do MapReduce será executado. </description> </property> Quadro 2: Trecho de código XML para inserir no arquivo /usr/hadoop/conf/mapred-site.xml 6 3.3.2.4. Editando arquivo /usr/hadoop/conf/hdfs-site.xml Acrescentar o texto do Quadro 3 entre <configuration> e </configuration> no arquivo hdfs-site.xml [12 , 13]. A propriedade dfs.replication determina o número de replicações padrão e local no qual será executado o rastreador de tarefas, jobtracker. <property> <name>dfs.replication</name> <value>2</value> <description>Determina o número padrão de replicações que serão feitas. </description> </property> Quadro 3: Trecho de código XML para inserir no arquivo /usr/hadoop/conf/hdfs-site.xml 3.3.2.5. Editando arquivo /usr/local/hadoop/conf/masters Nesse arquivo são definidas as máquinas mestres, uma para cada linha, neste trabalho é acrescentada somente uma, a máquina ‘mestre’ [13]. Para isso, deve-se executar o comando abaixo. Quando aberto o arquivo, apagar todo o conteúdo do arquivo, digitar na primeira linha somente ‘mestre.local’ e gravar. $ sudo nano /usr/local/hadoop/conf/masters 3.3.2.6. Editando arquivo /usr/local/hadoop/conf/slaves Nesse arquivo são definidas as máquinas escravas, uma para cada linha, neste trabalho, é acrescentada somente uma, a máquina ‘escravo1’. [13] Para isso, deve-se executar o comando abaixo. Quando aberto o arquivo apagar todo o conteúdo do arquivo, digitar na primeira linha ‘mestre.local’, na segunda ‘escravo1.local’, uma linha para cada máquina escrava que se deseja criar e gravar. Notar que o mestre também faz parte do cluster Hadoop. $ sudo nano /usr/local/hadoop/conf/slaves 3.4. Máquinas ‘escravas’ Depois de instalada e configurada a máquina ‘mestre’ terá que ser clonada para criar as máquinas escravas. Para isso, desligar a máquina virtual ‘mestre’, abrir o gerenciador do Virtual Box, selecionar a máquina virtual ‘mestre’, clicar com o botão direito e escolher ‘Clone’ (Clonar), nomear a máquina virtual clonada de ‘escravo1’. Marcar obrigatoriamente a opção 'Reinitialize the MAC address of all network cards' (Reiniciar endereços MAC de todas as placas de rede) e clicar em ‘Continue’ (Continuar). Na próxima etapa escolher ‘Full clone’ (Clonagem completa), clicar em ‘Clone’ (Clonar) e aguardar o processo terminar. Quando a clonagem estiver completa, ligar a nova máquina virtual ‘escravo1’ e conectar como usuário ‘hdadm’. O nome de máquina da máquina recém-clonada deve ser alterado de ‘mestre’ para ‘escravo1’ editando os seguintes arquivos /etc/hostname e /etc/hosts. $ sudo nano /etc/hostname $ sudo nano /etc/hosts Devido à clonagem da máquina também é necessário apagar o arquivo /etc/udev/rules.d/70-persistent-net.rules que contém informações sobre a placa de rede 7 anterior da máquina ‘mestre’ que devem ser eliminadas para que a máquina ‘escravo1’ refaça conforme sua nova configuração de rede. Para isso, executar o comando a seguir [19]. $ sudo rm -f /etc/udev/rules.d/70-persistent-net.rules Depois de alterado o nome da máquina, reiniciar a máquina virtual ‘escravo1’ e iniciar também a máquina ‘mestre’, acessar a máquina ‘mestre’ com usuário ‘hduser’, para fazer a cópia da chave publica de acesso SSH para a máquina ‘escravo1’ com o seguinte comando [13]: $ ssh-copy-id -i $HOME/.ssh/id_rsa.pub [email protected] Este comando pede pela senha de logon do usuário ‘hduser’ da máquina ‘escravo1’ então copiará a chave para ela. Depois de feita a cópia, é preciso acessar uma vez a máquina ‘escravo1’ a partir da máquina ‘mestre’ para gravar a máquina ‘mestre’ como máquina conhecida e confiável (known host). Fazer o mesmo para ‘mestre’, para isso, execute os seguintes comandos a partir da máquina ‘mestre’ com o usuário ‘hduser’: $ ssh mestre.local $ ssh escravo1.local Assim, a máquina ‘mestre’ será capaz de controlar sua máquina escrava, ‘escravo1’. Para acrescentar mais nós escravos, basta repetir os passos de clonagem e configuração, acrescentando os novos escravos ao arquivo /usr/local/hadoop/conf/slaves. 3.5. Formatando o sistema de arquivos HDFS O Hadoop utiliza o sistema de arquivo distribuído HDFS (Hadoop Distributed File System) [17], por isso aguarda-se até serem criadas as máquinas escravas para formatálo. O sistema HDFS somará as capacidades de armazenamento de todas as máquinas pertencentes ao cluster. Qualquer arquivo gravado no sistema HDFS poderá ser replicado para garantir segurança dos arquivos. Além disso, um arquivo pode estar separado em partes dependendo do seu tamanho, cada parte poderá ser replicada ‘n’ vezes em máquinas diferentes de acordo com a quantidade de replicações informada no arquivo /usr/local/hadoop/conf/hdfs-site.xml na propriedade dfs.replication [13]. Para formatar o sistema de arquivos HDFS use o seguinte comando: $ hadoop namenode -format O resultado do comando pode ser visto na Figura 1 a seguir. 8 Figura 1: Formatação do sistema de arquivos HDFS do Hadoop 3.6 Carregando o Hadoop Agora que já foi instalado e formatado o HDFS, deve-se iniciar os serviços do Hadoop, para isso é executado o script /usr/local/hadoop/bin/start-all.sh que pode ser chamado por meio do comando abaixo, pois já foi acrescentado o caminho do Hadoop às variáveis de ambiente [12]. $ start-all.sh Este comando executará automaticamente os serviços necessários na máquina ‘mestre’ e também na máquina escrava ‘escravo1’. É possível ver os serviços carregados usando o comando abaixo na máquina ‘mestre’ e na máquina escrava ‘escravo1’. Os resultados dos comandos encontram-se no Apêndice A. $ jps Após executado o comando ‘jps’ na máquina ‘escravo1’ notasse que os serviços na máquina ‘escravo1’ foram executados automaticamente ao iniciar os serviços na máquina ‘mestre’, pois a máquina ‘mestre’ os executou fazendo as chamadas pelo protocolo SSH discutido anteriormente [12, 13]. O Hadoop também disponibiliza o monitoramento dos seus serviços via navegador, acessando alguns endereços de página compostos pelo nome da máquina seguido das portas dos serviços, conforme mostra a Tabela 2. No Apêndice B estão as interfaces dos serviços. Esse recurso deverá ser acessado pela máquina hospedeira das máquinas virtuais, pois o Ubuntu Server, por padrão, não dá suporte à imagem, somente terminal. 9 Tabela 2: Interfaces Web Hadoop Endereço http://mestre.local:50070/ Nome Interface web do NameNode (Camada HDFS) http://mestre.local:50030/ Interface web do JobTrack er (camada MapReduce) http://mestre.local:50060/ Interface web do Task Track er (camada MapReduce) Descrição Mostra informações sobre capacidade total e disponível, nós ativos e nós parados. Possibilita navegar no sistema de arquivos HDFS, mostrando diretórios, arquivos e seus conteúdos. Também mostra os logs dos Namenodes. Mostra informações sobre os trabalhos sendo executado: em execução, concluídos e falhos. Mostra estatística e logs dos trabalhos executados. Mostra as tarefas sendo executadas e paradas, também mostra o log do Hadoop do nó local. 4. Exemplo de Aplicação O exemplo de aplicação escolhido foi analisar mensagens postadas no Twitter (tweets), buscando confrontar os ‘tweets’ das Polícias Militar e Federal contra os ‘tweets’ dos manifestantes ‘Anonymous’ (anônimos). 4.1. Extração dos dados do Twitter Foi desenvolvida uma pequena aplicação em Java utilizando o framework ‘Twitter4J’ [21] para baixar dados de perfis do Twitter em intervalos mínimos de 30 minutos, devido à limitação de quantidade de solicitações à API do Twitter. Quando tais solicitações são executadas demasiadamente, o Twitter é bloqueado temporariamente e só volta a funcionar após no mínimo 15 minutos, podendo em casos extremos ser bloqueado definitivamente [22]. Nos quadros a seguir, do Quadro 4 ao Quadro 8, são mostrados os trechos de código fonte mais importantes da aplicação. Para fazer consultas ao Twitter como aplicação é necessário criar uma ‘chave consumidora’ e um ‘token de acesso’. Para isso, deve-se acessar o seguinte site: https://dev.twitter.com/apps/new e autenticar-se com uma conta do Twitter. A aplicação funciona da seguinte forma: ao iniciar o método ‘main’, Quadro 4, é chamado o método ‘carregaPropriedades’, Quadro 5, que lê as informações contidas no arquivo de configurações twitter4j.properties e chama para cada usuário de Twitter desejado o método ‘lerTwitter’, Quadro 6, que lê os últimos tweets do usuário, com ‘Id’ maior que o último ‘Id’ lido anteriormente para não haver duplicações de registros e faz alguns ajustes na mensagem deixando-a mais limpa. Então os tweets lidos são gravados em arquivo, com as informações necessárias separadas por caracteres ‘Tabs’ com a seguinte estrutura: Id, data mensagem, tipo de mensagem, tipo perfil, usuário e mensagem (tweet). Um exemplo dos dados gravados pode ser visto na Figura 2. 10 Figura 2: Exemplo de texto extraído utilizando a aplicação de extração de tweets package twitterextractor; import import import import import import import import import java.io.BufferedReader; import java.io.BufferedWriter; java.io.File; import java.io.FileInputStream; java.io.FileReader; import java.io.FileWriter; java.io.IOException; import java.io.InputStream; java.text.SimpleDateFormat; import java.util.Calendar; java.util.List; import java.util.Properties; twitter4j.Query; import twitter4j.QueryResult; twitter4j.Status; import twitter4j.Twitter; twitter4j.TwitterFactory; public class TwitterExtractor { static File file = new File("twitter4j.properties"); static Properties prop = new Properties(); static String jTab = "" + (char) 9; static String jEnter1310 = "" + (char) 10 + (char) 13; static String jEnter1013 = "" + (char) 13 + (char) 10; static String jEnter10 = "" + (char) 10; static String jEnter13 = "" + (char) 13; public static void main(String[] args) { if (carregaPropriedades()) { try {//Policias lerTwitter("agenciapf", "p"); Thread.sleep(5000); lerTwitter("pmdfcom", "p"); Thread.sleep(5000); lerTwitter("PMERJ", "p"); Thread.sleep(5000); lerTwitter("PMESP", "p"); Thread.sleep(5000); //Anônimos lerTwitter("AnonBr4sil2", "a"); Thread.sleep(5000); lerTwitter("AnonBRNews", "a"); Thread.sleep(5000); lerTwitter("anonopsbrasil", "a"); Thread.sleep(5000); lerTwitter("PlanoAnonBR", "a"); Thread.sleep(5000); lerTwitter("AnonymousFUEL", "a"); } catch (InterruptedException ex) { System.out.println("Erro ao ler tweets: " + ex.getMessage()); } } else { System.out.println("Erro ao ler configurações de:" + file.getName()); } } //Ver código completo no Quadro 5 private static boolean carregaPropriedades() {...} //Ver código completo no Quadro 6 private static void lerTwitter(String twitteruser, String strTipoFerfil) {...} //Ver código completo no Quadro 7 private static String limparTweet(String t) {...} } Quadro 4: Trecho de código fonte do extrator de tweets - main 11 private static boolean carregaPropriedades() { InputStream is = null; try { if (file.exists()) { is = new FileInputStream(file); prop.load(is); System.out.println("Configurações carregadas."); return true; } else { System.out.println("Configurações não encontradas!"); } } catch (IOException ex) { System.out.println("Erro:" + ex.getMessage()); } return false; } Quadro 5: Trecho de código fonte do extrator de tweets - carregaPropriedades private static void lerTwitter(String twitteruser, String strTipoFerfil) { String linha; Twitter twitter; Query query; QueryResult result; Status tweet; Long lngId = 0L; Long lngId2 = 0; String strDate = ""; String strUser = ""; String strTweet = ""; String strTipo = ""; File nFile = new File(twitteruser + "_out.txt"); System.out.println("Lendo " + twitteruser); try { if (!nFile.exists()) { nFile.createNewFile(); } else { FileReader fr = new FileReader(twitteruser + "_out.txt"); BufferedReader br = new BufferedReader(fr); String line; while ((line = br.readLine()) != null) { String tmp = line.split(jTab)[0]; if (tmp.trim().length() > 0) { if (Long.parseLong(tmp) > lngId2) { lngId2 = Long.parseLong(tmp); //Encontrando ultimo Id } } } } FileWriter fw = new FileWriter(nFile.getAbsoluteFile(), true); BufferedWriter bw = new BufferedWriter(fw); bw.flush(); twitter = new TwitterFactory().getInstance(); //Buscando tweets maiores que lngId2 (evitando repetições) query = new Query("from:" + twitteruser).sinceId(lngId2); result = twitter.search(query); List<Status> tweets = result.getTweets(); for (int j = 0; j < tweets.size(); j++) { tweet = tweets.get(j); lngId = tweet.getId(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar cal = Calendar.getInstance(); cal.setTime(tweet.getCreatedAt()); strDate = dateFormat.format(cal.getTime()); //fixo, pois o Twitter removeu o suporte à retweet por timeline/query strTipo = "tweet"; strUser = tweet.getUser().getScreenName(); strTweet = limparTweet(tweet.getText()); linha = lngId.toString() + jTab + strDate + jTab + strTipo + jTab + strTipoFerfil + jTab + strUser + jTab + strTweet + jEnter13; bw.append(linha); } bw.close(); } catch (Exception ex1) { System.out.println("Erro:" + ex1.getMessage()); } } Quadro 6: Trecho de código fonte do extrator de tweets - lerTwitter 12 private static String limparTweet(String t) { //Limpa e corrige alguns erros no tweet t = t.replace(jTab, " "); t = t.replace(jEnter1013, " "); t = t.replace(jEnter10, " "); t = t.replace(jEnter13, " "); t = t.replace("&nbsp;", " "); t = t.replace(" ", " "); while (t.contains(" ")) { t = t.replace(" ", " "); } t = t.replace("# ", "#"); t = t.replace("@ ", "@"); t = t.replace("http:// ", "http://"); t = t.replace("www. ", "www."); t = t.replace("/ ", "/"); t = t.replace(" /", "/"); return t.trim(); } Quadro 7: Trecho de código fonte do extrator de tweets – limparTweet debug = false oauth.consumerKey = MbjlfH........joKaqUA oauth.consumerSecret = SvHnMQj2cKa........omF0DMPlP2KpkhtASI3AVs oauth.accessToken = 100004316-79........yPvAzetmnryh3G1MzGgdzMlJ7PA9g5 oauth.accessTokenSecret = 8TiuXc........p8i8ASCQFKiX9ufucLURTsRpr1aQ Quadro 8: Arquivo de configurações ‘twitter4j.properties’ do extrator de tweets 4.2. Carregando os dados obtidos para o sistema de arquivos HDFS Para aproveitar a vantagem de processamento distribuído do Hadoop é preciso carregar os arquivos dentro do sistema distribuído HDFS. A seguir, na Tabela 3 estão os comandos básicos do sistema HDFS para listar, copiar, apagar, mover e renomear arquivos ou pastas [17]. Tabela 3: Comandos básicos do sistema HDFS. hadoop fs -ls Comando Descrição Li s tar conteúdo das pastas hadoop fs -mkdir nome_pasta Cri a r nova s pastas hadoop fs -rm nome_arquivo Excl ui r a rquivos hadoop fs -rmr nome_pasta Excl ui r pastas e os s eus conteúdos recursivamente Copi a r arquivos do s i stema l ocal para o sistema HDFS Copi a r arquivos do s i stema HDFS para o sistema l ocal Copi a arquivo dentro do HDFS hadoop fs -copyFromLocal /caminho_local/arquivo /caminho_hdfs/arquivo hadoop fs -copyToLocal /caminho_hdfs/arquivo /caminho_local/arquivo hadoop fs -cp /origem/arquivo /destino/arquivo hadoop fs -mv /nome_ou_local_antigo /nome_ou_local_novo Mover ou renomear a rquivos e pa s tas dentro do HDFS Para usar os arquivos extraídos na etapa anterior, é preciso copiar os arquivos obtidos na aplicação de extração de tweets da máquina hospedeira (máquina que roda as máquinas virtuais) para dentro da máquina virtual ‘mestre’. Para isso executar os seguintes comandos na máquina ‘mestre’ para criar as pastas nas quais serão copiados os arquivos da máquina hospedeira para a máquina virtual ‘mestre’. $ mkdir /home/hduser/policia $ mkdir /home/hduser/anonimo 13 No terminal da máquina hospedeira é necessário executar os comandos abaixo para copiar da hospedeira para a máquina virtual. $ scp /local/onde/estao/arquivos/policia/*.* [email protected]:~/dados/policia $ scp /local/onde/estao/arquivos/anonimo/*.* [email protected]:~/dados/anonimo Se os arquivos já estiverem na máquina virtual, deve-se fazer uma cópia ou mover os arquivos da polícia para pasta /home/hduser/policia e os arquivos dos anônimos para a pasta /home/hduser/anonimo. Depois de feita a cópia dos arquivos para a máquina virtual ‘mestre’, executar os comandos abaixo, assumindo que os arquivos já foram copiados para a máquina virtual dentro das pastas /home/hduser/policia e /home/hduser/anonimo. $ $ $ $ $ hadoop hadoop hadoop hadoop hadoop fs fs fs fs fs -mkdir /user/hduser/dados -mkdir /user/hduser/dados/policia -mkdir /user/hduser/dados/anonimo -copyFromLocal /home/hduser/policia/* /user/hduser/dados/policia/ -copyFromLocal /home/hduser/anonimo/* /user/hduser/dados/anonimo/ Os resultados das cópias dos arquivos podem ser vistos no Apêndice C. 4.3. Utilizando Apache Pig para extrair informações dos dados O Apache Pig é utilizado para processar os dados extraídos do Twitter para analisar os tweets dos anônimos contra os tweets da polícia. O Pig pode ser executado em dois modos: modo local com arquivos locais da máquina ou modo Hadoop mapreduce [20] que utiliza o sistema HDFS aproveitando as vantagens de processamento distribuído. Neste trabalho foi utilizado o modo Hadoop mapreduce. Para isso certifique-se de ter iniciado os serviços do Hadoop executando o comando start-all.sh conforme instruções anteriores no item ‘3.6 Carregando o Hadoop’. Depois digite apenas o comando ‘pig’ no terminal da máquina ‘mestre’ como usuário ‘hduser’. $ pig O comando ‘pig’ abre o Grunt Shell [18], que é o terminal no qual são executados os comandos do Pig. A partir do Grunt Shell foram executados em sequência os comandos dos Quadros 9, 10 e 11. Os comandos dos Quadros 9 e 10 possuem os mesmos comandos e passos, exceto nas entradas de dados que carregam os arquivos das pastas do HDFS (/user/hduser/dados/policia e /user/hduser/dados/anonimo) e também nos filtros que são aplicados a cada perfil (polícia e anônimos). Abaixo são explicados os passos dos Quadros 9 e 10 para obter os dados no formato desejado para processamento de cada perfil: Primeiro é registrada a biblioteca piggybank.jar com comando REGISTER para que seja possível definir com o comando DEFINE a função REPLACE, que realiza a troca de um texto por outro, necessário nos passos seguintes; O comando LOAD atribui a carga das pastas /user/hduser/dados/policia e /user/hduser/dados/anonimo aos alias tP0 e tA0 respectivamente, definindo o nome das colunas e seus tipos: (id:long, momento:chararray, tipo:chararray, tipoPerfil:chararray, user:chararray, tweet:chararray); São filtrados tP0 e tA0 com o comando FILTER para pegar somente tweets do tipo tweet, os resultados dos filtros são atribuídos aos alias tP1 e tA1; São agrupados tP1 e tA1 para remover possíveis tweets repetidos utilizando o comando GROUP, o resultado do agrupamento é atribuído aos alias tP2 e tA2; Com o comando FOREACH, é recuperada cada ocorrência do agrupamento e são geradas, com o comando GENERATE, as colunas necessárias para os 14 próximos passos (group.momento, group.user, group.tweet), o resultado é atribuído a tP e tA; A coluna tweet é filtrada com as seguintes expressões regulares aplicadas ao comando MATCHES. Para a polícia: '.*(movimento|ato)\\s*(pac(í|i)fico|organizado|passe livre).*|.*derruba site.*|.*anon(y|i).*|.*ddos.*|.*tango.*|.*manifest.*|.*protest.*|.*passeata.*|.*bl ack\\s*bloc.*' Que retornará qualquer ocorrência e palavras que contenham as partes indicadas acima, exemplo: todos os tweets que comecem com ‘manifest’ (manifestante, manifestantes, manifestação...). Todas as ocorrências do filtro serão atribuídas ao alias fP; Para os anônimos: '.*pol(i|í)cia.*|.*pm.*|.*pf.*|.*milico.*|.*tropa de choque.*|.*batalh(ã|a)o.*|.*viatura.*' Que retornará qualquer ocorrência e palavras que contenham as partes indicadas acima, exemplo: todos os tweets que comecem com ‘polícia’ (polícia, policiais, policial...). Todas as ocorrências do filtro serão atribuídas ao alias fA; Para cada resultado de fP e fA é limpado o campo momento, removendo os caracteres indesejados com o comando REPLACE definido anteriormente, deixando somente números, mudando o tipo de momento para long, mantendo as demais colunas intactas. Os resultados são atribuídos aos alias nP e nA; Ordenam-se nP e nA pela coluna momento, usando o comando ORDER e atribui-se o resultado aos alias oP e oA; Com o resultado desejado para cada perfil pronto, é possível gravar o resultado no sistema HDFS. Mas antes de gravá-los, por precaução, apagam-se as pastas de destino, pois se elas já existirem haverá um erro na gravação do resultado. Para isso, é executado o comando RMF seguido das pastas de destino (/user/hduser/dados/policia/falouDeManifestantes e user/hduser/dados/anonimo/falouDaPolicia) Então se grava no sistema HDFS o resultado usando o comando STORE para oP e oA, Carregam-se os resultados gravados nas pastas em tRP e tRA os quais estão prontos para o Quadro 11. 15 -- ----------------- P O L I C I A -------------------------------REGISTER /usr/local/pig/contrib/piggybank/java/piggybank.jar; DEFINE REPLACE org.apache.pig.piggybank.evaluation.string.REPLACE(); tP0 = LOAD '/user/hduser/dados/policia/' USING PigStorage('\t') AS (id:long, momento:chararray, tipo:chararray, tipoPerfil:chararray, user:chararray, tweet:chararray); tP1 = FILTER tP0 BY (tipo == 'tweet'); tP2 = GROUP tP1 by (id, momento, tipo, tipoPerfil, user, tweet); tP = FOREACH tP2 GENERATE group.momento, group.user, group.tweet; fP = FILTER tP BY(LOWER(tweet) matches '.*(movimento|ato)\\s*(pac(í|i)fico|organizado|passe livre).*|.*derruba site.*|.*anon(y|i).*|.*ddos.*|.*tango.*|.*manifest.*|.*protest.*|.*passeata.*|.*black \\s*bloc.*'); nP = FOREACH fP GENERATE REPLACE(REPLACE(REPLACE($0,'-',''),':',''),' ','') AS momento, $1 AS user, $2 AS tweet; oP = ORDER nP BY (momento); RMF /user/hduser/dados/policia/falouDeManifestantes; STORE oP INTO '/user/hduser/dados/policia/falouDeManifestantes' ; tRP = LOAD '/user/hduser/dados/policia/falouDeManifestantes' USING PigStorage('\t') AS (momento:chararray, user:chararray, tweet:chararray); Quadro 9: Script Pig para preparar os dados dos tweets da polícia -- ----------------- A N O N I M O S ------------------------------REGISTER /usr/local/pig/contrib/piggybank/java/piggybank.jar; DEFINE REPLACE org.apache.pig.piggybank.evaluation.string.REPLACE(); tA0 = LOAD '/user/hduser/dados/anonimo/' USING PigStorage('\t') AS (id:long, momento:chararray, tipo:chararray, tipoPerfil:chararray, user:chararray, tweet:chararray); tA1 = FILTER tA0 BY (tipo == 'tweet'); tA2 = GROUP tA1 by (id, momento, tipo, tipoPerfil, user, tweet); tA = FOREACH tA2 GENERATE group.momento, group.user, group.tweet; fA = FILTER tA BY(LOWER(tweet) matches '.*pol(i|í)cia.*|.*pm.*|.*pf.*|.*milico.*|.*tropa de choque.*|.*batalh(ã|a)o.*|.*viatura.*'); nA = FOREACH fA GENERATE REPLACE(REPLACE(REPLACE($0,'-',''),':',''),' ','') AS momento, $1 AS user, $2 AS tweet; oA = ORDER nA BY (momento); RMF /user/hduser/dados/anonimo/falouDaPolicia; STORE oA INTO '/user/hduser/dados/anonimo/falouDaPolicia'; tRA = LOAD '/user/hduser/dados/anonimo/falouDaPolicia' USING PigStorage('\t') AS (momento:chararray, user:chararray, tweet:chararray); Quadro 10: Script Pig para preparar os dados dos tweets dos anônimos 16 Abaixo são explicados os passos do Quadros 11 para obter os dados no formato desejado para análise dos perfis: Usa-se o comando CROSS para cruzar todos os resultados de tRP e tRA, atribuindo os resultados a tJ; É gravado em disco tJ usando comando STORE para a pasta /user/hduser/dados/juntos/policiaXanonimos; Carregam-se os resultados gravados na pasta /user/hduser/dados/juntos/policiaXanonimos, renomeando as colunas para (amomento:chararray, auser:chararray, atweet:chararray, pmomento:chararray, puser:chararray, ptweet:chararray) e atribuindo ao alias tJ, aproveitando o mesmo alias mas agora com as novas colunas; Para cada resultado de tJ, são trocados os tipos de amomento e pmomento para datetime e atribuído o resultado ao alias tJ1; Ordena-se tJ1 por pmomento e atribui-se a otJ1, depois ordena-se otJ1 por amomento e atribui-se a otJ2; Filtra-se otJ2 para mostrar para cada ocorrência de amomento (momento do tweet dos anônimos) as ocorrências de pmomento (momento do tweet da polícia) menores ou iguais a amomento mais 24 horas e atribui-se o resultado a ftJ1; Grava-se o resultado de ftJ1 na pasta /user/hduser/dados/juntos/policiaXanon24h; -- -------------- P O L I C I A x A N O N I M O S -------------tJ = CROSS tRA, tRP; RMF /user/hduser/dados/juntos/policiaXanonimos; STORE tJ INTO '/user/hduser/dados/juntos/policiaXanonimos' ; tJ = LOAD '/user/hduser/dados/juntos/policiaXanonimos' USING PigStorage('\t') AS (amomento:chararray, auser:chararray, atweet:chararray, pmomento:chararray, puser:chararray, ptweet:chararray); tJ1 = FOREACH tJ GENERATE ToDate($0, 'yyyyMMddHHmmss') AS (amomento:datetime), $1 AS (auser:chararray), $2 AS (atweet:chararray), ToDate($3, 'yyyyMMddHHmmss') AS (pmomento:datetime), $4 AS (puser:chararray), $5 AS (ptweet:chararray); otJ1 = ORDER tJ1 BY(pmomento); otJ2 = ORDER otJ1 BY(amomento); ftJ1 = FILTER otJ2 BY ((pmomento >= amomento) and (pmomento <= AddDuration(amomento,'PT24H'))); RMF /user/hduser/dados/juntos/policiaXanon24; STORE ftJ1 INTO '/user/hduser/dados/juntos/policiaXanon24h'; Quadro 11: Script Pig para juntar os dois perfis e obter os resultados 4.4. Resgatando o resultado do HDFS É possível resgatar os arquivos do sistema de arquivos HDFS de duas maneiras, (Apêndice D): Utilizando o comando copyToLocal do HDFS, conforme os comandos abaixo: $ cd /home/hduser $ mkdir resultado $ hadoop fs -copyToLocal /user/hduser/dados/juntos/policiaXanon24h/part-r-00000 /home/hduser/resultado Baixando o arquivo da interface web Hadoop Namenode comentada anteriormente no item ‘3.6 Carregando o Hadoop’ a partir do endereço: http://mestre.local:50070, clicando em ‘Browse the filesystem’, navegando até a pasta /user/hduser/dados/juntos/policiaXanon24h e clicando no arquivo ‘part-r00000’, depois clicando em ‘Download this file’, o arquivo será salvo na máquina na qual foi acessado o endereço da interface web. 17 4.5. Análise do Resultado Conforme a os filtros aplicados no script do Quadro 11, tem-se as informações cruzadas para cada ocorrência de tweets dos anônimos com os tweets do perfil da polícia nas próximas 24 horas, dispostas da seguinte forma: Data Anônimo, Usuário Anônimo, Tweet Anônimo, Data Polícia, Usuário Polícia, Tweet Polícia. A partir dessas informações é possível fazer comparações do que um escreve sobre o outro com mais facilidade, pois se pode ver lado a lado, o que um fala, seguido das possíveis reações do outro (exemplos de resultados no Apêndice E). Entretanto, para alguns tweets não existe resposta de ambos os lados, ou existem postagens fora de contexto. 5. Conclusões e Trabalhos Futuros Este artigo apresentou um exemplo de como instalar, configurar e utilizar o Apache Hadoop. Foi desenvolvida uma pequena ferramenta que busca, de tempo em tempo, por novos tweets na rede social Twitter para acumular tweets para serem processados usando o Apache Hadoop com o Apache Pig. Durante o decorrer desse artigo percebe-se a grandiosidade do universo de possibilidades de uso do Big Data, desde análise de logs em servidores, sensores diversos, históricos de compras até conversas em redes sociais. Todos esses elementos podem ser analisados para descobrir novas tendências, gerar relatórios para tomadas de decisões, previsão do tempo, definição de perfis de consumidores entre diversas outras aplicações que antes não eram possíveis devido ao grande volume de dados. Tudo isso faz do Apache Hadoop uma ótima alternativa na plataforma Java, com diversas áreas de aplicações. Como direção para possíveis trabalhos futuros tem-se: (i) Desenvolver uma aplicação que automatize a coleta e análise dos dados, evitando que o usuário tenha que trabalhar com linhas de comando e scripts; (ii) Desenvolver um filtro para comparar tweets e identificar os tweets relacionados para o Apache Pig usando UDF (User Defined Function); (iii) Estudar a possibilidade de implementar as análises usando o Apache Hive, similar ao SQL. Agradecimentos Agradeço em primeiro a Deus, por ter me dado saúde e força para prosseguir com esse trabalho. À minha mãe, esposa, familiares e amigos pelo apoio e incentivo. E ao meu orientador Professor Dr. Edson A. Oliveira Junior, pela paciência e ajuda mostrando os caminhos a seguir no desenvolvimento deste trabalho. Referências Bibliográficas [1] Petabyte, The Tech Terms Computer Dictionary: <http://www.techterms.com/definition/petabyte>. Acesso em: 06, Fev, 2013. Disponível em: [2] Java Magazine. BIG DATA PLATAFORMA JAVA: Uma introdução ao big data e opções para encará-lo. DevMedia Group, Edição. 103, p. 16, 2009. [3] Big Data Just Beginning to Explode - Interactive Infographic | CSC: Disponível em: <http://www.csc.com/big_data/flxwd/83638big_data_just_beginning_to_explode_interactive_infographic> . Acesso em: 08, Fev, 2013 [4] CSC World Fall 2012. BIG DATA AND BUSINESS INTELLIGENCE: A Match Made in Hadoop. Disponível em: <http://assets1.csc.com/cscworld/downloads/CSC_World_Fall_2012.pdf> . Acesso em: 08, Fev, 2013. 18 [5] Welcome to Apache™ Hadoop®!: Disponível <http://hadoop.apache.org/#What+Is+Apache+Hadoop%3F>. Acesso em: 26, Out, 2013. em: [6] Sobre - Twitter, Inc.: Disponível em: <https://twitter.com/about>. Acesso em: 26, Out, 2013. [7] Oracle VM VirtualBox: Disponível em: <https://www.virtualbox.org/>. Acesso em: 26, Out, 2013 [8] GNU General Public License v2.0 - GNU Project - Free Software Foundation: Disponível em: <http://www.gnu.org/licenses/old-licenses/gpl-2.0. html>. Acesso em: 30, Set, 2013. [9] The world´s most popular free OS | Ubuntu. Disponível em: <http://www.ubuntu.com/>. Acesso em: 26, Out, 2013. [10] Hadoop – YDN: Disponível em: <http://developer.yahoo.com/hadoop/>. Acesso em: 27, Set, 2013. [11] Welcome to Apache Pig. Disponível em: <http://pig.apache.org/> Acesso em: 26, Out, 2013 [12] Running Hadoop On Ubuntu Linux (Single -Node Cluster) - Michael G. Noll: Disponível em: <http://www.michael-noll.com/tutorials/running-hadoop-on-ubuntu-linux-single-node-cluster/>. Acesso em: 20, Mai, 2013 [13] Running Hadoop On Ubuntu Linux (Multi-Node Cluster) - Michael G. Noll: Disponível em: <http://www.michael-noll.com/tutorials/running-hadoop-on-ubuntu-linux-single-node-cluster/>. Acesso em: 22, Mai, 2013 [14] nss-mdns – Freecode. Disponível em: <http://freecode.com/projects/nss-mdns>. Acesso em: 26, Out, 2013 [15] Install Oracle Java 7 in Ubuntu via PPA Repository ~ Web Upd8: Ubuntu / Linux blog: Disponível em: <http://www.webupd8.org/2012/01/install-oracle-java-jdk-7-in-ubuntu-via.html>. Acesso em: 20, Mai, 2013 [16] White, Tom. Hadoop: The Definitive Guide. 3a. Edição, Editora O'Reilly, p. 295-336, 2012 [17] White, Tom. Hadoop: The Definitive Guide. 3a. Edição, Editora O'Reilly, p. 45-81, 2012 [18] White, Tom. Hadoop: The Definitive Guide. 3a. Edição, Editora O'Reilly, p. 365-409, 2012 [19] Fix Missing eth0 When Cloning Ubuntu VMware Virtual Machines. Disponível em: <http://chris.dziemborowicz.com/blog/2010/07/25/fix -missing-eth0-when-cloning-ubuntu-vmwarevirtual-machines/>. Acesso em: 26, Out, 2013 [20] Getting Started - Apache Pig. Disponível em: <http://pig.apache.org/docs/r0.12.0/start.html>. Acesso em: 17, Out, 2013 [21] Twitter4J - A Java library for the Twitter API: Disponível em: < http://twitter4j.org>. Acesso em: 27, Mai, 2013 [22] REST API Rate Limiting in v1.1 | Twitter Developers: <https://dev.twitter.com/docs/rate-limiting/1.1>. Acesso em: 04, Jun, 2013 Disponível em: 19 Apêndices APÊNDICE A – Resultado da execução do comando de inicialização de serviços do Hadoop, start-all.sh, seguido do comando jps para acompanhar os serviços carregados Resultado do comando star-all.sh seguido do comando jps na máquina ‘mestre’. Resultado do jps na máquina ‘escravo1’. 20 APÊNDICE B – Telas das interfaces web dos serviços de monitoramento do Hadoop Interface web do NameNode 21 Interface web do JobTracker Interface web do TaskTracker 22 APÊNDICE C – Resultados dos comandos de cópia de arquivo da máquina hospedeira para máquina virtual mestre e da máquina mestre para o sistema HDFS Cópia da máquina hospedeira para a máquina virtual mestre Cópia da máquina virtual mestre para o sistema de arquivos HDFS 23 APÊNDICE D – Resgatando o resultado de dentro do sistema Hadoop HDFS Resgate do resultado do sistema HDFS usando o comando copyToLocal Resgate do resultado do sistema HDFS usando a interface web do Hadoop NameNode por download 24 APÊNDICE E – Tabela com resultado parcial obtido no processamento dos tweets dos perfis de usuários anônimos e polícia Perfil dos Anônimos Perfil da Polícia data usuário tw eet data usuário tw eet ... ... ... ... ... ... 6/9/13 19:59 AnonBRNews Policia Federal em apoio a manifestação no dia 7 de setembro! #OperacaoSeteDeSetembro #VemPraRua ... http://fb.me/6zbT8uKez AnonBRNews Policia Federal em apoio a manifestação no dia 7 de setembro! #OperacaoSeteDeSetembro #VemPraRua ... http://fb.me/6zbT8uKez AnonBRNews Policia Federal em apoio a manifestação no dia 7 de setembro! #OperacaoSeteDeSetembro #VemPraRua ... http://fb.me/6zbT8uKez AnonBRNews Antes que eles comecem com porrada, vamos começar a nossa. http://w w w .pmdf.df.gov.br/Dow n 7/9/13 18:28 PMESP Manifestações na capital SP: equipes do policiamento territorial e de choque permanecem mobilizadas para conter manifestantes exaltados; 7/9/13 18:33 pmdfcom Jornalistas recebem treinamento para agir com segurança em cobertura de manifestações. http://goo.gl/r4AAZl 7/9/13 19:43 PMERJ Na localidade de Laranjeiras, 50 pessoas foram detidas até o momento. No total em manifestações no dia de hoje foram 77 detidos. 7/9/13 18:08 PMESP Manifestações na capital SP(região Pça da Sé):policiamento territorial e de choque permanece na região p/conter manifestantes exaltados; 7/9/13 12:01 AnonBRNews Antes que eles comecem com porrada, vamos começar a nossa. http://w w w .pmdf.df.gov.br/Dow n 7/9/13 16:54 PMESP Manifestações na capital SP:manifestantes próximos à Av. 23 de maio, no acesso sentido praça da Sé e praça João Mendes; 7/9/13 12:01 AnonBRNews Antes que eles comecem com porrada, vamos começar a nossa. http://w w w .pmdf.df.gov.br/Dow n 7/9/13 17:28 PMESP Manifestações na capital SP(próx.à Pça da Sé):manifestantes depredam telefônico público; 7/9/13 12:01 AnonBRNews Antes que eles comecem com porrada, vamos começar a nossa. http://w w w .pmdf.df.gov.br/Dow n 7/9/13 17:34 PMESP Manifestações na capital SP:manifestantes muito exaltados insistem em depredar fachada de agência; 7/9/13 12:01 AnonBRNews Antes que eles comecem com porrada, vamos começar a nossa. http://w w w .pmdf.df.gov.br/Dow n 7/9/13 17:33 PMESP Manifestações na capital SP (Pça da Sé):manifestantes depredam fachada de agência bancária; 7/9/13 12:01 AnonBRNews Antes que eles comecem com porrada, vamos começar a nossa. http://w w w .pmdf.df.gov.br/Dow n 7/9/13 17:07 PMESP Manifestações na capital SP:manifestantes em frente da Câmara Municipal de São Paulo; 7/9/13 12:01 AnonBRNews Antes que eles comecem com porrada, vamos começar a nossa. http://w w w .pmdf.df.gov.br/Dow n 7/9/13 16:59 PMESP Manifestações na capital SP:aproximadamente 2.000 manifestantes estão pelo Viaduto Maria Paula, sentido avenida Brigadeiro Luis Antonio; 7/9/13 12:01 AnonBRNews Antes que eles comecem com porrada, vamos começar a nossa. http://w w w .pmdf.df.gov.br/Dow n 7/9/13 15:21 PMERJ Material apreendido com manifestantes detidos até o momento pic.tw itter.com/Tw nQu6LNt8 7/9/13 14:28 AnonBr4sil2 Ato Público PELA INDEPENDÊNCIA DO POLICIAL FEDERAL Sindicato dos Policiais Federais do Estado do Acre – SINPOFAC... http://fb.me/2Q5vkgbG9 7/9/13 16:19 ... ... ... ... 6/9/13 19:59 6/9/13 19:59 7/9/13 12:01 pmdfcom #7deSetembro Ao contrário do que está sendo noticiado, informamos que não houve nenhum ataque de nossos cães a fotógrafos ou manifestantes. ... ... 25