quarta-feira, 4 de julho de 2018

Hadoop standalone no Ubuntu 16

Este exemplo mostra como rodar o Hadoop 2.7.6 no Ubuntu 16.04 LTS.
Eu considero que você acabou de instalar o Ubuntu Server com a instalação mínima e SSH server instalado. O SSH server só precisa ser instalado para você fazer o acesso remoto na máquina, caso você não precise disto, nem mesmo o SSH server precisa ser instalado.

Os passos mostrados abaixo consideram que você está utilizando um usuário que faz parte do sudoers, isto é, aquele que é criado durante a instalação. No meu caso este usuário se chama hadoopuser.

Os comandos estão mostrados em azul e as saídas das telas em vermelho.

O primeiro passo é atualizar o sistema.

$ sudo apt-get -y update
$ sudo apt-get -y upgrade

Instalação

Depois precisamos instalar o java JDK. Neste post vamos usar o openjdk mesmo, mas você pode utilizar o JDK da Oracle. Eu faço isto em outro post sobre o Hadoop. Se você estiver curioso, veja o link.
O primeiro comando faz a instalação e o segundo mostra a versão depois de instalado.

$ sudo apt-get install -y default-jdk
$ java -version

No meu caso a saída mostrada é do java versão 1.8.0 build 171.

hadoopuser@hadoop1:~$ java -version
openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)

Em seguida temos que baixar o hadoop da internet.
Vou usar o comando wget para baixar. Na data desta postagem a última versão disponível na data é 3.1.0, contudo vou utilizar a versão 2.7.6, que tem mais ou menos ~207MB, para manter a compatibilidade com o outro post.


$ wget https://dist.apache.org/repos/dist/release/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz

$ wget https://dist.apache.org/repos/dist/release/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz.mds

$ shasum -a 256 hadoop-2.7.6.tar.gz

$ cat hadoop-2.7.6.tar.gz.mds

Os dois primeiros programas baixam respectivamente o hadoop compactado e o checksum do arquivo do compactado. Em seguinda shasum é usado para gerar o checksum do arquivo que foi baixado e cat é usado para ver o conteúdo do arquivo de checksum. A linha fornecida por shasum deve igual à linha indicada como SHA256 fornecida por cat.
Veja na minha saída que elas são iguais (em rosa).

hadoopuser@hadoop1:~$ shasum -a 256 hadoop-2.7.6.tar.gz
f2327ea93f4bc5a5d7150dee8e0ede196d3a77ff8526a7dd05a48a09aae25669  hadoop-2.7.6.tar.gz
hadoopuser@hadoop1:~$ cat hadoop-2.7.6.tar.gz.mds
hadoop-2.7.6.tar.gz:    MD5 = 6B DF 41 74 20 2C 82 77  4F 31 47 2E 04 3D 61 07
hadoop-2.7.6.tar.gz:   SHA1 = E6BF 4C57 14D4 27F4 776F  B14A 3383 ED00 5F7D 6CA7
hadoop-2.7.6.tar.gz: RMD160 = 669B F782 7DB3 1527 708D  BDDF BDA4 923F 6F1D AC73
hadoop-2.7.6.tar.gz: SHA224 = 8873B3B2 1DF3C8E3 11311872 FD0E098C 7307DDB7
                              D7E333E0 048470F1
hadoop-2.7.6.tar.gz: SHA256 = F2327EA9 3F4BC5A5 D7150DEE 8E0EDE19 6D3A77FF
                              8526A7DD 05A48A09 AAE25669
hadoop-2.7.6.tar.gz: SHA384 = E2A4472F 97A91D91 EE3407FC ACA02B89 225670CF
                              BCBAACDE 520D1640 9A912127 FDE4F029 130E95CC
                              87EEABC8 B6CC9B98
hadoop-2.7.6.tar.gz: SHA512 = 725A86B5 1674573A 2BA69528 6CE40CB6 EA631BFF
                              E6445E01 0A11EECB B93B6647 CB424CFE 95CEA99C
                              2CD52FCA EF438E26 45DA3855 D808D113 59E0E349
                              4E90B331

Ok, como sabemos que o arquivo não foi alterado, podemos descompactá-lo com tar.
E vamos mové-lo para o diretório de programas.
Para isto damos os dois comandos a seguir:

$ tar -xzvf hadoop-2.7.6.tar.gz
$ sudo mv hadoop-2.7.6 /usr/local/hadoop

Configurar o ambiente

Agora precisamos configurar o ambiente do hadoop, o que é relativamente fácil no modo standalone.
Vamos para isto usar o comando a seguir para configurar a variável de ambiente JAVA_HOME.

$ readlink -f /usr/bin/java | sed "s:bin/java::"


A saída deste comando no meu computador é
hadoopuser@hadoop1:~$ readlink -f /usr/bin/java | sed "s:bin/java::"
/usr/lib/jvm/java-8-openjdk-amd64/jre/

Precisamos então configurar o arquivo de configuração de ambiente  do hadoop.
Vou utilizar o vi para isto, mas você pode utilizar seu editor preferido.
Lembre que tem que ser sudo.

$ sudo vi /usr/local/hadoop/etc/hadoop/hadoop-env.sh

Ache a linha onde tem JAVA_HOME. Eu comentei a linha original e criei uma nova da seguinte maneira:

#export JAVA_HOME=${JAVA_HOME}
export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")


Rodar um exemplo

Agora podemos utilizar o Hadoop. Vamos rodá-lo com o comando:
$ /usr/local/hadoop/bin/hadoop

No meu computador a saída deste comando é
hadoopuser@hadoop1:~$ /usr/local/hadoop/bin/hadoop
Usage: hadoop [--config confdir] [COMMAND | CLASSNAME]
  CLASSNAME            run the class named CLASSNAME
 or
  where COMMAND is one of:
  fs                   run a generic filesystem user client
  version              print the version
  jar <jar>            run a jar file
                       note: please use "yarn jar" to launch
                             YARN applications, not this command.
  checknative [-a|-h]  check native hadoop and compression libraries availability
  distcp <srcurl> <desturl> copy file or directories recursively
  archive -archiveName NAME -p <parent path> <src>* <dest> create a hadoop archive
  classpath            prints the class path needed to get the
  credential           interact with credential providers
                       Hadoop jar and the required libraries
  daemonlog            get/set the log level for each daemon
  trace                view and modify Hadoop tracing settings

Se você não quiser ficar digitando o caminho sempre, você pode alterar o PATH do linux.
Você vai precisar editar o arquivo .bashrc.

$ vi ~/.bashrc

Para acrescentar a linha abaixo no final do arquivo:
export PATH=$PATH:/usr/local/hadoop/bin

Você precisará fazer logoff e em seguida logon novamente para carregar a alteração no seu usuário.

Vamos rodar um teste com o hadoop.
Para isto vamos criar um diretório de entrada para conter os arquivo .xml de configuração do exemplos que já vem no programa. Vamos utilizar hadoop-mapreduce-examples para rodar um map-reduce.

$ mkdir ~/input
$ cp /usr/local/hadoop/etc/hadoop/*.xml ~/input
$ /usr/local/hadoop/bin/hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.6.jar grep ~/input ~/output 'principal[.]*'

Este exemplo irá rodar, procurando a palavra principal.
Se tudo correr corretamente, uma saída parecida com a mostrada abaixo vai aparecer na sua tela.

18/07/04 18:11:50 INFO mapreduce.Job: Counters: 30
    File System Counters
        FILE: Number of bytes read=1248344
        FILE: Number of bytes written=2398340
        FILE: Number of read operations=0
        FILE: Number of large read operations=0
        FILE: Number of write operations=0
    Map-Reduce Framework
        Map input records=2
        Map output records=2
        Map output bytes=37
        Map output materialized bytes=47
        Input split bytes=120
        Combine input records=0
        Combine output records=0
        Reduce input groups=2
        Reduce shuffle bytes=47
        Reduce input records=2
        Reduce output records=2
        Spilled Records=4
        Shuffled Maps =1
        Failed Shuffles=0
        Merged Map outputs=1
        GC time elapsed (ms)=48
        Total committed heap usage (bytes)=274874368
    Shuffle Errors
        BAD_ID=0
        CONNECTION=0
        IO_ERROR=0
        WRONG_LENGTH=0
        WRONG_MAP=0
        WRONG_REDUCE=0
    File Input Format Counters 
        Bytes Read=151
    File Output Format Counters 
        Bytes Written=37

Note que se você tentar rodar novamente no mesmo diretório de saída (~/output no exemplo acima) vai dar erro de execução, similar ao mostrado abaixo:

18/07/04 18:13:50 INFO jvm.JvmMetrics: Cannot initialize JVM Metrics with processName=JobTracker, sessionId= - already initialized
org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory file:/home/hadoopuser/output already exists
    at org.apache.hadoop.mapreduce.lib.output.FileOutputFormat.checkOutputSpecs(FileOutputFormat.java:146)
    at org.apache.hadoop.mapreduce.JobSubmitter.checkSpecs(JobSubmitter.java:266)
    at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:139)
    at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1290)
    at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1287)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:422)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1758)
    at org.apache.hadoop.mapreduce.Job.submit(Job.java:1287)
    at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1308)
    at org.apache.hadoop.examples.Grep.run(Grep.java:94)
    at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
    at org.apache.hadoop.examples.Grep.main(Grep.java:103)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.hadoop.util.ProgramDriver$ProgramDescription.invoke(ProgramDriver.java:71)
    at org.apache.hadoop.util.ProgramDriver.run(ProgramDriver.java:144)
    at org.apache.hadoop.examples.ExampleDriver.main(ExampleDriver.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
    at org.apache.hadoop.util.RunJar.main(RunJar.java:136)


O resultado está no diretório de saída

hadoopuser@hadoop1:~$ ls output/
part-r-00000  _SUCCESS

Veja que gerou um arquivo _SUCESS para indicar que tudo deu certo. No arquivo part-r-0000 está o resultado. É um arquivo texto simples, que pode ser visualizado com cat.

hadoopuser@hadoop1:~$ cat part-r-00000 
6   principal
1   principal.

As duas linhas listadas indicam que o map-reduce achou 6x a palavra principal e 1x a palavra seguida de um ponto.

quinta-feira, 21 de junho de 2018

Multiplexador de terminais

Neste post vamos falar do TMUX que é um multiplexador de terminais.
Afinal o que é um multiplexador de terminais?
É um programa que roda no linux e que permite a criação de vários terminais dentro de uma sessão de acesso de usuário, por exemplo via tty, ssh ou telnet.
Estes terminais são acessados e controlados a partir de uma única tela.
Ele não é a mesma coisa, mas tem um comportamento ligeiramente semelhante ao Terminator.
Contudo com o tmux pode ser separado de uma tela e continuar a execução em segundo plano que pode em seguida ser reconectada.

Como instalar. 

O Tmux pode ser instalado de diversas maneiras. Por exemplo no ubuntu basta usar os comandos

sudo apt-get update
sudo apt-get install tmux

Contudo nem sempre este procedimento fornece a última versão.
Para isto temos que fazer um processo mais complicado que mostro a seguir.

1-) Precisamos instalar várias dependências e começamos atualizando as informações de pacotes. Os comandos a seguir vão fazer esta atualização, baixar o git (um programa necessário para baixar os fontes do tmux) e instalar as ferramentas de compilação ( compilação ?? não se assunte, seguindo estes passos é fácil).

$ sudo apt update
$ sudo apt install -y git
$ sudo apt install -y automake
$ sudo apt install -y build-essential
$ sudo apt install -y pkg-config
$ sudo apt install -y libevent-dev
$ sudo apt install -y libncurses5-dev

Note que você pode dar todos os comandos apt install em uma única linha.

2-) Precisamos escolher o diretório de destino para o qual faremos o download do tmux. Vamos fazer o download em /tmp/tmux. A primeira linha é só para garantir que o diretório está vazio.

$ rm -fr /tmp/tmux
$ git clone https://github.com/tmux/tmux.git /tmp/tmux

3-) Git deve ter baixado os fontes e agora vamos compilá-la.

$ cd /tmp/tmux
$ sh autogen.sh
$ ./configure
$ make
$ sudo make install
$ cd ~
$ rm -fr /tmp/tmux

Remover o tmux

Se você removeu o diretório de compilação (/tmp/tmux) será preciso remover manualmente o tmux.
Use whereis para saber onde os arquivos estão e apague-os.
Abaixo um exemplo com o saída no meu computador. Note que whereis retorna dois caminhos (um executável e um arquivo gz). Apague os dois e pronto.

$ whereis tmux
tmux:  /usr/local/bin/tmux /usr/share/man/man1/tmux.1.gz
$ sudo rm /usr/local/bin/tmux /usr/share/man/man1/tmux.1.gz


sexta-feira, 1 de junho de 2018

Instalar Redis no Ubuntu 18

Redis é um serviço de armazenamento de dados na memória que utiliza o paradigma valor-chave.
Ele é conhecido por sua flexibilidade, desempenho e amplo suporte a idiomas.
Mostraremos neste post como instalar e configurar o Redis em um servidor Ubuntu 18.
Consideramos que você já tenha feito download e instalado o Ubuntu-server e que tenha acesso de root ao servidor (ou vm).

Instalação

Para obter a versão mais recente do Redis, compilamos e instalamos do código-fonte. Assim, precisamos satisfazer as dependências de compilação instalando o meta-pacote build-essential e tcl dos repositórios do Ubuntu, usando os comandos:

$ sudo apt-get update
$ sudo apt-get install tcl build-essencial

Em seguida, podemos começar a instalar o Redis, começando pelo download.
Extraímos o código-fonte no nosso servidor, por exemplo no diretório /tmp.
Vamos baixar a versão estável do Redis.

$ cd /tmp
$ curl -O http://download.redis.io/redis-stable.tar.gz
$ tar xzvf redis-stable.tar.gz
$ cd redis-stable

Para compilar os passos são simples:

$ make
$ make test
$ sudo make install

Configuração

Com o Redis instalado, precisamos agora fazer uma configuração básica para ele rodar.
Para começar, precisamos criar um diretório de configuração cujo padrão é /etc/redis, que pode ser criado digitando:

$ sudo mkdir /etc/redis
$ sudo cp /tmp/redis-stable/redis.conf /etc/redis
$ sudo vi /etc/redis/redis.conf

1º) No arquivo, localize a diretiva supervised que por default é definido como não. Como estamos executando um sistema operacional que usa o init systemd, podemos mudar isso para systemd.

2º) O próximo passo é alterar o parâmetro dir que especifica o diretório que o Redis usará para despejar dados persistentes. Precisamos escolher um local onde o Redis tenha permissão de gravação e que não seja visualizável por usuários normais. Nós vamos usar o /var/lib/redis que criaremos manualmente.

3) Criar usuários, grupos e diretórios:

$ sudo adduser --system --group --no-create-home redis
$ sudo mkdir /var/lib/redis
$ sudo chown redis:redis /var/lib/redis
$ sudo chmod 770 /var/lib/redis

4) Criar o arquivo de inicialização /etc/systemd/system/redis.service:
[Unit]
Description=Redis In-Memory Data Store
After=network.target

[Service]
User=redis
Group=redis
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
ExecStop=/usr/local/bin/redis-cli shutdown
Restart=always

[Install]
WantedBy=multi-user.target

Testando

Vamos iniciar o serviço com o comando mostrado na primeira linha abaixo e verifique se o serviço não teve erros executando a segunda linha:
$ sudo systemctl start redis
$ sudo systemctl status redis
Você verá um resultado semelhante ao abaixo. Note na última linha que está dizendo "Ready to accept connections", ou seja, pronta para receber conexões.


Para habilitar que o Redis inicie com o Boot

Se todos os seus testes funcionarem e você desejar iniciar o Redis automaticamente quando o servidor inicializar, digite:
$ sudo systemctl enable redis




sexta-feira, 11 de maio de 2018

Como colocar o PyCharm no launcher do Ubuntu

Atualizei recentemente meu pycharm para a versão 2018.1.
A atualização basicamente consiste em baixar do site da Jetbrains dedicado ao PyCharm, e depois do download basta descompactar e mover o diretório criado para você você achar mais adequado.
No meu caso está em ~/bin/pycharm.
Para rodar o pycharm é só executar o script pycharm.sh que está no diretório bin dentro do diretório do pycharm, isto é, no meu caso ~/bin/pycharm/bin/pycharm.sh.

Eu queria ter o ícone do pycharm no launcher (aquela barra lateral do Ubuntu) para ficar mais fácil chamá-lo. O PyCharm pode criar seu próprio ícone de lançador, contudo ele não é cria por padrão.
A gente tem que executar alguns comandos:

1) Comece chamando o PyCharm em um terminal.


2) No menu Ferramentas, selecione "Criar entrada da área de trabalho ..."

3) Se você já tem o PyCharm, ele irá perguntar se você quer reaproveitar as configurações da versão anterior:


4) Marque a caixa correspondente, se você quiser o lançador para todos os usuários. Se você selecionou "Criar entrada para todos os usuários", será solicitada sua senha e seu usuário deve estar entre os sudoers.

5) Você precisa fechar o Pycharm. Você verá na parte de baixo da tela do programa que ele terminou a instalação e criou a entrada de desktop.


6) Você agora irá encontrar o PyCharm no Unity Dash. Clique no ícone para abrir o PyCharm novamente.


7) Ao abrir o Pycharm novamente você pode fixá-lo na barra lateral clicando com o botão direito sobre o ícone.



domingo, 6 de maio de 2018

Como instalar o kernel do Javascript (Node.js) no Jupyter do Windows

Neste vídeo considero que você já tem o Jupyter instalado no seu Windows.
Kernel é o nome que o Jupyter dá para os módulos que acrescentam linguagens no seu ambiente.
Para achar onde está o kernel basta procurar no google "jupyter javascript". Vamos utilizar o kernel que aparece na primeira opção, que é o "n-riesco/javascript":

Se você clicar no link, será enviado para a página no GitHub. Mais ou menos descendo 70% da página, você achará as instruções para instalação no Windows que mostramos abaixo:

No meu caso estou utilizando a versão oficial do Python para Windows, contudo o processo de instalação descrito acima não funcionaram no meu Windows 10. Os comandos são parecidos e eu mostro abaixo:

python -m pip install --upgrade pip
pip install npm
npm install -g ijavascript
ijsinstall
Se você não tiver o jupiter ainda, basta alterar a segunda linha de comando acima para a linha abaixo:

pip install jupyter npm
Agora o módulo está instalado. Podemos abrir o jupyter. Fazemos isto na linha de comando como mostramos abaixo:

O navegador irá abrir a página do notebook do Jupyter e você poderá criar um notebook com Javascript:

terça-feira, 1 de maio de 2018

Rodando vários cron jobs em uma linha

Neste post mostro como executar dois (ou mais) comandos consecutivamente, não simultaneamente, utilizando uma linha do crontab.
Um crontab normalmente executa um comando em cada linha.
Por exemplo:

# m h dom mon dow command
01 00 * * * /usr/sbin/meu_programa1
05 00 * * * /usr/sbin/meu_programa2
00 01 * * * /usr/sbin/meu_programa3
00 02 * * * /usr/sbin/meu_programa4

No exemplo acima mostramos como criar quatro tarefas que são executadas às 00:01, às 00:05, às 01:00 e às 02:00. Contudo imagine que queremos que meu_programa2 seja executado depois de meu_programa1 e meu_programa1 pode durar menos ou um pouco mais de cinco minutos.
Usando a configuração acima, não temos esta garantia. Assim teríamos que alterar a segunda linha para garantir um intervalo maior entre os dois programas.

Em vez disso, posso executar essas tarefas cron uma após a outra, colocando && entre cada tarefa. Assim o nosso exemplo ficaria:

# m h dom mon dow command
01 00 * * * /usr/sbin/meu_programa1 && /usr/sbin/meu_programa2
01 01 * * * /usr/sbin/meu_programa3
01 02 * * * /usr/sbin/meu_programa4

Desta forma as duas primeiras são feitas consecutivamente. Assim que acabar meu_programa1, a segunda tarefa (meu_programa2) é executada.

Isso é útil para situações onde queremos que as tarefas sejam executadas uma depois da outra, ou
(1) porque existe uma dependência entre elas, isto é, a tarefa executada pelo primeiro programa é uma entrada do segundo programa ou
(2) utiliza um recurso de hardware (por exemplo, é muito intensiva em I/O ou gasta muito espaço em disco para executar)  que é importante que a primeira tarefa acabe antes da segunda começar.

Reparando o boot no Ubuntu

Caso você não consiga mais acessar o seu Ubuntu porque um erro para a inicialização (ou o boot para no prompt grub>), você pode reparar a inicialização utilizando uma ferramenta bastante interessante e que torna o processo bem simples: Boot Repair (a página do projeto é https://sourceforge.net/p/boot-repair/home/pt/).

Para instalar o Boot Repair no Ubuntu é necessário instalar um novo repositório. Esta instalação permite ainda que você receba automaticamente as futuras atualizações dele.

Vamos iniciar o computador com um pendrive que tem o Ubuntu live, selecionando a opção de Experimentar o Ubuntu como mostrado abaixo:



Quando o Ubuntu tiver carregado, precisamos chamar um terminal (no Unity use as teclas CTRL + ALT + T) ou podemos pesquisar em aplicativos como abaixo:


Agora vamos adicione o repositório do programa com este comando:



$ sudo add-apt-repository ppa:yannubuntu/boot-repair


Se você estiver utilizando o Ubuntu 18, não é necessário atualizar o APT com o comando, contudo para versões 17 ou inferior, você precisa executar:
$ sudo apt-get -y update
Tendo feito a atualização (caso necessário), use o comando abaixo para instalar o programa:
$ sudo apt-get -y install boot-repair

Pronto agora basta rodar o programa (digitando a linha abaixo no terminal) e selecionar a opção de reparação recomendada:
$ boot-repair

Agora o programa irá rodar e quando terminar irá mostrar o resultado da reparação. Se seu HD estiver ok, acredito que você não terá problemas e receberá uma mensagem como a mostrada abaixo:

É só dar reboot.


Como aumentar o espaço disponível no Ubuntu usando LVM

Ao tentar realizar uma atualização de versão do Ubuntu, um dos problemas mais comuns em servidores ou máquinas virtuais com pouco armazename...