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 NODEUm 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.


        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!


domingo, 19 de setembro de 2021

PL/SQL Resumo

 O PL/SQL é uma extensão da linguagem padrão SQL para o SGBD da Oracle. É uma linguagem procedural da Oracle que estende a linguagem SQL. Permite que a manipulação de dados seja incluída em unidades de programas.

Todo programa possui variáveis, estruturas de condição, estruturas de repetição, unidades de programas reutilizáveis(funções e procedimentos) comandos para receber e exibir valores. 

Além disso, o PL/SQL possibilita a integração com ferramentas Oracle, portabilidade e o tratamento de exceções.

Assuntos a serem tratados:



Nesse primeiro post vamos falar sobre as estruturas presentes em um programa e variáveis

(bloco anônimo)

DECLARE --(opcional)

–-Variáveis, cursores e exceções definidas pelo usuário

BEGIN --(obrigatório)

–-Instruções SQL

–-Instruções PL/SQL

EXCEPTION --(opcional)

–- Ações a serem executadas quando ocorrerem exceções

END; --(obrigatório)

Blocos nomeados

-- Procedures(Não retornam valor)

PROCEDURE name
IS
BEGIN
 --statements
[EXCEPTION]
END;

--Funções (retornam valor)

FUNCTION name
RETURN datatype
IS
BEGIN
 --statements
 RETURN value;
[EXCEPTION]
END;

Variáveis (PL/SQL, de substituição e de ligação)

/*
Para habilitar a saída no SQL Developer, execute o 
seguinte comando antes de executar o bloco PL/SQL:
SET SERVEROUTPUT ON
2. Utilize um pacote Oracle predefinido e seu procedure no 
bloco anônimo:
– DBMS_OUTPUT.PUT_LINE
*/

set SERVEROUTPUT ON;
--variáveis plsql
DECLARE 
V_NOME VARCHAR2(50):= 'Habbema';
BEGIN 
DBMS_OUTPUT.PUT_LINE(V_NOME); -- pacote e procedure que permite exibir o valor de variáveis
END;

--Variáveis de substituição

DECLARE 
V_NOME VARCHAR2(50):= '&nome';
BEGIN 
DBMS_OUTPUT.PUT_LINE(V_NOME); -- pacote e procedure que permite exibir o valor de variáveis
END;

--variáveis de ligação (BIND)

VARIABLE b_nome VARCHAR(20)
EXEC :b_nome :='TESTE';
BEGIN
  DBMS_OUTPUT.PUT_LINE(:b_nome);
END;

--Declarando  e inicializando variáveis

DECLARE
 v_myName VARCHAR2(20);
BEGIN
 DBMS_OUTPUT.PUT_LINE('My name is: '|| v_myName);
 v_myName := 'John';
 DBMS_OUTPUT.PUT_LINE('My name is: '|| v_myName);
END;

-- referenciando uma variável do tipo bind

VARIABLE b_emp_salary NUMBER
BEGIN
 SELECT salary INTO :b_emp_salary 
 FROM employees WHERE employee_id = 178; 
END;
/
PRINT b_emp_salary
SELECT first_name, last_name
FROM employees
WHERE salary=:b_emp_salary;

-- variáveis compostas
--registro
DECLARE
 TYPE t_rec IS RECORD
 (v_sal number(8),
 v_minsal number(8) default 1000,
 v_hire_date employees.hire_date%type,
 v_rec1 employees%rowtype);
 v_myrec t_rec;
BEGIN
 v_myrec.v_sal := v_myrec.v_minsal + 500;
 v_myrec.v_hire_date := sysdate;
 SELECT * INTO v_myrec.v_rec1
 FROM employees WHERE employee_id = 100; 
 DBMS_OUTPUT.PUT_LINE(v_myrec.v_rec1.last_name ||' '||
 to_char(v_myrec.v_hire_date) ||' '|| to_char(v_myrec.v_sal));
END;


quinta-feira, 19 de agosto de 2021

O Básico de Python

Python é uma linguagem Open-Source de propósito geral usado bastante em data science, machine learning, desenvolvimento de web, desenvolvimento de aplicativos, automação de scripts, fintechs e mais.

A ideia deste post é fazer um resumo, descrevendo a sintaxe da linguagem e suas estruturas (condição, repetição, e dados).


#criação e exibição de conteúdo de variáveis
nome = "Hugo" #tipo string

#printando uma variável
print(nome)
idade = 47 #tipo inteiro
print(idade)

#estrutura de condição
if idade == 48:
  print(idade)
else:
  print("Esse é o texto que vai aparecer")

#elif
media = 6
if media <5:
  print('reprovado')
elif media > 5 and media < 7:
  print('recuperacao')
else:
  print('aprovado')

#Estruturas de repetição
#while
gastos = 0
valor_gasto = 0
while gastos < 10:
  #input serve para capturar valores fornecidos pelo usuário
  #O int é para converter explicitamente o valor da variável.
  valor_gasto = int(input("Digite o valor do novo gasto"))
  gastos = gastos + valor_gasto
print(gastos)

#for
for i in range(110):
    print(i)


#Criação de uma função
def mais_um_ano(idade):
  return idade + 1

#chamando a função
mais_um_ano(idade)

#Estrutura de dados
#listas
lista = ["item1""item2""item3"]
print(lista)

#Como pegar um item de uma lista
print(lista[0]) #primeiro elemento da lista

#pegar o último elemento da lista
print(lista[-1])

#Como iterar sobre a lista
for i in lista:
  print(i)

#dicionários
dados = {"nome":"Hugo","idade":47}

#printando itens do dicionário]
print(dados)

#printando um item do dicionário
print(dados["idade"])

#Iterando na lista

for i in dados:
  print(dados[i])

#tuplas são imutáveis
nome_da_tupla = (123#tupla de inteiros

nome_da_tupla = (1"olá"1.5#tupla heterogênea

print(nome_da_tupla)

Veja que o Python é uma linguagem simples. O que dá poder a ela é são os pacotes/bibliotecas desenvolvidas por terceiros. Vamos falar sobre alguns pacotes em outros Posts.

Inté.

Análise de dados na prática com o Pandas

 Lembra daquele trabalho que a gente fazia para promover a transformação e a higienização de dados no Excel?  Não tínhamos problema em trabalhar dessa forma enquanto o volume de dados era pequeno. Porém na era do Big Data planilhar e analisar os dados no excel virou um problema. O pacote Pandas surgiu para resolver esse problema. 

A biblioteca Pandas nos permite fazer análises exploratórias em conjunto de dados. Ela dá ao Python, a capacidade de trabalhar com dados tipo planilha, permitindo carregar, manipular e combinar dados.

A ideia aqui é apresentar um trabalho prático, de modo a assimilar conhecimento sobre o Pandas, sendo necessário apenas conhecimento básico das estruturas de dados do Python.

1 - Vamos criar um arquivo pandas.csv

2- importar o pacote pandas

#importando a biblioteca pandas
import pandas as pd

3- Carregar o Dataset sob o qual faremos a análise exploratória. No pandas, um dataset é conhecido como Dataframe.

#Carregando o dataset retirando linhas com problema e 
#utilizando como separador ponto e vírgula
df = pd.read_csv("Gapminder.csv",error_bad_lines=False, sep=';')

3- Visualizando os dados
#visualizando as 5 primeiras linhas
df.head(10) # ao passar um valor inteiro, você determina a quantidade
de linhas retornadas


















5- Renomeando colunas

#Renomeando colunas
df.rename(columns=
{"country":"País","continent":"Continente","year":"Ano",
"lifeExp":"Expectativa de vida","pop":"População","gdpPercap":"PIB"})

6- Retornando o número de linhas e colunas
#retornando o número de linhas e colunas
df.shape
(3312, 6)

7- Retornando o nome das colunas

#Retornando o nome das colunas 
df.columns
Index(['country', 'continent', 'year', 'lifeExp', 'pop', 'gdpPercap'], dtype='object')

8- Retornando o nome das colunas
#retornando os tipos de dados das colunas
df.dtypes

country object continent object year int64 lifeExp float64 pop int64 gdpPercap float64 dtype: object

9- Retornando as últimas linhas
#retornando as últimas linhas
df.tail()












10- Retornando dados estatísticos

#Retornando dados estatísticos
df.describe()

















11 - Pegando valores únicos na Coluna (Distinct)
# pegando valores únicos na coluna Continent
df['continent'].unique()

array(['Asia', 'Europe', 'Africa', 'Americas', nan, 'FSU', 'Oceania'], dtype=object)

12 - Filtrando dados (where)
#filtrando dados
Oceania = df.loc[df["continent"] == "Oceania"]
Oceania.head()












13 - Pegando a média de um campo
#média da expectativa de vida
df.groupby("year")["lifeExp"].mean()

14 - Agrupando dados (paises por continente count())
#agrupando dados por continente
df.groupby("continent")["country"].nunique()

15 - Soma e Média dos valores de um campo.

#Soma dos valores de um campo
df["gdpPercap"].sum()

#Média de valores de um campo
df["gdpPercap"].mean()

Neste exemplo, trabalhamos com arquivos .csv, mas é possível também trabalhar com planilhas Excel, dados provenientes de bancos de dados, entre outros.

Até a próxima!

sábado, 7 de agosto de 2021

O que é Engenharia de Dados

         Até pouco tempo atrás, nos deparávamos com um cenário onde os sistemas eram monolíticos, persistindo e consultando informações em bancos de dados relacionais. 

        Os mais avançadinhos criavam bancos de dados dimensionais visando performance e facilidade na busca das informações.

        Com o tempo, esse cenário foi mudando. Com o advento da Internet e Internet das coisas, hoje praticamente tudo gera informação, nem sempre de forma estruturada. O formato varia de acordo com o dispositivo que gera a informação. Exemplo: Câmeras que geram fotos, roteadores que geram logs em formato txt, uma peça de um automóvel que indica ao fabricante a necessidade de reparo, entre outros.

        Daí surge algumas questões: Como e onde guardar esses dados? Como produzir informação com os dados gerados se estes, nem sempre são estruturados e possui diversos formatos. Seria o DBA o responsável por resolver essas questões? É nesse cenário que surge a Engenharia de Dados, visando promover a governança das estruturas que irão receber dados desta natureza.

     Em um outro post falamos de ETL, aonde extraímos dados de bancos relacionais, realizamos transformações e geramos informações de acordo com a necessidade do negócio envolvido, com a finalidade de alimentar um banco de dados dimensional(Um DW estruturado). Mas, quando estamos lidando com dados semiestruturados ou ainda dados não estruturados, a ordem dos fatores se altera. Ocorre outro tipo de processo que é conhecido como ELT. É feita a carga desses dados não estruturados para o que chamamos de Datalake, onde é feita a transformação dos dados.

    Resumindo, um Engenheiro de Dados é o profissional que desenvolve, opera e mantem estruturas de dados complexas e heterogêneas, sendo responsável pela segurança, integridade, disponibilidade e confiabilidade desses dados.


sexta-feira, 4 de junho de 2021

O cinto de utilidades ETL

 Na postagem anterior, ficaram algumas questões a serem respondidas. Para responder a estas questões, vamos criar um cenário hipotético.

A empresa na qual você trabalha demandou a criação de uma base de dados OLAP para subsidiar um Data Warehouse. Essa empresa possui dois Sistemas OLTP para apoiar o trabalho desempenhada por ela: Um sistema de gestão administrativo no qual são mantidos o cadastro dos funcionários entre outros e outro sistema de gestão para gerir vendas efetuadas pela Empresa. Ao demandar a criação da base OLAP, o solicitante indicou aonde obter aos dados que irão compor a base em questão, com a finalidade de analisar as vendas efetuadas pelos funcionários da Empresa. Parte dessas informações encontram-se na base de dados que subsidia o sistema administrativo. Outra parte, pode ser obtida na base de dados do sistema que subsidia o sistema de vendas e ainda há informações constantes em planilhas preenchidas pelos vendedores e por seus gerentes.

Daí você pensa: Vou fazer um select desses dados nas bases de dados indicadas e fazer um insert no banco de dados OLAP. Simples assim! Simples? Como fica a questão das planilhas? E ainda como vincular as informações extraídas desses sistemas e das planilhas mencionadas? Além disso, verificou-se que os dados contidos nessas bases de origem possui formatos distintos, ou seja, não seguem um padrão único. 

Chega a fazer a gente pensar que com a solução do Select/Insert é impossível resolver essa questão. Impossível não é, mas daria um "trabalhão" danado. Ainda mais, se levássemos em consideração a atualização periódica dessa base OLAP.

Complicou, né? E para descomplicar, surgiram no mercado ferramentas que fazem esse trabalho de Extração, Tranformação e carga dos dados.

ETL, vem do inglês Extract Transform Load, ou seja, Extração Transformação Carga. O ETL visa trabalhar com toda a parte de extração de dados de fontes externas, transformação para atender às necessidades de negócios e carga dos dados dentro do Data Warehouse. 

Abaixo, uma ilustração do processo


Vamos descrever as atividades envolvidas nesse processo:

Na extração, é feita a coleta de dados dos sistemas de origem , extraindo-os e transferindo-os para o ambiente de DW, permitindo ao sistema de ETL operar sobre os dados de forma independente.

 Na etapa de transformação, é feita a limpeza, os ajustes e a consolidação dos dados ingeridos. É nesta etapa que realizamos os devidos ajustes, podendo assim melhorar a qualidade dos dados e consolidar dados de duas ou mais fontes. O estágio de transformação aplica uma série de regras ou funções aos dados extraídos para ajustar os dados a serem carregados. Algumas fontes de dados necessitarão de muito pouca manipulação de dados. Em outros casos, pode ser necessários trabalhar algumas transformações, como por exemplo, junção de dados provenientes de diversas fontes, seleção de apenas determinadas colunas e tradução de valores codificados. Por exemplo, se o sistema de origem armazena 1 para sexo masculino e 2 para feminino, mas o data warehouse armazena M para masculino e F para feminino.

A entrega ou Carga dos dados, consiste em fisicamente estruturar e carregar os dados para dentro da camada de apresentação seguindo o modelo dimensional. Dependendo das necessidades da organização, este processo varia amplamente. Alguns data warehouses podem substituir as informações existentes semanalmente, com dados cumulativos e atualizados, ao passo que outro DW (ou até mesmo outras partes do mesmo DW) podem adicionar dados a cada hora. A latência e o alcance de reposição ou acréscimo constituem opções de projeto estratégicas que dependem do tempo disponível e das necessidades de negócios. 

Há ainda a parte de Gerenciamento que é composta por serviços para auxiliar no gerenciamento do DataWarehouse. Aqui existem tasks específicas para gerenciamento de jobs, planos de backup, verificação de itens de segurança e compliance.

A intenção aqui, era fazer um overview sobre o assunto. Existem diversas ferramentas deste tipo no mercado. Cabe a vocês pesquisarem sobre elas:

  • Data Stage da IBM 
  • PowerCenter da Informatica
  • Data Integrator da Oracle
  • SSIS – Sql Server Integration Services da Microsoft

Hoje com o crescimento dos projetos de Big Data aumenta-se mais ainda a necessidade de fazer ETL entre plataformas heterogêneas, para isso, projetos como o Hadoop, possuem ferramentas próprias para carga de dados, como :

SQOOP – Ferramenta para movimentar dados dentre bancos de dados relacionais e o ambiente Hadoop.

HIVE – Ambiente de SQL sobre um cluster Hadoop.

PIG – Ferramenta de Script para transformação e processamento de dados.

SPARK – Framework de processamento em memoria.

É isso!

Modelagem dimensional na prática

 Em outro post, tentei desmistificar o conceito de Data warehouse. Voltando a ler o Post, senti falta de um exemplo prático que mostrasse as vantagens e desvantagens de modelar de forma dimensional uma base de dados para atender a um DW.  A ideia deste post é tentar apresentar uma resposta a estas questões.

Conforme mencionado no outro post, o DW visa resolver questões de performance na execução das consultas.  E como se resolve isso? A forma encontrada foi modelar a base de um jeitão meio diferente, o que ficou conhecido como Modelagem dimensional.

A Modelagem dimensional é uma técnica de design de banco de dados projetada para suportar consultas de usuários finais em um Data Warehouse.  

A ideia é que os usuários consigam fazer consultas sem necessitar da ajuda de profissionais especializados em SQL. 

Em modelos relacionais, é prezada a questão da normalização. Na modelagem dimensional, para melhorar o desempenho das consultas, há redundância planejada dos dados, compensando os gastos com armazenamento e atualização das informações, fazendo com o que a base de dados fique de certo modo desnormalizada.

O modelo dimensional é composto por tabelas fato e por tabelas conhecida como dimensões.

Na prática, a tabela fato armazena as chaves das dimensões e armazena também as métricas a serem analisadas por quem vier a consultar o DW.

Já as tabelas de dimensão são compostas basicamente de atributos que descrevem as entidades envolvidas no modelo. 

Modelando desta forma, o modelo fica parecido com uma "estrela"


Nesse modelo os dados são desnormalisados para evitar joins entre tabelas, diminuindo o tempo de consultas, no entanto devido a repetição de dados, utiliza mais espaço em disco. A vantagem desse modelo é a eficiência na extração de dados, o que é um grande diferencial em se tratando de um datawarehouse.

A chave da tabela fato é uma chave composta, uma vez que trata-se da junção das chaves das tabelas de dimensão.

Importante também é não misturar os fatos. Exemplo: A finalidade é analisar o volume de vendas? Devemos criar uma tabela fato específica para isso. Ao analisar o volume de compras, deve-se criar outra tabela fato com essa finalidade.

Quando a quantidade de atributos das dimensões é muito grande,  costuma-se normalizar as tabelas de dimensão. Neste caso, o modelo fica parecendo um floco de neve (Snow Flake ). Isto porque cada tabela de dimensão seria normalizada, "quebrando-se" a tabela original ao longo de hierarquias existentes em seus atributos. 



A adoção de um modelo ou de outro de implementação trás vantagens e desvantagens em relação a performance das consultas e volume de armazenamento dos dados. Cabe aos analistas decidirem qual será a melhor abordagem.

Cheguei a conclusão de que a melhor maneira de entender a modelagem dimensão é através de exemplos. Abaixo coloquei alguns exemplos de modo a clarear o entendimento deste tipo de modelagem.

Exemplo de um modelo conceitual



Exemplo de modelo para análise de despesas



Exemplo de modelo para análise de produção


A dica aqui é procurar nos pais dos burros (Google) mais modelos de modo a fixar a ideia desse tipo de modelagem.

Como entrevistar os usuários de um DW? Segue um texto legal do Piton nesse link https://rafaelpiton.com.br/blog/data-warehouse-como-modelar/

E aí? O post deu uma clareada? Em caso afirmativo, fico satisfeito. Tem outras questões a serem respondidas. Como importar os dados da origem de dados que comporão as tabelas do DW? Como atualizar esses dados ao longo do tempo? Se os dados que vierem compor o DW provierem de fontes de dados distintos, com formatos diferentes, como unificar o padrão desses dados? A resposta a essas perguntas estará em outro post sobre ETL.


Valeu!!!