Skip to content
Spark + Hadoop
Jupyter Notebook Shell Python Dockerfile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
binder Update start Nov 8, 2019
resources
NASA_access_log_Aug95.gz
NASA_access_log_Jul95.gz
README.md
index.ipynb
index_respostas.ipynb
nasa_requests.py

README.md

nasa-log-analysis

Introdução

Este projeto tem como objetivo analisar os logs de requisições HTTP feitas para o servidor da NASA Kennedy Space Center. Além disso, possui as respostas de algumas questões teóricas sobre Apache Spark.

Dados

Download do dataset:

  • Julho: ftp://ita.ee.lbl.gov/traces/NASA_access_log_Jul95.gz

  • Agosto: ftp://ita.ee.lbl.gov/traces/NASA_access_log_Aug95.gz

Descrição do dataset: Os logs estão em arquivos ASCII com uma linha por requisição com as seguintes colunas:

  • Host fazendo a requisição. Um hostname quando possível, caso contrário o endereço de internet se o nome não puder ser identificado;

  • Timestamp no formato "DIA/MÊS/ANO:HH:MM:SS TIMEZONE";

  • Requisição (entre aspas);

  • Código do retorno HTTP;

  • Total de bytes retornados.

Executando o projeto

Em uma instância BinderHub

O BinderHub permite criar um ambiente computacional personalizado que pode ser acessado por diferentes usuários utilizando uma URL.

Instruções de execução: Clique em um dos banners abaixo (sugestão: clicar com o botão direito e abrir em nova aba) para executar o projeto em uma instância Binder com Spark, Hadoop e Python instalados. O projeto é executado no navegador, sem a necessidade de instalar as ferramentas na sua máquina =).

Binder

Binder

Com o ambiente em execução, abrir o notebook index.ipynb e ir clicando no "Play" para executar o comando em cada célula. A cada click no "Play" uma célula é executada e seu resultado é exibido logo abaixo.

Executando o projeto

Para visualizar o script que contém o código em Spark+Python, basta clicar duas vezes em nasa_requests.py. Além disso, o arquivo index_respostas.ipynb contém o notebook com todas as células já executadas.

Local

Pré-requisitos: Apache Spark 2.4.4. Download e instruções de instalação são encontradas em https://spark.apache.org/downloads.html.

Instruções de execução: Baixar o script nasa_requests.py para sua máquina; baixar os dois arquivos do dataset e colocar em uma pasta input no mesmo diretório do script nasa_requests.py. Executar o script:

spark-submit nasa_requests.py

Informações extraídas do dataset

1. Número de hosts únicos.

O número de hosts únicos: 137978

2. O total de erros 404.

O total de erros 404: 20901

3. As 5 URLs que mais causaram erro 404.

As 5 URL's que mais causaram erro 404:
URL: /pub/winvn/readme.txt                          Quantidade: 2004
URL: /pub/winvn/release.txt                         Quantidade: 1732
URL: /shuttle/missions/STS-69/mission-STS-69.html   Quantidade: 682
URL: /shuttle/missions/sts-68/ksc-upclose.gif       Quantidade: 426
URL: /history/apollo/a-001/a-001-patch-small.gif    Quantidade: 384

4. Quantidade de erros 404 por dia.

A quantidade de erros 404 por dia: 
Dia: 01/Aug/1995 Quantidade: 243
Dia: 03/Aug/1995 Quantidade: 304
Dia: 04/Aug/1995 Quantidade: 346
Dia: 05/Aug/1995 Quantidade: 236
Dia: 06/Aug/1995 Quantidade: 373
Dia: 07/Aug/1995 Quantidade: 537
Dia: 08/Aug/1995 Quantidade: 391
Dia: 09/Aug/1995 Quantidade: 279
Dia: 10/Aug/1995 Quantidade: 315
Dia: 11/Aug/1995 Quantidade: 263
Dia: 12/Aug/1995 Quantidade: 196
Dia: 13/Aug/1995 Quantidade: 216
Dia: 14/Aug/1995 Quantidade: 287
Dia: 15/Aug/1995 Quantidade: 327
Dia: 16/Aug/1995 Quantidade: 259
Dia: 17/Aug/1995 Quantidade: 271
Dia: 18/Aug/1995 Quantidade: 256
Dia: 19/Aug/1995 Quantidade: 209
Dia: 20/Aug/1995 Quantidade: 312
Dia: 21/Aug/1995 Quantidade: 305
Dia: 22/Aug/1995 Quantidade: 288
Dia: 23/Aug/1995 Quantidade: 345
Dia: 24/Aug/1995 Quantidade: 420
Dia: 25/Aug/1995 Quantidade: 415
Dia: 26/Aug/1995 Quantidade: 366
Dia: 27/Aug/1995 Quantidade: 370
Dia: 28/Aug/1995 Quantidade: 410
Dia: 29/Aug/1995 Quantidade: 420
Dia: 30/Aug/1995 Quantidade: 571
Dia: 31/Aug/1995 Quantidade: 526
Dia: 01/Jul/1995 Quantidade: 316
Dia: 02/Jul/1995 Quantidade: 291
Dia: 03/Jul/1995 Quantidade: 474
Dia: 04/Jul/1995 Quantidade: 359
Dia: 05/Jul/1995 Quantidade: 497
Dia: 06/Jul/1995 Quantidade: 640
Dia: 07/Jul/1995 Quantidade: 570
Dia: 08/Jul/1995 Quantidade: 302
Dia: 09/Jul/1995 Quantidade: 348
Dia: 10/Jul/1995 Quantidade: 398
Dia: 11/Jul/1995 Quantidade: 471
Dia: 12/Jul/1995 Quantidade: 471
Dia: 13/Jul/1995 Quantidade: 532
Dia: 14/Jul/1995 Quantidade: 413
Dia: 15/Jul/1995 Quantidade: 254
Dia: 16/Jul/1995 Quantidade: 257
Dia: 17/Jul/1995 Quantidade: 406
Dia: 18/Jul/1995 Quantidade: 465
Dia: 19/Jul/1995 Quantidade: 639
Dia: 20/Jul/1995 Quantidade: 428
Dia: 21/Jul/1995 Quantidade: 334
Dia: 22/Jul/1995 Quantidade: 192
Dia: 23/Jul/1995 Quantidade: 233
Dia: 24/Jul/1995 Quantidade: 328
Dia: 25/Jul/1995 Quantidade: 461
Dia: 26/Jul/1995 Quantidade: 336
Dia: 27/Jul/1995 Quantidade: 336
Dia: 28/Jul/1995 Quantidade: 94

5. O total de bytes retornados.

A quantidade de bytes utilizados: 65524314915

Problemas encontrados no dataset:

  1. Entrada fora do padrão esperado;
  2. URLs das requisições com " e/ou espaços;
  3. String - no lugar de inteiro para representar os bytes utilizados

Questões Teóricas:

1. Qual o objetivo do comando cache em Spark?

O comando cache armazena o RDD (Resilient Distributed Dataset) em memória. Utilizamos a função cache quando queremos reutilizar o RDD. O RDD é reprocessado cada vez que executamos uma ação, utilizando a função cache este RDD ficará disponível na memória aumentando o desempenho de acesso em seu reuso.

2. O mesmo código implementado em Spark é normalmente mais rápido que a implementação equivalente em MapReduce. Por quê?

O Spark utiliza o conceito de DAG (Directed Acyclic Graph - Grafos Acíclicos Direcionados) que permite mapear os passos que serão necessários para atingir o resultado esperado e, então, otimiza esses passos da melhor maneira possível; O Spark faz suas operações em memória; O Spark trabalha com RDD que armazena os elementos, é tolerante a falhas e pode ser executado em paralelo. Além disso, o Spark não computa os seus resultados de imediato, uma transformação é executada apenas quando uma ação é solicitada, isto também contribui para o seu desempenho. Por estes motivos, o Spark consegue executar um trabalho de maneira mais eficiente que o MapReduce.

3. Qual é a função do SparkContext?

O SparkContext permite a conexão com um cluster Spark e então podemos utilizar os recursos do Spark naquele cluster, por exemplo criar RDDs.

4. Explique com suas palavras o que é Resilient Distributed Datasets (RDD).

O RDD é a principal estrutura de dados do Spark, é um conjunto de registros imutáveis que podem ser executados em paralelo. É possível realizar transformações e ações no RDD. Apenas as transformações geram um novo RDD e essas transformações só são aplicadas quando uma ação é necessária. Cada vez que é necessário utilizar um RDD ele é reprocessado, mas existem funções para persistir um RDD em memória ou disco melhorando o desempenho.

5. GroupByKey é menos eficiente que reduceByKey em grandes dataset. Por quê?

O GroupByKey é menos eficiente que o reduceByKey porque ele transfere mais dados pela rede para computar o resultado final. O GroupByKey percorre todas as partições em busca de todos os valores para todas as chaves e então transfere todos esses dados via rede para obter o resultado final (processo conhecido como shuffle). Por outro lado, o reduceByKey primeiro agrega todas os valores das chaves, transferindo via rede uma menor quantidade de dados, ou seja, apenas um valor para cada chave.

6. Explique o que o código Scala abaixo faz.

val​​ ​ textFile​​ ​ = ​ ​ sc​ . ​ textFile​ ( ​ "hdfs://..."​ )
val​​ ​ counts​​ ​ = ​ ​ textFile​ . ​ flatMap​ ( ​ line​​ ​ =>​​ ​ line​ . ​ split​ ( ​ " ​ ​ " ​ ))
​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ . ​ map​ ( ​ word​​ ​ =>​​ ​ ( ​ word​ , ​ ​ 1 ​ ))
​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ . ​ reduceByKey​ ( ​ _ ​ ​ + ​ ​ _ ​ )
counts​ . ​ saveAsTextFile​ ( ​ "hdfs://..."​ )

O código realiza a contagem de palavras de um arquivo lido do HDFS e salva seu resultado em um arquivo texto também no HDFS. É criado um RDD a partir do arquivo lido do HDFS, em seguida ocorrem várias transformações: o RDD inicial é transformado utilizando a função flatMap, assim obtemos as palavras separando cada entrada por espaço. Em seguida, transformamos o RDD utilizando a função map para exportar pares chave-valor com a palavras sendo a chave e o valor o numeral 1. Por fim, a transformação reduceBykey irá somar os valores para cada chave. A ação saveAsTextFile faz com que as transformações sejam de fato processadas e salva o resultado em um arquivo no HDFS.

You can’t perform that action at this time.