terça-feira, 14 de junho de 2022

O protocolo HTTP

     Quando abrimos um navegador, digitamos uma URL na barra de endereço e damos um ENTER, o navegador (O CLIENTE) faz uma requisição para um recurso hospedado em um servidor. O SERVIDOR então devolve para o cliente o recurso requisitado (páginas html, scripts PHP, ASP, JSP, arquivos css, arquivos js, imagens, e documentos de diversas espécies, .DOC.XLS,PDF, XML, JSON,entre outros). 

Essa resposta é uma espécie de pacote composto por dados e por um código de STATUS. Esse código serve para indicar para o cliente, a situação da resposta dada pelo servidor. Se o recurso requisitado foi enviado com sucesso ou não, seja por não ter encontrado o recurso requisitado, seja por conta de alguma problema que o servidor requisitado tenha enfrentado. Toda essa troca de informação é feita por meio do protocolo HTTP.

 HTTP é um protocolo (protocol) que permite a obtenção de recursos, como documentos HTML. É a base de qualquer troca de dados na Web e um protocolo cliente-servidor, o que significa que as requisições são iniciadas pelo destinatário, geralmente um navegador da Web. Um documento completo é reconstruído a partir dos diferentes sub-documentos obtidos, como por exemplo texto, descrição do layout, imagens, vídeos, scripts e muito mais.

Os códigos de status do HTTP são representados por 5 grupos de numeração. São eles

  • 100 a 199 - status de informação
  • 200 a 299 - status de sucesso (200 OK)
  • 300 a 399 - status de redirecionamento
  • 400 a 499 - status de erro de cliente (404 página não encontrada)
  • 500 a 599 - status de erro de servidor (500 erro no servidor)
Algo muito comum hoje em dia é a requisição a uma API (application programing Interface). Trata-se de um recurso que pode ter diversas funcionalidades que são retornadas em formato XML ou formato JSON. Para requisitar esses recursos, é necessário conhecer o endereço que é a URL(Uniforme Resource Locator) desse recurso. 

Esse endereço é composto pelo tipo de protocolo(http://), mais o IP do servidor (127.0.0.1) e a porta que está sendo utilizada (:5094).

É importante também se conhecer o nome do recurso que é chamado de URN (Uniforme Resource Name).

A junção da URL com a URN é conhecida com URI (Universal Resource Identifier).

Exemplo: http://127.0.0.1:3000/clientes

Sabendo disso, nos resta fazer as requisições de forma padronizada e é aí que entra o conceito de REST (Representational State Transfer).

A requisição é feita por meio de métodos do protocolo HTTP. São eles:

  • GET (quando se quer buscar alguma informação)
  • POST (quando se quer registrar alguma informação no servidor)
  • PUT (quando se quer alterar alguma informação registrada no servidor)
  • DELETE (quando se quer excluir alguma informação registrada no servidor)
Bom, vamos parar de papo furado e colocar a mão na massa. Para isso, vamos fazer uso do  CURL.

O que é o curl

Curl é uma ferramenta para transferir dados de/para um servidor, usando um dos protocolos suportados. Normalmente estamos usando o HTTP.

Ele é uma ferramenta de linha de comando que funciona como interface para a biblioteca que faz o serviço pesado, o libcurl.

De forma geral, seu navegador realiza requisições web, recebe respostas, lê/escreve cookies e renderiza sua página. O curl pode fazer tudo isso, exceto a renderização, que cabe ao seu navegador.

Ele oferece uma infinidade de funções úteis como realização de autenticação, interação com API's, preencher formulários HTML, download de arquivos e paginas HTML etc.

Desde de a versão 10 o CURL já vem instalado no windows.

Abra o prompt do windows e digite curl www.google.com/

A resposta será o código HTML da página inicial do google.

Também é possível obter uma resposta mais verbosa, permitindo visualizar os cabeçalhos da requisição HTTP usando a opção -i. Executando o comando abaixo você poderá vizualizar informações como o Status Code da resposta, a data e hora em que ela foi enviada, o tipo do conteúdo da resposta e várias outras informações que podem variar a depender da implementação do servidor.

curl -i http://www.google.com/

A primeira linha indica a versão do protocolo HTTP usada e o Status Code de sucesso (200).

Caso queira ignorar o conteúdo da página e receber somente o cabeçalho, você pode usar a opção -I (i maiúsculo).

curl -I https://www.google.com/

Fazendo download de arquivos:

Vamos utilizar aqui a mídia de instalação da ultima versão do Ubuntu como exemplo. Para fazer o download de um arquivo, salvando com o mesmo nome do arquivo definido pelo servidor, basta usar a opção -O.

curl-O https://releases.ubuntu.com/20.04.1/ubuntu-20.04.1-desktop-amd64.iso

Interagindo com API's REST com GET e POST

O curl também é útil para realizar testes de API's REST. Tomemos como exemplo a aplicação https://jsonplaceholder.typicode.com/ que foi feita justamente para fins de testes.

Ela possui as seguintes rotas:

GET /posts
GET /posts/:id
GET /posts/:id/comments
GET /comments?postId={:id}
POST /posts
PUT /posts/:id
PATCH /posts/:id
DELETE /posts/:id

Por padrão, o curl usa o método HTTP GET para realizar as requisições. Para fazer uma requisição GET, basta executar

curl https://jsonplaceholder.typicode.com/posts

O retorno será em formato JSON contendo uma lista de posts:

[ { "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum
rerum est autem sunt rem eveniet architecto" }, { "userId": 1, "id": 2, "title": "qui est esse", "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate
porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" }, { "userId": 1, "id": 3, "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis
pariatur\nmolestiae porro eius odio et labore et velit aut" }, [continua ...]

Também é possível especificar qual método usar, passando a opção -X e o método como argumento:

curl -X GET https://jsonplaceholder.typicode.com/posts

Para realizar a criação de um post, você pode executar:

curl -i -X POST https://jsonplaceholder.typicode.com/comments \ -H 'Content-Type: application/json' \ -d $'{ "postId": 101, "name": "Vitor Almeida", "email": "vitor.almeida@alura.com.br", "body": "De acordo ao manual do curl ( disponível online [...]" }'

Resultando em

HTTP/2 201 date: Tue, 05 Jan 2021 01:17:53 GMT content-type: application/json; charset=utf-8 content-length: 168 set-cookie: __cfduid=d4f15935c351e1b9ece6e8d8cdb1ffa1a1609809470; expires=Thu, 04-Feb-21 01:17:50 GMT;
path=/; domain=.typicode.com; HttpOnly; SameSite=Lax x-powered-by: Express [continua ...] { "postId": 101, "name": "Vitor Almeida", "email": "vitor.almeida@alura.com.br", "body": "De acordo ao manual do curl ( disponível online [...]", "id": 501 }

A opção -H permite adicionar um cabeçalho e a -d permite passar os dados da requisição. Nesse caso, definimos que o conteúdo é no formato JSON e passamos o conteúdo da requisição que será usado para criar uma conta. Podemos ver no resultado que o status foi 201, indicando que um novo recurso foi criado.

Uma alternativa ao CURL é um cara chamado POSTMAN, mas uma coisa de cada vez. Um dia faço um POST sobre o assunto.

Até a próxima!



domingo, 12 de junho de 2022

Single Page Applications

Quando iniciei a minha carreira (optei por atuar na área de desenvolvimento) a maioria dos sistemas eram desenvolvidos em plataforma WEB. 

As tecnologias usadas a época para desenvolver esse tipo de sistema eram ASP 3.0, PHP, JSP, ColdFusion, Javascript, entre outras. Todas essas tecnologias se baseavam na arquitetura do tipo cliente/servidor, aonde um usuário, através de um navegador (browser) fazia uma requisição do tipo HTTP a uma página hospedada em um servidor e este por sua vez devolvia essa página entre outros recursos (html,css, javascript, imagens e documentos) para o cliente que fez a requisição. Esse processo se repetia toda vez que o cliente interagia com a página, ou seja, toda vez que o usuário selecionava uma opção em um combobox, clicava em um link ou ainda uma imagem, o browser fazia uma nova requisição ao servidor. 

Era um processo síncrono, pois a resposta a requisição era dada na mesmo momento em que era feita essa requisição.

Em certo momento da carreira, meu chefe pediu que eu desenvolvesse um formulário aonde havia uma combo de seleção com opções que estavam persistidas em um banco de dados. Ao entregar a encomenda, meu chefe estava incomodado com o fato de toda vez que ele escolhia uma opção, a página que continha o formulário era recarregada.

Ele então me disse: Por que você não utiliza Ajax nessa combo? Eu dei uma risada e falei: Como vou solucionar esse problema com um produto de limpeza, meu líder?

AJAX significa Asynchronous JavaScript and XML, ou JavaScript e XML Assíncronos, em bom português. Ele é um conjunto de técnicas de desenvolvimento voltado para a web que permite que aplicações trabalhem de modo assíncrono, processando qualquer requisição ao servidor em segundo plano.

A partir dali, verifiquei que havia uma forma de se fazer requisição do tipo HTTP sem a necessidade de se carregar a página, ou seja, um jeito de tornar o processo assíncrono.

Com o tempo fui notando que tudo parecia utilizar tecnologia similar AJAX (Gmail, Facebook, Google Maps). As requisições HTTP ficavam todas transparentes, causando ao usuário a experiência semelhante ao uso de aplicações ou sistemas do tipo Desktop. 

Surgia ali o conceito de Single Page Application ou SPA.

Single Page Applications (SPA) são aplicações cuja funcionalidade está concentrada em uma única página. Ao invés de recarregar toda a página ou redirecionar o usuário para uma página nova, apenas o conteúdo principal é atualizado de forma assíncrona, mantendo toda a estrutura da página estática.

Além de otimizar a performance da aplicação, reduzindo o conteúdo a ser carregado, as SPAs têm foco na experiência do usuário, que lida com uma interface mais rápida.

Há atualmente no mercado diversos frameworks/bibliotecas que facilitam a criação de aplicações seguindo esse modelo. Entre os principais estão: Angular, React e Vue.js, frameworks JavaScript que trabalham com o conceito de componentes, mas aí é assunto para um outro post.

Valeu!

terça-feira, 31 de maio de 2022

Análise de Dados

 Ao assistir Netflix, nos são apresentados os filmes que estão em "alta" e ainda, nos deparamos com recomendações baseadas nos filmes que costumamos assistir.

O mesmo acontece ao acessarmos o Mercado Livre e o Youtube. Nos são sugeridos videos e produtos similares aos que foram pesquisados em visitas passadas.

Fica parecendo que estes sites são videntes que advinham o que se passa pelas nossas cabeças, ou ainda, que seus desenvolvedores fazem magia negra ou até mesmo tem pacto com o Pai do Fogo, não mesmo?

Uma das maiores redes de varejo dos Estados Unidos descobriu que a venda de fraldas descartáveis estava associada à de cerveja. Em geral, os compradores eram homens, que saíam à noite para comprar fraldas e aproveitavam para levar algumas latinhas para casa. Os produtos foram postos lado a lado. Resultado: a venda de fraldas e cervejas disparou. A pergunta que não quer calar é: Como essa empresa chegou a essa conclusão com informações que aparentemente são desconexas? 

Magia negra? Simpatia? Pacto com o Demo? Não! Trata-se de análise de dados.

Análise de dados é o processo de aplicação de técnicas estatísticas e lógicas para avaliar informações obtidas a partir de determinados processos. O principal objetivo da prática é extrair informações úteis a partir dos dados. A partir destas informações, é possível tomar decisões mais assertivas e orientadas para resultados. 

Não é de hoje que análise de dados é uma atividade bastante desempenhada por pessoas e empresas. Quem nunca utilizou o Excel para analisar e contabilizar dados, gerar insights e apoiar nossas decisões? 

Mas como analisar dados? Acredito que a melhor forma de explicar isso é através de exemplos.

Vamos supor que um plano de saúde encomende uma análise de perfil de seus associados. A Operadora utiliza um sistema de gestão que possui o cadastro de todos os associados contendo a data de nascimento, sexo, tipo de plano, procedimentos médicos efetuados, etc.

Uma forma de analisar os dados é se basear em fatos, utilizando procedimentos e técnicas de estatística descritiva.

Algumas medidas que são normalmente usadas para descrever um conjunto de dados são medidas de tendência central. Medidas de tendência central incluem média, mediana e moda. Medidas de variabilidade incluem desvio padrão, variância, o valor máximo e mínimo, obliquidade e curtose.

Depois de promover a agregação em conjunto de dados podemos saber a média da idades dos associados do plano de saúde. O percentual de associados do sexo Masculino ou feminino, quais procedimentos médicos são mais realizados e por aí vai.

Damos a ser tipo de análise o nome de ANÁLISE DESCRITIVA.

Após a produção dessas informações podemos prescrever ações para chegarmos a novos resultados. Vamos supor que a incidência de consultas com clínico geral esteja muito alta. Poderíamos propor a aplicação de programas do tipo medicina em família de modo reduzir essa incidência. Esse tipo de análise é conhecimento com ANÁLISE PRESCRITIVA.

Verifique que os exemplos apresentados são basicamente quantitativos. A estatística serve não só como instrumento quantificador, como também para montar modelos e fórmulas que possam antecipar resultados (PROBABILIDADE). É aí que entra a ANÁLISE PREDITIVA aonde são desenvolvidos modelos de aprendizado de máquina capazes de prever que a abertura de clínicas próprias por parte da Operadora de plano de Saúde tende a reduzir o custo da Operadora com consultas com clínico geral.

Resumindo analisar dados é verificar as possibilidades que esses dados trazem, tirando conclusões sobre eles e antecipar tendências.

Mas isso aí é só a pontinha do Iceberg. Bora pro próximo Post!

domingo, 16 de janeiro de 2022

Kubernetes na prática I

        Em outro Post, falamos do que trata o Kubernetes, mas complementando a explicação, trata-se de uma engine de orquestração de contêineres Open Source utilizado para automatizar a implantação, dimensionamento e gerenciamento de aplicativos em contêiner. Algum POD caiu? ele se encarrega de provisionar um novo POD. Aumentou o uso da aplicação? Ele possibilita a criação de novos Pods, para escalar essa aplicação. 

Agora vejamos na prática como trabalhar como implantar um aplicativo em contêiner em um cluster.

  • Atualizar o aplicativo em contêiner com uma nova versão do software.
  • Depurar o aplicativo em contêiner.

Instalação

Quando você realiza a instalação de um cluster Kubernetes, deve decidir o tipo de instalação baseado em critérios como facilidade de manutenção, segurança, controle, quantidade de recursos disponíveis e a experiência necessária para gerenciar e operar o cluster.

Você pode criar um cluster Kubernetes em uma máquina local, na nuvem, em um datacenter on-premises ou ainda escolher uma oferta de um cluster Kubernetes gerenciado pelo seu provedor de computação em nuvem.

Para estudo, uma boa opção é a instalação do Minikube.

Instalou o Minikube? verifique se a instalação foi feita corretamente, executando o comando:

minikube version

Verifique o status do Kubernets executando o comando:

minikube status

Caso o mesmo esteja parado, você pode deletar um cluster. 

minikube delete

Inicialize o cluster, executando o comando:

minikube start

Assim que o seu cluster Kubernetes estiver em execução você pode implementar seu aplicativo em contêiners nele. Para fazer isso, você precisa criar uma configuração do tipo Deployment do Kubernetes. O Deployment define como criar e atualizar instâncias do seu aplicativo. Depois de criar um Deployment, o Master do Kubernetes agenda as instâncias do aplicativo incluídas nesse Deployment para ser executado em nós individuais do Cluster. Na prática fazer um deploy seria criar um Pod em um node. 

kubectl run nginx --image nginx

Podemos verificar se o pod foi criado através do comando 

kubectl get pods

Podemos ter mais informações sobre o Pod, através do comando

kubectl get pods -o wide

Quer mais detalhes sobre um pod específico? Utilize o comando

kubectl describe pod nginx

Até o momento, executamos os comandos via terminal. Contudo podemos fazer isso através de arquivos yaml.

apiVersion: v1

kind: Pod

metadata:

  name: nginx-pod

  labels:

    env: production

spec:

  containers:

    - name: nginx-container

      image: nginx

Com o arquivo em mãos criamos o pod com o seguinte comando:

kubectl create -f pod.yaml ou kubectl apply -f pod.yaml

sexta-feira, 31 de dezembro de 2021

Javascript

 Quando comecei a programar, a linguagem de programação ensinada na minha faculdade era PASCAL. Logo no início arrumei emprego para trabalhar com páginas HTML e para deixar as páginas mais dinâmicas, tive que aprender Javascript. Com o tempo, imaginei que a linguagem ia logo cair em desuso por conta da evolução das tecnologias utilizadas para construção de página. Ledo engano! As novas tecnologias utilizam javascript(frameworks como JQuery, entre outros). O objetivo deste Post é fazer um resumo de javascript na forma mais básica.


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title> Página 1</title>
    </head>
    <body>
        <p>Programação web Com Javascript</p>
        <script>
            //variáveis
            var nome = "Hugo"; //string
            var idade = 48;//inteiro
            var altura = 1.73; //ponto flutuante
            var ativo = true; //boleano
            var alunos =["Hugo", "Fernanda"]; //vetor
            var aluno ={
                nome:"Hugo",
                idade:48,
                altura:1.73,
                ativo:true,
            };  //objeto
            console.log("Imprimindo a variável nome: " + nome);
            console.log(alunos[0]);
            //listando um array
            for(i=0;i<alunos.length;i++){
                console.log(alunos[i]);
            }
            console.log(aluno.nome + aluno.idade);
            //Operadores aritméticos operações matemáticas
            var numero1 = 20;
            var numero2 = 10;
           
            var soma = numero1 + numero2;//soma
            var subtracao = numero1 - numero2;//subtração
            var multiplicacao = numero1 * numero2;//multiplicação
            var divisao = numero1 / numero2;//divisão
            var modulo = numero1 / numero2; //resto da divisão
            var potenciacao = numero1 ** 2

            console.log(soma);
            console.log(subtracao);
            console.log(multiplicacao);
            console.log(divisao);
            console.log(modulo);
            console.log(potenciacao);

            //estruturas de condição
            if(numero1 >= numero2){
                console.log("condição verdadeira");
            }else{
                console.log("condição falsa");
            }
            switch (new Date().getDay()) {
                case 0:
                  day = "Sunday";
                  break;
                case 1:
                  day = "Monday";
                  break;
                case 2:
                   day = "Tuesday";
                  break;
                case 3:
                  day = "Wednesday";
                  break;
                case 4:
                  day = "Thursday";
                  break;
                case 5:
                  day = "Friday";
                  break;
                case 6:
                  day = "Saturday";
              }
              console.log(day);

              //operação ternária
              console.log(day > 6 ? "opção inválida":day);
           
            // estruturas de repetição
            for(var i = 0;i <=10; i++){
                console.log(i);
            }
            while(i <=10){
                console.log(i);
                i = i + 1;
            }
            var contador = 0;
            do{
                contador = contador + 1;
                console.log(contador);
            }while(contador <=10);

            //operadores lógicos
            console.log(10>20 && 20>10);
            console.log(10>20 || 20>10);
            //operadores relacionais
            console.log(5 == 5);
            console.log(5 != 5);

            //Funções
            function somar(num1,num2){
                var res = num1 + num2;
                return res;
            }
            function escrever(){
                console.log("teste");
            }
            console.log(somar(1,2));

            // intervalo
            setInterval(escrever,1000);

            //timeout  Delay
            setTimout(escrever,1000);

            //escopo de variáveis
            function subtrair(num1 - num2){
                var valor = 5;
                return valor = num1 - num2;

            }
            console.log(valor);

            //

        </script>
    </body>

</html>


sábado, 25 de dezembro de 2021

O Ecossistema Hadoop

Até pouco tempo atrás, empresas trabalhavam com sistemas integrados operando em bancos de dados relacionais. Alguns desses sistemas, produziam relatórios com base nesses bancos. Outros, produziam relatórios a partir de armazéns de dados analíticos conhecidos como Datawarehouses.

Hoje o cenário mudou bastante. Estamos vivendo na era da informação em um cenário de BIG DATA Praticamente tudo gera dado(redes sociais, dispositivos do tipo "Internet das coisas", aviões, carros, telefones, entre outros). As vezes, os dados são estruturados, algumas vezes semiestruturados e  muitas vezes, os dados não são estruturados.

Por conta deste novo cenário, o volume de dados e a velocidade de produção desses dados aumentou exponencialmente e consequentemente, a complexidade para mantê-los aumentou proporcionalmente. 

A arquitetura clássica empregada nas soluções de processamento desses dados já não atendia mais a demanda. Verificou-se que toda normalização e segurança providas pelos SGBD's relacionais comprometia do desempenho da análise de dados.

Era necessário processar dados em tempo real, processar as informações de forma distribuída, além de possibilitar a análise de dados não estruturados.


No sentido de atender a essas necessidades, eis que surge um conjunto de ferramentas que fazem parte de um ecossistema conhecido como HADOOP.

O Hadoop foi inspirado na publicação de MapReduce , GoogleFS e BigTable of Google . Ele foi criado por Doug Cutting e faz parte dos projetos da Apache Software Foundation desde 2009.


Esse ecossistema é uma estrutura de código aberto livre escrita em Java destinada a facilitar a criação de aplicativos distribuídos (armazenamento e processamento de dados) e escalonáveis ​​(escalonáveis) , permitindo que os aplicativos trabalhem com milhares de nós e petabytes de dados. Cada nó é, portanto, composto de máquinas padrão agrupadas em um cluster. Todos os módulos do Hadoop são projetados com a ideia de que as falhas de hardware são frequentes e, portanto, devem ser tratadas automaticamente pela estrutura.

O núcleo do Hadoop consiste em uma parte de armazenamento: HDFS ( Hadoop Distributed File System ) e uma parte de processamento chamada MapReduce. O Hadoop divide os arquivos em grandes blocos e os distribui pelos nós do cluster. Para processar os dados, ele transfere o código para cada nó e cada nó processa os dados que possui. Isso torna possível processar todos os dados de forma mais rápida e eficiente do que em uma arquitetura de supercomputador mais tradicional, que conta com um sistema de arquivos paralelo onde cálculos e dados são distribuídos em redes de alta velocidade.

O HDFS é o software responsável pela gestão dos computadores do cluster, definindo como os arquivos serão distribuídos pelos nós que o compõe.

Componentes do HADOOP

Map Reduce

Para manejar grandes volumes de dados e extrair o máximo do big data, o Hadoop conta com um algoritmo, também introduzido pelo Google, chamado Map Reduce que facilita a distribuição e execução de uma tarefa, paralelamente. Sua missão, é basicamente, dividir uma tarefa em várias e processar essas tarefas em máquinas diferentes.

Utilizando-me do ditado popular, ele divide para conquistar e executa os processos nas máquinas do cluster, evitando assim um tráfego intenso de rede.

A forma como o MapReduce funciona pode ser dividida em três fases, com uma quarta fase como opção.

Mapper: Nesta primeira fase, a lógica condicional filtra os dados em todos os nós em pares de valores-chave. A “chave” refere-se ao endereço de deslocamento para cada registro e o “valor” contém todo o conteúdo do registro.

Shuffle: Durante a segunda fase, os valores de saída do mapeamento são classificados e consolidados. Os valores são agrupados de acordo com chaves semelhantes e os valores duplicados são descartados. A saída da fase shuffle também é organizada em pares de valores-chave, mas desta vez os valores indicam um intervalo em vez do conteúdo em um registro.

Reducer: Na terceira fase, a saída da fase Shuffle consolidada é agregada, com todos os valores adicionados às suas chaves correspondentes. Isso é então combinado em um único diretório de saída.

Combiner: A execução desta fase pode otimizar o desempenho do trabalho do MapReduce, fazendo com que os trabalhos fluam mais rapidamente. Ele faz isso pegando as saídas do mapper e examinando-as no nível do nó em busca de duplicatas, que são combinadas em um único par k-v, reduzindo assim o trabalho realizado pela fase shuffle.


HDFS – Hadoop Distribuited File System

Para possibilitar a aplicação do algorítmo de Map Reduce, foi necessária a criação de um de uma novo sistema de arquivos conhecido com HDFS. O HDFS é o componente que armazena dados em formato de arquivos no Hadoop.

A sua arquitetura possui dois componentes principais que são o name node e o data node.

Name node:  é o nó mestre e há apenas um por cluster. Sua tarefa principal é gerenciar os arquivos e os blocos armazenados em cada cluster. Ele basicamente mapeia a localização, faz a divisão dos arquivos em blocos e controla a localização de suas réplicas.  

Data Nodes: são nós escravos e podem ter vários por cluster. Sua missão é recuperar os dados quando requisitado, de onde eles estiverem. São eles que fazem o armazenamento efetivo dos dados e podem conter inúmeros blocos de diferentes arquivos. Eles estão sempre reportando ao name node quais blocos estão guardando e todas alterações que foram efetuadas neles. 


O orquestrador YARN

O YARN ou Yet Another Resource Negotiator gerencia os recursos no cluster e as aplicações no Hadoop. Ele permite que os dados armazenados no HDFS possam ser processados em vários engines como processamento em lote, streaming e etc.

Segundo a Wikipedia, ele se divide basicamente em duas funcionalidades de gerenciamento de recursos e agendamento/monitoramento de jobs em daemons separados.

Em resumo, ele coordena como as aplicações são executadas.

HBASE um banco de dados NoSQL

O HBase é um banco de dados NoSQL, open-source com estrutura colunar.

Roda com o HDFS e pode trabalhar com diversos formatos de dados, permitindo o processamento em tempo real e randômico de leitura/gravação nos dados.

A função principal dele é hospedar grandes tabelas – bilhões de linhas x milhões de colunas – sobre clusters de hardware comum, muito semelhante ao HDFS.

Simplificando a análise de dados com  o Apache Pig

Esse componente do ecossistema Hadoop originou-se de um projeto desenvolvido pelo Yahoo, por volta de 2006 por conta da necessidade de ser ter um mecanismo para execução de jobs MapReduce de maneira ad-hoc, ou seja, de forma mais simplificada para os usuários.

O Pig foi desenvolvido para analisar grandes conjuntos de dados e simplificar a escrita de funções map reduce ou Spark. Ele está estruturado em dois componentes: Pig Latin e Pig engine.

Pig Latin é uma linguagem de script semelhante ao SQL e o Pig Engine é o motor de execução do que é desenvolvido em Pig Latin. Internamente, o script desenvolvido em Pig Latin é convertido em funções MapReduce, tornando a vida dos programadores que não conhecem Java muito mais fácil.

Hive o data warehouse do Hadoop

O Hive é um sistema de data warehouse distribuído desenvolvido pelo facebook.

Ele permite de maneira simples, ler, gravar e gerenciar grandes arquivos no HDFS. Tem sua própria linguagem de consulta chamda HQL – Hive Querie Language – que é muito similar à linguagem SQL.

Ela simplifica a escrita de funções MapReduce usando a linguagem HQL.

Importando e exportando dados de bases relacionais com Sqoop

Sabemos que muitos dados estão armazenados em bancos de dados relacionais. Como eles já estão há muito tempo no mercado, são uma importante fonte de dados. e é aqui que o Sqoop desempenha um papel importante para trazer esses dados dos bancos estruturados para dentro do HDFS.

Todos comandos escritos internamente no Sqoop são convertidos em tarefas MapReduce que são carregadas no HDFS, tem compatibilidade com a maioria dos bancos relacionais (Oracle, SQL Server, MySQL, PostGree e etc.) e pode exportar dados do HDFS para esses bancos.

 Coletando dados em tempo real (streaming) com o Flume

O Flume é software de código aberto, confiável e distribuído utilizado para coletar, agregar e mover grandes quantidades de dados para o HDFS. Segundo a Wikipedia, possui uma arquitetura simples e flexível baseada em fluxo de dados de streaming. Ela é bastante robusta e tolerante a falhas pois possui vários mecanismos de failover e recuperação caso seja necessário.
Ele pode coletar os dados em real time ou batch.

Mensageria com o Kafka

Existem inúmeras aplicações gerando dados e muitas outras consumindo-os, porém conectá-las individualmente é uma tarefa bastante difícil. Quando essa necessidade aparece é que entra o Kafka.
Ele fica entre as aplicações que geram dados (producers/produtores) e as que consomem os dados (consumers/consumidores).

A plataforma, segundo a Wikipedia, tem por objetivo entregar uma plataforma integrada e de baixa latência para tratamento de dados em tempo real.

O Kafka tem processamento distribuído, replicação e tolerância a falhas nativo. Ele pode lidar com streaming de dados e permite a análise de dados em tempo real. Ele foi originalmente desenvolvido pelo Linkedin e teve seu código aberto no início de 2011.

 Scheduller com o Oozie


O Oozie é um agendador de workflows que permite aos usuários fazerem o agendamento dos jobs desenvolvidos em várias plataformas, como MapReduce, Pig, Hive e etc.

Usando o Oozie é possível criar um job que possa chamar de maneira orquestrada, outros jobs ou pipelines de dados, seja de maneira sequencial ou paralela para executar uma determinada tarefa.

É um produto open-source, confiável e escalável que auxilia muito as tarefas de quem usa o ecossistema Hadoop.

Zookeeper

Como já vimos manter um ambiente Hadoop é bastante desafiador. Sincronizar, coordenar e manter as configurações de um ambiente de cluster Hadoop exige bastante esforço, para resolver esse problema entra em cena o Zookeeper.
Ele é um software open-source, distribuído, e com um serviço centralizado para manter as informações de configuração, naming , sincronização distribuída e um grupo de serviços para todo o cluster.

Processando dados em memória principal com o Spark

O Spark é um framework de código aberto, alternativo ao Hadoop, desenvolvido em Scala que também oferece suporte a diversas aplicações escritas em Java, Python(Pyspark) e etc.

Comparado com o MapReduce, ele executa o processamento em memória aumentando consideravelmente a velocidade de execução desses processos.

Outro ponto importante a ser considerado é que além dele executar processos em batch igual o Hadoop, ele também consegue trabalhar em tempo real.

Além disso, o Spark tem seu próprio ecossistema:

Spark Core: é o core da aplicação, o principal mecanismo de execução do Spark e outras API´s construídas sobre ele.

Spark SQL API: permite fazer queries/consultas em dados estruturados em data frames ou tabelas Hive.

Streaming API: permite o Spark lidar com dados em tempo real. Ele se integra facilmente com uma variedade de fontes de dados como Kafka, Flume, Twitter e etc.

MLlib: é uma biblioteca de machine learning escalável que permite executar algoritimos de ciência de dados aproveitando as funcionalidades do Spark ao mesmo tempo, sem perda drástica de performance.

GraphX: é um engine de computação gráfica que permite os usuários interagir, construir e transformar dados em gráficos e vem com uma biblioteca de algorítimos comuns.

Etapas de um processo de Big Data com Hadoop

  • Flume, Kafka, Sqoop são utilizados para fazer a ingestão de dados no HDFS.
  • O HDFS é a unidade de armazenamento do Hadoop. Até os dados importados do HBase também são armazenados no HDFS.
  • MapReduce e Spark são usados para processar os dados no HDFS e executar várias outras tarefas.
  •  Pig, Hive e Spark são utilizados para analisar dados.
  • Oozie ajuda a agendar as tarefas e por funcionar com várias plataformas, é utilizado ao longo das etapas.
  • Zookeeper sincroniza todos os nós do cluster e é utilizado em todas as etapas.
Ficou grande, mas considero um bom resumo sobre tecnologias que foram criadas para trabalhar com grande volume de informações.

Inté!






sábado, 6 de novembro de 2021

Orquestração de Containers com Kubernetes.

        Com o tempo, a sua aplicação ficou bastante famosa e começou a receber muitos acessos e consequentemente, ela ficou muito lenta. Como resolver isso? Certa a resposta para quem pensou em provisionar mais recursos de infra para a aplicação. É necessário "Escalar" o Sistema. Você pode fazer isso de duas formas: Escalar verticalmente, aumentando o poder de processamento do servidor no qual a sua aplicação foi hospedada,  aumentando recursos de CPU e memória, ou ainda, escalar horizontalmente, criando/adicionando nós ao cluster de servidores que atende as requisições para este Sistema.

            Tomar essa decisão não é a coisa mais simples do mundo e depende de uma série de variáveis. O Sistema é monolítico ou baseado em Microserviços? Se você respondeu que ele foi construído baseado em uma arquitetura de microserviços, você ainda consegue escalar esse sistema de forma mais eficiente. 
            
        Agora vamos supor que você provisionou esses microserviços em containers. Para escalar, bastaria criar novos containers dos microserviços impactados pelo número de requisições feitos a ele.

            Para quem é craque em docker sabe que isso é uma dor de cabeça. Como monitorar esses containers? Você pode gerenciar isso manualmente, fazendo sua aplicação escalar up/down de acordo com as necessidades. Controlar dois ou três serviços é fácil. Agora imagina monitorar dezenas ou centenas deles?

        Pensando nisso, a Docker e diversas outras Empresas, correram atrás de criar soluções para orquestrar containers. A solução criada pela Google ganhou grande popularidade e até pouco tempo atrás era líder de mercado. Estamos falando aqui do Kubernetes.

         O kubernetes, conhecido também como K8s, foi criado pela Google, baseado na experiência deles no gerenciamento de containers em produção. A evolução do kubernetes e ampla adoção se deu após este projeto se tornar open-source, ou seja, de código aberto, na qual qualquer pessoa ou empresa não somente passou a poder utilizá-lo gratuitamente, mas também novas funcionalidades e melhorias foram implementadas de forma mais rápida.

        Fazendo uso do Kubernetes, a medida que sua aplicação vai recebendo mais acessos, novos “nodes” são criados, e se a aplicação tiver menos acessos estes “nodes” extras são destruídos, fazendo com que tenhamos mais flexibilidade.

Arquitetura do Kubernetes

          Mas o que é um NODE? Um node é uma máquina, física ou virtual, onde o Kubernetes está instalado. No node criamos os containers(com docker) com as nossas aplicações. 

        Quando criamos uma aplicação em um container, o Kubernetes não faz uso/acesso direto ao container. Os Containeres ficam dentro de Pods.

            A medida que o sistema vai recebendo mais acessos, o Kubernetes cria novos Pods com containers e faz o balancemento de cargas para dividir as requisições feitas ao sistema.

                 Se a quantidade de acessos à sua aplicação continuar a crescer e seu node não suportar novas instâncias da aplicação, ainda podemos adicionar quantos novos nodes forem necessários ao cluster para dividir a carga.
                
                Em alguns raros casos podemos ter a necessidade de uma aplicação fazer uso de um container auxiliar, logo podem existir casos de um Pod conter mais de um container (Python e um container com o Redis por exemplo).

            No Kubernetes os nodes costumam ser agrupados em CLUTERS. Caso um node venha a falhar, outro node assume o controle, evitando-se assim a indisponibilidade do sistema.

            A partir do momento que temos um cluster, algum node tem que ficar responsável por gerenciá-lo. Gerenciar o cluster significa manter informações dos membros do cluster, monitorar os nodes, ativar um novo node ou não, quando um node falha. O node que faz esse papel é chamado MASTER. Os demais nodes são conhecidos com WORKERS.

Componentes do Kubernets

            Quando instalamos o Kubernets, 6 componentes são instalados com ele. Aqui vai uma pequena descrição desses componentes:

API SERVER - A API Server funciona como um frontend para o Kubernetes. Ou seja, é através dele que gerenciamos usuários, dispositivos e interface de linha de comando.

ETCD - O etcd é usado para armazenar dados, de forma distribuída, no formato chave/valor para configuração e gerenciamento dos clusters. Podemos ter múltiplos clusters, cada cluster com seu master, e o etcd guardando dados de forma distribuída nos nodes. Além disso os logs dos clusters são gravados aqui.

SCHEDULE (agendador) é responsável por distribuir o trabalho para os containers através dos múltiplos nodes. Ele também “busca” por novos containers criados e anexa eles aos nodes.

CONTROLLER é o cérebro por traz da orquestração. Ele é responsável por tomar as decisões quando um node falha ou apresenta problemas e pode ativar novos nodes para substituir os
problemáticos.

CONTAINER RUNTIME faz interface com o software usado para criação dos containers, no nosso caso o docker engine, mas pode ser utilizado com outros softwares com o mesmo propósito.

KUBERLET é o agente que é executado em cada node em um cluster. O agente é responsável por checar se os containers estão sendo executado no node conforme o esperado.


        O que difere um master node de um worker node é a quantidade de componentes que esses nodes possuem. Enquanto o node Master tem mais componentes, os work nodes possui menos componentes(Kuberlet e Container Runtime).

       Por fim, ao instalar e configurar o Kubernetes, temos a disposição um programa de linha de comando chamado kubectl (Kube Control Tool), utilizado, em muitos momentos, para executar comandos do kubernetes. Uma das utilizações desta ferramenta é para realizar deploy (publicação) de aplicações em um cluster do kubernetes.

Resumindo, quer trabalhar com containers em ambiente de desenvolvimento ou homologação? Usa Docker. Vai trabalhar com containers em ambiente de produção? Kubernetes é o cara!

        O Post ficou grande. Faremos outro para tratar ver na prática como o Kubernets pode nos facilitar a vida.

Até mais!