MDX Para Quê?

Por que alguém precisaria aprender MDX? É o que eu pretendo justificar aqui.

Preparado?

Get set, ready, go!

M-D-OQ?

MultiDimensional Expressions é uma linguagem para construção de visões de dados multidimensionais (i.e. com cabeçalhos em linhas e colunas) inventada pela Microsoft, a partir da meta simples de levar BI para as massas.

MDX é muito parecido com SQL, no sentido de que é uma consulta que “constrói” uma “tabela”, exceto por alguns fatos:

  • O resultado tem uma forma mais semelhante a uma planilha que a uma lista;
  • O motor que trata consultas MDX não é um banco de dados relacional tradicional, mas um servidor de dados multidimensional;
  • MDX não possui uma DDL, que é um conjunto de comandos para definir estruturas de dados. Em SQL, por exemplo, CREATE TABLE é um comando DDL;
  • E não tem esses comandos justamente porque o propósito do MDX é fazer consultas, não transações. Mesmo assim, criou-se uma coisa chamada writeback, que permite escrever dados de volta para o servidor multidimensional.

Se você ainda não adivinhou, MDX é uma linguagem de consulta de cubos OLAP. Daí você entende facilmente que MDX é apenas parte de uma arquitetura maior, que engloba um servidor OLAP, ou multidimensional (do qual o Mondrian é um tipo), e algum tipo de processo de atualização de dados.

Há dois bons livros para aprender sobre OLAP e MDX:

O Problema

Vamos deixar MDX de lado um pouco, e examinar o problema desta semana. Para (não) variar, é um problema que eu vim a enfrentar ao tentar resolver uma situação muito ordinária, apresentada por um colega de trabalho.

Esse colega trabalha no marketing da empresa e fez uma pesquisa com nossos empregados. De maneira geral, a pesquisa tinha dois tipos de perguntas:

  • Perguntas com respostas únicas, como sim/não ou uma lista de opções do qual somente uma podia ser escolhida. Por exemplo, setor do empregado (uma opção de uma lista), e se conhecia a estratégia da empresa (sim ou não;)
  • Perguntas que podiam ter nenhuma resposta, uma resposta ou mais de uma resposta. Exemplos: qual é seu meio preferido de comunicação (cite até três).

Para simplificar, assuma que esses dados eram coletados em uma planilha com este layout:

ID P1 P2.A P2.B P2.C
1 Sim E-mail
2 Não Cartaz Reunião
3 Sim

Obviamente a pesquisa era bem maior que isso, e tínhamos várias perguntas de cada tipo. O que é importante guardar aqui é que existe uma pergunta que gera uma resposta em uma única coluna, como a P1, e perguntas que geravam suas respostas em n colunas – duas, três, dez.

Como analisamos esses dados? Bom, por exemplo, podemos perguntar quantas pessoas conhecem a estratégia da empresa, que é a P1. A resposta é obtida somando-se todos os SIMs da lista de respostas. Um simples SELECT COUNT('SIM') AS conheco FROM pesquisa traria a resposta. Ou falando em termos de Excel, basta colocar uma função de contagem para totalizar a coluna da P1.

Outra pergunta pode ser: quantas pessoas têm no e-mail seu meio de comunicação preferido? A resposta, de novo, é obtida com relativa facilidade: contamos quantas vezes a expressão E-mail aparece na coluna P2.A.

Mas é claro que a realidade nunca é assim tão fácil, não é mesmo? Não teria graça, se fosse. ;-)

Suponha que nosso chefe peça o seguinte: “descubra os três meios de comunicação mais preferidos, por ordem do mais votado para o menos votado”.

Fácil? Algoritmicamente, talvez:

  1. Conte P2.A, P2.B, P2.c etc.
  2. Crie uma outra tabela, de duas colunas: opção e contagem;
  3. Insira, na primeira linha desta tabela, o rótulo “E-mail” na coluna 1, e sua contagem na coluna 2;
  4. Repita isso para todas as outras opções;
  5. Ordene esse tabela do maior para o menor, usando a coluna 2 e limitando o resultado em 3 linhas.

O resultado seria algo assim:

Meio Contagem
E-mail 10
Cartazes 7
Reuniões 2

“Ah”, pensas tu, “fácil como torcer para o Grêmio, guri!”


Estou em um treinamento de Lean Business Analysis pelo Luiz Parzianello, um porto-alegrense bah, tchê! Daí eu acabei pegando o sotaque, índio velho!


Então você pensa que é fácil?

Hahahahahaha…

Permita-me frisar:


HahahAHhAHHHaHAhAhAHAHHHahahaHAhahaha!!!….


É qualquer coisa, menos fácil. Por favor, tente essas análises:

  1. Qual é a porcentagem de empregados que conhece a estratégia e prefere e-mail?
  2. Qual é a porcentagem de cada opção, em cima do total de empregados que responderam essa pergunta?

A primeira análise é similar à inicial, mas com um filtro aplicado (conhece a estratégia = sim) antes de calcular a razão entre todos que responderam SIM para opção de e-mail pela quantidade de SIMs totais.

E a segunda? Simples:

  1. Calcular a razão entre a quantidade que respondeu “prefiro e-mail”, pela quantidade de participantes que tem pelo menos uma resposta;
  2. Calcular a razão entre a quantidade que respondeu “prefiro cartaz”, pela quantidade de participantes que tem pelo menos uma resposta;
  3. Etc.

E é claro que fica cada vez mais complicado: depois de dois dias trabalhando com Excel sem parar, o chefe olha seu relatório e diz: “excelente! agora quebra por setor!”

Vamos é querer quebrar a cabeça do pobre desafortunado que decidiu te ter na equipe, não é?


Vou tentar colocar de outra maneira: contagens simples são, como o nome implica, ações triviais. Só que, em geral, o maior valor de negócio está nas análises mais complexas, mais sofisticadas. Coisas que nem sempre podem ser respondidas com filtros e contagens.

Se meu exemplo não passou esse cenário, perdão. Esse é o cerne do problema: análises “complexas”


Trabalho de Ser Vivo de Crânio Ornado com Projeções Ósseas

Pode não ser um trampo excessivo quando temos uma pesquisa só, que por sua vez contém apenas uma pergunta deste tipo, que não tem mais que meia-dúzia de opções.

Mas, adivinha: meu colega vai fazer uma pesquisa assim uma vez a cada pelo menos dois meses! E cada uma das pesquisas do baita tem, por alto, uma meia-dúzia dessas perguntas, cada uma com quase dez opções, se não mais. E cada pesquisa atinge 10.000 empregados, com uma taxa de quantidade de respostas média em torno de 3.000. Ou seja, dos 10.000 pesquisados, em média, 3.000 respondem.

E conforme o número de variáveis sobe (gênero, setor, cidade, faixa etária, conhecimento etc. etc. etc.) sobe exponencialmente o trabalho para correlacionar uma coisa com outra.

Mas fica pior.

Uma Pergunta Múltipla Incomoda Muita Gente…

.. duas incomodam, icomodam muito maais.

Uma técnica prática para simplificar o trabalho de corno que é tabular esse tipo de dado é transpor parte da pergunta, ou desnormalizá-la. Por exemplo, a tabela do início vai de:

ID P1 P2.A P2.B P2.C
1 Sim E-mail
2 Não Cartaz Reunião
3 Sim

para:

ID P1 P2
1 Sim E-mail
2 Não Cartaz
2 Não Reunião
3 Sim

Notou o que eu fiz? Eu repliquei cada linha que tinha mais de uma resposta, e coloquei todo mundo lá.

Agora ficou mais fácil fazer uma contatem simples. Mas o que aconteceu se eu tiver DUAS perguntas de múltiplas escolhas?

ID P1 P2 P3
1 Sim E-mail Escolha X
1 Sim E-mail Escolha Y
2 Não Cartaz Escolha Y
2 Não Cartaz Escolha K
2 Não Cartaz Escolha Z
2 Não Reunião
3 Sim Escolha Y

Agora não basta mais contar cada coluna: é preciso deduplicá-las antes, e fazer as contas depois.

Uma vez a cada dois meses.

Em datasets pequenos, de coisa de 3.000 linhas… E algumas dezenas de colunas. Duas perguntas de cinco escolhas cada, as 3.000 linhas iniciais pulam para pelo menos cerca 6.000, podendo chegar – em casos extremos – a centenas de milhares de linhas… PARA SEREM TRATADAS NO EXCEL.

Não vira, né? ;-)

Operações de Conjuntos

Foi tentando resolver esse problema que a minha ficha caiu: eu vou precisar de um ETL específico para cada pergunta de resposta múltipla para colocar tudo como colunas simples, para permitir contagens simples, mas cada contagem vai ficar mais complicada ainda! É um círculo vicioso! A solução que achamos foi aplicar essa transposição coluna a coluna, uma de cada vez, e fazer análises estanques. Só depois, então, as análises de cada coluna são feitas.

MDX To The Rescue

Bom, MDX é difícil, na prática, mas na teoria, no conceito, é simples: uma expressão literal que manuseia conjuntos multidimensionais.

Falando de outra maneira, é uma linguagem que trata um problema complexo como o que eu expliquei aqui, com muito menos trabalho que toda operação manual.

Por exemplo, o caso inicial – top 3 canais – pode ser descrito como um conjunto formado pela união de três subconjuntos, que por sua vez recebeu uma ordenação com limite.


Eu voltarei ao assunto com um exemplo concreto. Por ora, por favor, tentem visualizar o que estou descrevendo.


Mas e se tivermos, por exemplo, várias perguntas de múltiplas respostas? Não tem importância: comandos MDX, que podem ficar verdadeiramente cabeludos, lidam com conjuntos de membros de uma dimensão (as opções de cada pergunta) e calculam as métricas para aqueles cruzamentos. Comandos que constroem sub-conjuntos podem ser aninhados para montar dois, três, n conjuntos e, em seguida, totalizá-los o apresentá-los como uma matriz – uma planilha.

Complexo? Sim. Pouco intuitivo? É, um pouco. Torna tudo viável? Sim!

Conclusão

Muito de análise multidimensional pode ser feito com um conjunto de dados simples e uma boa ferramenta OLAP. Porém, certos conjuntos de dados representam um desafio muito maior – que nem mesmo um bom trabalho de ETL pode simplificar. Podemos acabar mudando um problema complexo em outro, tão complexo quanto ou mais!

A linguagem MDX, e as tecnologias OLAP associado por trás, como servidor de dados multidimensional, pré-agregadores etc., são uma opção poderosa, geralmente certeira e muito pouco conhecida!

É esse cenário que eu pretendo mudar, daqui para o final do ano.

Até lá, guarde em mente que um analista de dados deve aprender MDX por dois motivos simples:

  • Permite analisar mais dados, mais rapidamente;
  • Simplifica o trabalho de responder uma pergunta a partir dos dados, tornando algo complexo em simples, e tornando em possível o im possível.

Até a próxima! ;-)

 

Anúncios

Ladyvaulk – O Feitiço de Dataváulquila

Faz uns dois anos, e começou assim: minha mão estava coçando para testar Data Vault. Eu tinha feito alguns experimentos, tinha implementado um caso pequeno, mas ainda queria explorar mais. Queria um volume maior, mais complexidade, algo mais difícil.


Cuidado com o que você deseja, porque pode conseguir.


E eu consegui. Quem mandou desejar? Um dos softwares que o SERPRO usa é o Zabbix. Resumidamente, ele server para monitorar ativos, como roteadores, servidores e hubs, coletar métricas do parque informatizado e assim por diante. Consulte a página do projeto Zabbix para saber mais.

Como o SERPRO é uma coisa imensa, tudo está sempre no limite, no máximo, no maior volume, no mais complicado. São milhares de máquinas, dezenas, se não centenas de redes e sub-redes, kilômetros de cabos e tudo mais. Não vou entrar em detalhes técnicos para não correr o risco de falar besteira mas, resumidamente, o povo super-criativo conseguiu botar o esquema todo para a funcionar dentro do que era possível e desejável. Há um vídeo com uma apresentação sobre esse assunto neste link, feita por um dos empregados do SERPRO.

Uma das soluções adotadas passava por uma concentração de dados, que era atualizada periodicamente e servia para apresentar certos dados coletados pelo Zabbix.

Enter Linstedtman!

A pessoa responsável por essa necessidade foi aluna em um dos meus treinamentos de Pentaho, e veio me procurar imaginando se o PDI não poderia ajudar nesse caso. Afinal, consolidar dados é justamente a função dele.

As atualizações precisavam ocorrer a cada 30 minutos, no máximo, ou idealmente a cada 5 minutos ou menos. Apesar do grande espalhamento do sistema, como o volume dos dados capturados era, em si, até modesto, a baixa latência do refresh não era um problema.

O que realmente dava trabalho era a integração dos dados. Poderíamos, por exemplo, modelar os dados em uma estrela dimensional, definindo os atributos de interesse como dimensões e adotar uma fato artificial para correlacionar os dados entre si. Daria certo mas, depois de algumas mudanças nas fontes dos dados, as tabelas dimensionais acabariam ficando complicadas demais. Ou seja, logo no início do projeto daríamos de cara justamente com o ponto fraco da metodologia – a dificuldade de manutenção. Não era uma opção.

Poderíamos simplesmente replicar o layout de origem, mas isso implicaria em capturar os dados em uma granularidade confusa e, de novo, na primeira alteração na origem, quebraria todo histórico.

Não havia alternativa. Eu não queria admitir que estava usando os problemas como justificativa, mas no final, os problemas justificaram mesmo a escolha óbvia.

Usar um Data Vault. :-)

The Curse

Como havia uma certa urgência, trabalhamos em equipe: eu analisava os sistemas de origem para desenhar o Data Vault, e ia tirando dúvidas sobre os conceitos de negócio com os especialistas. Em pouco tempo (duas semanas, se não me falha a memória), foi montado o diagrama de tabelas, os modelos de transformação PDI e, com isso, um processo de ETL completo, de cabo a rabo, saiu do nada.

Como não era um grande volume de dados, a primeira carga levou coisa de uns trinta minutos, um pouco menos que isso. A partir da segunda carga, o processo de ETL terminava em menos de um minuto, graças ao fato de o DV usar CDC para tudo. Quando a rede está muito lenta, leva quase três minutos. Finalmente, por garantia, decidiu-se manter uma latência de 30 minutos (i.e. meia-hora), que dá uma boa margem para falha e recuperação, e ainda atende a necessidade.

E isso tem funcionado nesses últimos dois anos, sem parar, sem falhas, sem soluços, liso como gelo. De vez em quando aparece uma situação nova, e toca lá eu ir atrás de entender como usar Data Vault para resolver.

Um dia destes, batendo-papo e conversando sobre o projeto, a minha ficha caiu.

Sabe, eu não implementei esse lance – eu apenas desenhei um template, um gabarito de transformações para hubs, links, satélites e satélites de links. Nem tampouco desenhei o diagrama de dados: passei as regras de modelagem para a pessoa e deixei-a desenhar sozinha. Eu revisava tudo e corrigia os erros cometidos, mas eu mesmo não pus um dedo no processo de ETL!

É verdade que eu montei a configuração do PDI, configurei a captura de logs de cada transformação, e ainda montei um job que chama tudo. Mas de novo: montei na minha máquina, mandei para o projeto, expliquei como instalar no servidor e não fiz mais nada.

E tudo ia crescendo, ganhando tabelas, coletando dados… E a coisa rodando, e o monstro ficando maior, e maior e novos problemas aparecendo e eu só dizendo o que fazer. No máximo eu examinava os dados remotamente, para descobrir porque isso ou aquilo não estava dando certo, diagnosticava e, quando muito, corrigia os templates. A pessoa do projeto regerava as transformações problemáticas e tudo ia em frente.

Vocês não perceberam ainda né? Eu também demorei:


O projeto foi completamente, totalmente, 100%-mente construído, implementado e está sendo gerenciado por um profissional que não criou nada daquilo.

O projeto foi completamente, totalmente, 100%-mente construído, desenhado e planejado por um profissional que não implementou uma única transformação!


Sacaram? Eu não repeti a mesma frase duas vezes, leiam de novo.

Vou escrever ao contrário e vamos ver se fica mais claro:


O grau de automação do desenvolvimento foi tão grande, e em nível tão detalhado e profundo que a construção do modelo de dados e processo de ETL foi feito por um profissional que ignorava quase que completamente a técnica (DV) por trás.

E mais: a flexibilidade e resiliência da Metodologia de Data Vault é tão grande que foi possível desenvolver tudo – modelo e ETL – entendendo quase nada do negócio!


Nossa ignorância mútua dos problemas um do outro só não era total porque aos poucos fomos pegando partes da coisa – eu entendendo um pouco de Zabbix e o outro lado um pouco de DV e PDI. Mas nunca precisamos explicar nada sobre os detalhes de nada um ao outro!!!!!!!

:-O

Conclusão

Na esbórnia cultural que foi a década de 80, um dos filmes mais aclamados foi Ladyhawk, que contava a história de um casal amaldiçoado por um sacerdote malévolo. A maldição jogada nos dois fazia com que nunca se vissem, a não ser por uns breves segundos ao anoitecer e ao raiar do dia. Esse era o tal “Feitiço de Áquila”, que o nome do lugar: durante o dia a mulher era um gavião, e durante a noite, quando ela voltava à forma humana, o cara virava um lobo.

Preciso pedir perdão a vocẽs, porque foi mais forte que eu. Não deu para resistir.

Eu tive que brincar com isso.

A narrativa épica de um projeto de sucesso na era ágil! Quem projetou o ETL não implementou, e não sabia nada do negócio, enquanto que quem entendia tudo do negócio não sabia nada nem do modelo de dados, nem do ETL que estava  implementando com as próprias mãos (e um monte de processos automatizados!)

Uma equipe que nunca se vê, um projeto conhecido metade por cada um, que ninguém sabe por inteiro! Essa é a história de…

Ladyvaulk – O Feitiço de Dataváulquila!!!

Preciso concluir?? Não é à toa que existem, hoje, ferramentas como Wherescape e Attunity! Data Vault é uma coisa tão bombástica que um só “arquiteto”, como eu, pode cuidar de muitos projetos ao mesmo tempo, cada qual com UM – permita-me frisar: UM! – profissional de dados do outro lado.

AI MEUS SAIS!
AI MEUS SAIS!

Traduzindo: uma equipe de arquiteto mais alguns implementadores pode cuidar de muitos Data Vaults. É uma eficiência simplesmente impensável em qualquer outra metodologia!!

Claro que a realidade não é tão rósea. Para começo de conversa, os dados precisam ser extraídos do Data Vault, preparados e só então consumidos. Isso dá trabalho, mas mesmo assim nem de longe é o mesmo trabalho que dá construir um ETL para um modelo dimensional carregado diretamente a partir da fonte.

É isso. Até a próxima! :-)


Eu rio toda vez que falo Dataváulquila em voz alta. Vamos, tentem! Não me deixem pagando este mico sozinho!… :-D

Data Vault – Satélites?

No post Data Vault – Como Usar  falei um pouco sobre a motivação, conceitos e arquitetura envolvida em um projeto de DW baseado em Data Vault. Um dos meus leitores colocou algumas perguntas muito interessantes, tão interessantes que eu decidi respondê-las em um post exclusivo. Além de ser um meio mais cômodo que um formulário de comentários, é uma forma de agradecer pela participação e mostrar o quanto eu apreciei. ;-) (Sim, eu sou fã dos meus leitores.)

Perguntas, Perguntas, Perguntas

Eis as perguntas colocadas no comentário:

1) Nos satélites, você cita um campo “Load End Date/Timestamp: data e hora do fim da validade daquele registro (default é NULO);”. Neste ponto eu fiquei em dúvida. O ETL para estes satélites poderão realizar operação de update ou não? Ou este campo seria apenas para os casos de atributos que já tiveram uma “vigência fechada” nos OLTP (estou fazendo analogia ao SCD tipo II)?

2) Eu e um colega discutimos se o DV seriam bancos de dados para cada sistema transacional ou todo o DV corporativo estaria em um único banco de dados. Você sugere o DV deveria estar em bancos diferentes? Ou tudo junto? No meu caso, estou falando de SAS e, consequentemente, datasets são tabelas e diretórios são bancos de dados. Então, na falta de um banco relacional como DV, eu inicialmente colocaria todo o DV num “diretório dvault”.

3) Um BD relacional daria conta de manter um satélite gigantesco (algo como muitos atributos/colunas muitas transações/registros por dia)?

Vou responder uma por seção. Vamos lá.

LEDTS vs. SCD2

O ETL para estes satélites poderão realizar operação de update ou não?

Não apenas podem, como devem. Satélites guardam histórico e possuem exatamente o mesmo comportamento de uma dimensão de variação lenta do tipo 2. Ele acertou na mosca!

Hubs e links são tabelas que guardam os conceitos de negócio da organização, e as relações entre esses conceitos. Se algum dia um determinado hub ou relacionamento entre hubs existiu, o Data Vault captura e arquiva essa informação. Satélites, por outro lado, dão o contexto desses elementos.

O Cofre: Coleção ou Caverna?

A segunda pergunta é mais complexa:

Você sugere o DV deveria estar em bancos diferentes? Ou tudo junto?

Bom, por um simples questão de integração, deveria estar tudo junto.

Buraco Negro

Até que ponto pode crescer um satélite?

Um BD relacional daria conta de manter um satélite gigantesco (algo como muitos atributos/colunas muitas transações/registros por dia)?

Bom, o propósito central de um DV é acumular “todo os dados, para todo o sempre”. Logo, precisamos que a estrutura na qual os dados estão armazenados dê conta disso. Se um relacional não consegue, então precisamos recorrer a algo mais elástico. Inmon chamava essa camada de Near Line Storage, que é um armazenamento de alto volume, mas em uma mídia mais econômica. Em troca pelo preço menor por byte e durabilidade maior, a velocidade de acesso seria menor. No caso original, NLS seriam fitas magnéticas.

Conclusão

A conclusão, desta vez, é minha: do comentário e das perguntas eu posso ver que estou deixando algumas lacunas no assunto de Data Vault. Vou levar essa visão em consideração nos próximos posts sobre o assunto.

Até lá! ;-)

Projeto de Sucesso

Eu já escrevi um pouco sobre como projetos de BI “acontecem”. Em Cruel Sucesso eu divaguei sobre a eterna sensação de fracasso que algubs projetos de BI experimentam, mesmo que ele esteja indo de vento em popa. No Todos os Caminhos Levam a um DW eu me diverti escrevendo uma história maluca sobre um projeto de BI fictício, que nasce como uma planilha Excel e cresce como mandiopã, até explodir e voltar ao começo. Mudando o foco para requisitos, eu discorri sobre Ágil e BI (De Agilidade e BI), para descaradamente anunciar meu curso de requisitos de BI para gestão ágil.

Quase sempre esses posts vem do nada, motivados por alguma situação pela qual passei. Eu estava com o novo fascículo da série Soluções Clássica quase pronto (Credit Scoring), mas aconteceu de novo: me meti num debate sobre o que era um “bom” projeto de BI.

Bom, eu tenho uma idéia do que deve ser um. Vou dividir com vocês a opinião que eu coloquei no debate, mas já sabem, né?


Disclaimer: o que você vai ler é a minha opinião, logo você não é obrigado a gostar dela ou concordar. Terei prazer em ouvir críticas ou outras opiniões, mas no final – como diz o Homer Simpson – a opinião é minha e faço com ela o que quiser, certo?


Sucesso Não Existe

Primeiro, não existe mundo perfeito. Não adianta sonharmos com a próxima grande ferramenta para resolver nossos problemas, porque o melhor que pode acontecer é resolvermos os problemas atuais e caírmos em novos. O que faz a diferença, na minha humilde opinião, é evitarmos empacar. Se empacamos, o projeto começa a fazer água, e quanto mais tempo demoramos para resolver o problema da vez, menos relevante o projeto de BI se torna, até que um dia todo mundo está se virando sozinho e o projeto é mantido vivo apenas com auxílio de aparelhos.

O que torna um projeto bom, de sucesso, então, é o fato de ele estar sempre em movimento, resolvendo cada problema como um corredor salta obstáculos: pula, corre, pula, corre, pula, corre… Eventualmente, um dia a coisa toda entra em velocidade de cruzeiro, a quantidade de erros cai substancialmente e a empresa desenvolve uma cultura de BI. Esse é o projeto de sucesso: falível, sempre precisando de alguma melhoria, mas que entrega resultados e é acreditado pela organização, sustentado pela cultura de conhecimento da empresa.


Um projeto de BI de sucesso, IMHO, é aquele que resolve um problema atrás do outro, sempre entregando um pouco mais de resultados a cada etapa, capaz de suplanta as próprias limitações e ir ao encontro das expectativas do cliente.


O Caminho para o Sucesso

Ora, dirão vocês, bolas. A definição acima é uma rematada platitude: não diz nada de realmente útil ou prático. Concordo. Vamos escrevê-la ao contrário para ver se fica mais claro:


Fracassa o projeto de BI que persistir em trilhar caminhos sem saída.


Consegui me fazer entender? Quando optamos por este ou aquele caminho, corremos o risco de enveredar por uma rua sem saída. Projetos – de qualquer tipo – que reiteradamente optam por entrar em becos sem saída acabam morrendo porque, cedo ou tarde, a organização se cansa de tanto vai-e-vem! Quer seguir no caminho para o sucesso? Esforce-se por evitar decisões ruins!

Decisões, Decisões, Decisões

Devo ter engolido o grilo falante quando era criança, pois eu sempre escuto uma voz fininha, tirando onda com a minha cara. Desta vez ela disse “Intelijumento! Se soubéssemos que decisão vai dar errado, não a tomaríamos! Dã!”

Óbvio, claro, não se questiona isso. É a própria essência do processo decisório, é a meta personificada de se fazer uma escolha: fazer a escolha certa!

Como saber se uma opção, e não a outra, é a correta? Ah, de muitas formas. Em alguns casos estamos passando pelo mesmo problema uma segunda vez. Se da primeira fizemos a escolha certa, tendemos a repeti-la, e vice-versa: deu errado antes? Vamos tentar outra coisa. Em outros casos não conhecemos, ainda, as consequências de cada caminho, mas podemos avaliá-las com o que estivar à mão – opiniões, análises estatísticas, jogar cara-ou-coroa – e escolher a que parece melhor.


Em último caso, recorra a um taxista: eles sempre sabem o que os outros deviam fazer. ;-)


O Que Funciona?

E aqui chegamos no ponto em que eu queria: o que funciona em um projeto de BI? Como montar um projeto que vai empacar menos?

Armazéns de Dados

Um bom DW é fundamental para qualquer projeto de BI de sucesso. Você pode se virar com dumps, ODFs, Data Lakes, mas esses caminhos são becos sem saída: cedo ou tarde o peso da falta de integração dos dados (dumps e Data Lakes) e das manutenções de modelo e ETL (ODFs e EDW Dimensional) vão afundar seu projeto – mesmo que todo o restante funcione.

Logo, lição número um: monte um bom projeto de DW, capaz de incorporar novas fontes num estalar de dedos e de produzir novas apresentações de dados em dois palitos. Quem acompanha meu blog já sabe o que isso significa: Data Vault.

Equipes

Ferramentas são importantes, mas não são nem metade da solução. Problemas são resolvidos por pessoas com conhecimento e competência para aplicar ferramentas, não pelas ferramentas. E outra: muito ajuda quem pouco atrapalha – gerente bom é gerente quietinho, que serve a equipe, ajudando a remover obstáculos.

Processos

Há dois grupos de processos dentro de um projeto de BI, especificamente:

  • Processos de Desenvolvimento;
  • Processos de Atendimento.

O primeiro é batata: é o processo pelo qual a equipe (parte dela, na verdade) mencionada acima produz os resultados requisitados pelo cliente.

O segundo processo é virtualmente ignorado pela comunidade de praticantes de BI: é o processo pelo qual a outra parte da equipe apóia o cliente. Sim! É o time de “vendedores”, instrutores e tutores, que trabalham com o cliente para entender o que ele precisa e transformar isso em requisitos, que serão tratados pelos desenvolvedores; que ajudam cada novo usuário a aprender a usar as ferramentas e os dados do projeto. O tutor é uma figura inexistente na literatura, mas pode ser visto como um instrutor particular, que vai resolver o problema do usuário uma primeira vez, e ajudar o usuário a repetir esses passos. Ele é diferente do instrutor, que ensina a usar o que está pronto. O tutor cria coisas novas – novas práticas, novos usos dos dados, novos requisitos.

Processo de Desenvolvimento

Não tem segredo: waterfall [bigbang][bigbang_bitly] não funciona, ponto final. A única forma de gestão de projetos que dá certo é Ágil, e neste ponto Scrum é o meu preferido.

Processo de Atendimento

De novo, não tem segredo: um grupo de vendedores (ou evangelistas/analistas de requisitos) e apoiadores (instrutores e tutores) expostos exaustivamente, com uma mensagem clara: Precisa de dados? Me ligue!. Eles interagem com o processo de desenvolvimento alimentando novas histórias no backlog (para os vendedores), com o cliente por meio de chamadas de suporte (tutores/suporte técnico) e com a empresa por meio da capacitação corporativa.

Soluções

Todo projeto de BI usa quatro tipos de soluções:

  • Apresentações;
  • Relatórios;
  • OLAP;
  • Data Mining.

As três primeiras são baseadas em ferramentas, e portanto são resolvidas pela incorporação de profissionais das respectivas ferramentas ao time. Já a última é tratada como uma conjunto de projetos-filhos e raramente é tratada in house. O normal, para soluções que envolvem Data Mining, é contratar uma empresa especializada no assunto desejado.


E os painéis? Painel não é solução de BI, é ferramenta de (tcham-tcham-tcham-tcham-tcham!) apresentação de dados (e não, não é ferramenta de análise! Quem analisa é OLAP e Data Mining.) Logo, você pode ler o primeiro item da lista acima como “dashboards“. Porém, há muitas formas de se apresentar dados e eu evitaria fechar esse escopo prematuramente, jogando tudo na vala comum “painel”.


Um bom projeto de BI precisa incorporar essas categorias, sem exceções. Não precisa oferecer tudo ao mesmo tempo, desde o dia 1, mas deve garantir que o roadmap vai contemplá-las ao longo do caminho. Como conseguir isso? Tente incluir no seu time um generalista de BI, aquele cara que entende um pouco de tudo, e sabe como os assuntos se interconectam, como amadurecem ao longo do ciclo de vida do projeto.

Se você não puder contar com um membro permanente, aceite um membro flutuante, como um coacher, por exemplo. Se não existir na empresa, procure um consultor externo. Raramente um profissional desse cresce durante um projeto de BI, e você só vai achar um na sua empresa, à sua disposição, por pura sorte.

Conclusão

Então vamos lá: um bom projeto de BI é composto por um time multi-disciplinar (especialistas em ferramentas de ETL, apresentação e exploração de dados), com uma equipe voltada para o atendimento do cliente (esqueça a idéia de ter “self-service 100%”) e outra voltada para uma linha de produção de soluções. Na entrada dessa linha está um DW baseado em Data Vault, no meio as áreas de dados para consumo e na ponta as ferramentas de uso dos dados (apresentação, relatórios e OLAP.) Pipocando aqui e ali aparecem os sub-projetos de Data Mining, tocados normalmente por consultorias externas e nascendo de necessidades pontuais. Essa visão geral pode ser melhor organizada por um generalista.

Nenhuma destas idéias é minha, e isso em parte me dá confiança nelas: Bill Inmon chama esse modelo de CIF, o inglês para Fábrica de Informações Corporativas.

Diagrama da Fábrica Corporativa de Informações.
Diagrama da Fábrica Corporativa de Informações.

Outro nome para essa abordagem é BICCBusiness Intelligence Competence Center. Veja este artigo para uma discussão mais detalhada do conceito.

Não é um BICC, mas dá uma idéia de como funciona a tal "linha de produção".
Não é um BICC, mas dá uma idéia de como funciona a tal “linha de produção”.

O restante da minha confiança nesse modelo nasce de eu ter experimentado tudo isso: Data Vault, Scrum, Data Mining, OLAP, Relatórios, equipes proficientes etc. etc. etc. Eu vi projetos de BI fracassarem ao descuidar desses fundamentos, como também vi projetos de BI que estão vivos até hoje, alguns zumbis, outros mancando, mas em operação. Se os que dão certo trazem pistas do que pode ser o mais importante, ou o que dá resultados, os que se arrastam, semi-mortos, são os mais valiosos para entender como e porque as coisas dão errado.

É isso, até a próxima. ;-)

Data Vault – Como Usar

Um dos leitores do blog deixou este comentário em 18/5/16:


Fábio, gostaria de mais instruções sobre o data vault, como aplicar, onde aplicar e como é sua modelagem e arquitetura.


Prometi a ele que o próximo post responderia essa questão. Então aqui está: Data Vault, uma visão geral sobre onde aplicar, como modelar e em que arquitetura colocá-lo.

Do Começo, Por Favor

Data Vault é uma metodologia de desenvolvimento de Armazém de Dados Corporativo (do Inglês EDW), que inclui modelagem e processo de ETL. A versão 1.0 parava aí, já a 2.0 vai adiante, até a camada de apresentação dos dados.

Essa técnica foi inventada e desenvolvida por Daniel Linstedt para um projeto na mítica Lockheed Martin, que faz (fazia?) o mítico Blackbird SR-71, o avião dos X-Men. Baixe a amostra do Building a Scalable Data Warehouse with Data Vault 2.0 e leia o prefácio (do mítico Bill Inmon – isso aqui tá um templo grego de tanto mito!!) para ver essa história.

Perdão, mas eu precisava colocar isso aqui.
Perdão, mas eu precisava colocar isso aqui.

Aplicando Data Vault podemos desenvolver um Armazém de Dados com baixo custo, alta produtividade, baixo retrabalho, com processo de ETL de alta performance e altíssimo MTBF.

Volte Mais!

E porque precisamos de um Armazém de Dados mesmo? Bom, não é o assunto deste post, mas aqui vai, resumidamente:


No fundo, não “precisamos” de DW. Precisamos é armazenar a evolução dos parâmetros da empresa ao longo do tempo. Podemos fazer isso de várias formas: um estagiário anotando valores em um papel de pão, ou uma planilha Excel, ou dumps de bases em um cluster Hadoop. Ocorre que, por acaso, DW é a tecnologia adequada para isso.


Leia meu post Um Ponto Fita o Mundo para ver o argumento inteiro.

Vamos continuar?

Por Quê Adotar DV?

Todo EDW cumpre duas funções básicas:

  • Puxa dados dos vários sistemas da empresa para um repositório central;
  • Integra os dados dos diversos sistemas em uma visão abrangente.

Um EDW precisa puxar os dados de todos os sistemas porque qualquer se não olharmos em todos os dados da empresa nunca teremos a certeza de termos investigado tudo que há para ser examinado. É como perguntar que livro sumiu da biblioteca: só olhando todos vamos saber qual não está lá. Se o gerente financeiro pergunta “quais são todos os gastos da empresa”, precisamos olhar tudo!

Pense: se sua empresa tiver dois sistemas em MySQL, um em SQL Server, um em Postgres e outro em Oracle, como escrever um SQL que percorra todas essas bases? Não dá, não é? Os dados precisam estar em um repositório centralizado por simples limitação das atuais tecnologias de banco de dados: como em geral usamos SQL para fazer essas pesquisas, e um SELECT não consegue consultar – ao menos não de maneira fácil – dois ou três ou mais bancos de tecnologias diferentes ao mesmo tempo.

Os dados precisam estar integrados, o que significa bater os CPFs 012345678-00 com 1234567800. Quando puxamos um relatório do cliente 012.345.678-00 precisamos que ele seja identificado em todos os sistemas, não importando se na origem ele aparece como 1234567800, 012345678-00, 012.345.678-00 ou de qualquer outra forma. Dados não-integrados fornecem respostas erradas. Sem integrar os dados, seu DW não vale o HD no qual está gravado.

Há várias técnicas para construir um DW atendendo essas duas obrigações:

  • Copiar tudo da origem, mantendo os mesmos modelos, e integrar na hora de fazer a consulta. Frágil, trabalhoso e pesado (consome muita máquina;)
  • Copiar tudo da origem, gravando em um novo modelo na Terceira Forma Normal. Mais robusto e de melhor performance que o anterior, mas de evolução e manutenção tão difícil que beira o insano;
  • Copiar a origem em um novo modelo, como no item anterior, mas em um Modelo Dimensional. Não tão robusto, mas de boa performance, com evolução e manutenção práticas e simples no começo, mas tendendo à impossibilidade de manutenção e evolução com o tempo.

E finalmente, o Data Vault, que não sofre de nenhum destes problemas e tem todas as vantagens. Resumindo em figuras:

Os impactos das mudanças na arquitetura tradicional.
Os impactos das mudanças na arquitetura tradicional.
Os impactos das mudanças, agora no arquitetura com DV.
Os impactos das mudanças, agora no arquitetura com DV.

Só para ficar claro: por “nenhum impacto aqui”, no último quadro da figura acima, eu quero dizer “nenhum impacto de manutenção”, já que, obviamente, pode ser preciso criar algo novo. Não haverá impacto no que existe, não será necessário mudar nada.


Adotar Data Vault como metodologia para desenvolvimento de um DW vai evitar os problemas que costuma comprometer os DWs da 3FN e Dimensionais.


Hoje vamos deixar só com essa afirmação, porque este é um post de visão geral, mas você pode seguir os links apresentados até agora para ler o (extenso) argumento explicando porque é assim.

Como Aplicar?

De fato, não há segredo na aplicação de Data Vault. A técnica meio que se resume em:

  • Quebrar o trabalho em “histórias”: quero medir isso, quero analisar aquilo;
  • Daí, para cada uma:
    • Identificar as tabelas na origem que respondem essas perguntas
    • Expandir o modelo de dados do DV com hubs, links e satélites;
    • Gerar automaticamente ETL de carga do DV;
    • Desenhar o ETL para a área de apresentação.

Existem padrões e técnicas para cada atividade, e a metodologia casa-se como uma luva à gestão ágil. Meu método preferido é o Scrum, e chega a ser surpreendente ver como DV adequa-se tão perfeitamente ao Scrum.


Veja meu post De Agilidade e BI para alguns comentários sobre o levantamento de requisitos para projetos ágeis.


Como É a Arquitetura?

Você já deve ter intuido a forma geral da arquitetura em uma das figuras anteriores. Reorganizando e renomeando as partes daquela figura temos uma visão mais clara:

Arquitetura Data Vault.
Arquitetura Data Vault.

Ou seja:

  1. Um ETL (gerado automaticamente) traz os dados de cada origem;
  2. Um banco de dados (preferencialmente relacional, mas um Hadoop does too) recebe e, graças ao modelo de dados do DV, integra tudo “na entrada”;
  3. A partir deste banco um segundo processo de ETL popula as soluções;
  4. Essas soluções podem ser de todo tipo: análises multidimensionais (OLAP), Data Mining (CRM etc.), painéis, relatórios etc. etc. etc.

Cada uma destas soluções após o segundo ETL têm suas arquiteturas particulares. No fundo a arquitetura de um DV são dois ETLs com um banco com modelo de dados DV no meio, mais nada. A partir daí, tudo fica igual à qualquer outro projeto de BI.

Modelagem

A modelagem de um Data Vault é relativamente simples, e você pode ler um pouco mais sobre ela neste post. Grosso modo, porém, resume-se ao seguinte:

  • Identificar chaves de negócio e criar hubs;
  • Encontrar relacionamentos entre chaves de negócio e criar links;
  • Escolher os atributos de hubs e links e criar os satélites.

Hubs

Hubs são tabelas que guardam conceitos, ou chaves, de negócios. Uma chave de negócio é um conceito importante para a empresa: cliente, produto, pedido, posição no call center, empregado, etc.

Tabelas hub possuem as seguintes colunas, nem uma a mais nem a menos:

  • Business Key: chave primária, um inteiro sequencial;
  • Load Date/Timestamp: data e hora da inserção do registro;
  • Record Source: fonte da chave de negócios;
  • Source business key: chave de negócio no sistema de origem.
Uma tabela hub.
Uma tabela hub.

Não há grandes segredos aqui: tabelas hubs acumulam as chaves de negócio, que são a espinha dorsal do modelo. A chave primária é a BK. A cada carga insere-se apenas as novas chaves de negócio dos sistemas de origem. Se a chave já existe, nada é feito. Se a mesma chave existe em vários sistemas, apenas a primeira que chegar é inserida.

Links tão tabelas que guardam o relacionamento entre dois hubs. Uma tabela link que relaciona os hubs 1, 2, … , n possuem as seguintes colunas, nem mais, nem menos:

  • Link Key: chave primária, um inteiro sequencial;
  • Load Date/Timestamp: data e hora da inserção do registro;
  • Record Source: fonte do relacionamento;
  • BK1: business key do hub 1;
  • BK2: business key do hub 2;
  • BKn: business key do hub n.
Uma tabela link.
Uma tabela link.

Ela também não sofrem atualização: novos relacionamentos são inseridos, antigos são ignorados. Se um relacionamento já registrado não é mais detectado, ele não é apagado.

Satélites

Satélites são como tabelas de dimensão: guardam os contextos de hubs e links. Uma tabelas satélite de um hub/link que guarda os atributos A1, A2, … , An de um hub/link X possui as seguintes colunas, nem mais, nem menos:

  • Business Key/Link key: chave primária do hub/link
  • Load Date/Timestamp: data e hora da inserção do registro;
  • Load End Date/Timestamp: data e hora do fim da validade daquele registro (default é NULO);
  • Record Source: fonte dos atributos;
  • A1: atributo 1;
  • A2: atributo 2;
  • An: atributo n.
Uma tabela satélite.
Uma tabela satélite.

Modelo Completo

A coleção dessas tabelas e seus relacionamentos dão o modelo completo:

As tabelas combinadas no modelo.
As tabelas combinadas no modelo.

A etapa seguinte é construir o ETL para dentro do DV, e depois do DV para a camada de apresentação/consumo de dados.

ETL

Um DV possui duas vantagens “matadoras”: integração dos dados no modelo, ao invés de no ETL como é o mais comum, e um ETL padronizado. Graças à essa padronização o ETL de um DV inteiro pode ser gerado automaticamente: a partir de alguns gabaritos de SQL podemos construir o processo que lê e grava todos os hubs, links e satélites.

Eu sempre uso o Pentaho Data Integration (PDI) para processos de ETL, e meu curso de DV entrega ao aluno um gabarito de projeto completo – é só tirar da caixa e usar. A última versão dele traz até os SQLs para criar as tabelas no Data Vault.

Isso para o primeiro ETL, para dentro do DV. O segundo ETL, saindo do DV para a camada de apresentação, é mais particular, e não há como automatizar sua geração. Por outro lado, como todos os pontos de partida não são mais os sistemas de origem mas sim o DV, a “forma” geral desse segundo processo é mais uniforme, e alguns padrões acabam por facilitar seu desenvolvimento.

Por exemplo, dimensões são quase sempre construídas a partir de um hub e seus satélites, e tabelas fatos originam-se de links. Construídos os SQLs que lêem isso no DV (e nisso eles seguem um padrão de JOINs bem cadenciado), o passo seguinte é fazer trocas de chaves naturais por delegadas e, em caso de necessidade, limpar os dados.

Conclusão

Adoro quando um leitor pede algo, pois escolher o tema do próximo post, para mim, é como escolher roupa para sair: muito, muito difícil – e se não gostarem? e se ficar ruim? e se eu falar besteira por saber pouco? E se?…

Vimos que um Data Vault é uma metodologia que habilita a realização da visão de Bill Inmon, a Corporate Information Factory. A [CIF][cif_bitly] (até o advento do DV, outro mito) é como uma linha de produção, que ingere todos os dados da empresa e “fabrica” produtos de dados conforme as necessidades vão surgindo.

Data Vault é uma metodologia composta por uma modelagem, um processo de geração automática de ETL e outros elementos (como padrões e nomenclaturas.) O EDW se completa com um segundo processo de extração, que leva os dados para as áreas de apresentação, em formato dimensional ou não. Tudo em um processo de desenvolvimento que nasceu para ser tocado com gestão ágil (Scrum, na minha preferência), boa parte automatizada e com baixo ou nenhum retrabalho.


Não deixe de ver o post As Vantagens do Data Vault para mais sobre como um DV pode ajudar seu projeto de EDW.


É claro que nada é 100% a prova de falhas, defeitos ou problemas e eu mesmo já enfrentei minha cota de surpresas, dificuldades e maluquices nesse caminho que venho trilhando há alguns anos. Mesmo assim, hoje em dia, um Data Vault é a coisa que mais se aproxima de um método perfeito.

Fora essa babação no final, acredito que era isso. ;-)

As Vantagens do Data Vault

Semana passada, 6/5/16, eu assisti uma palestra sobre uma empresa chamada Attunity, e suas ferramentas para Business Intelligence. Vendo as promessas do representante brasileiro eu me dei conta de que já escrevi bastante sobre DV, mas nunca escrevi especificamente sobre as vantagens trazidas pela adotação de Data Vault. Vamos corrigir isso hoje, partindo desta apresentação.


Você pode pular direto para a lista de vantagens clicando aqui.


Uma Nova Categoria

Estamos em 2016 e já lá se vão cerca de 40-50 anos desde que Bill Inmon começou o debate sobre Armazéns de Dados, e 24 anos desde seu livro Building the Data Warehouse. Muita água passou embaixo da ponte e todas suas idéias estão sedimentadas, firmes, sobre as quais se assenta a moderna indústria de DW. Um destes conceitos é a Corporate Information Factory, que agrupa as fontes de dados e seus consumidores como uma linha de produção.

Diagrama da Fábrica Corporativa de Informações.
Diagrama da Fábrica Corporativa de Informações.

Tal qual a revolução industrial fez com a manufatura, graus de automação sucessivamente maiores estão acelerando e simplificando o desenvolvimento, manutenção e gerenciamento de Data Warehouses. Instrumental para essa revolução foram tecnologias aparentemente irrelevantes, como modelos de dados e metodologias de desenvolvimento.

Metodologias como Scrum, Continuous Integrations e DevOps agem para diminuir a intervenção e variabilidade da ação humana, enquanto que outras, como Modelagem Dimensional e Data Vault, domam a confusão dos sistemas OLTP e permitem a criação de algoritmos. E é justamente essa criação de algoritmos que permite automatizar o processo de desenho, desenvolvimento e manutenção de DWs.

Uma nova categoria de ferramentas brotou desse fértil ambiente: ferramentas de automação de gestão de DW. Ainda não vi esse ramo ser tratado por um acrônimo, nem mesmo ter um nome mais comum, mas acho que, em Inglês, seria algo Data Warehouse Management Solutions, ou DWMS. Já sabem: se virem por aí, apareceu no GeekBI primeiro. ;-)

Continuando, essa categoria já tem alguns nomes internacionais:

Fazia tempo que eu não visitava o BI Ready, empresa de Ian Nicholson com quem já troquei umas idéias no LinkedIn. Surpresa! Ela foi adquirida pela Attunity e agora são um nome só. Não é à toa que, na apresentação, a Attunity declarou pertencer a essa turma – ela comprou “metade” das empresas dessa área!

Esse é o Ian Nicholson, fundador da BI Ready, fazendo a mesma cara que eu faria se tirasse essa foto.
Esse é o Ian Nicholson, fundador da BI Ready, fazendo a mesma cara que eu faria se tirasse essa foto.

Processos e Problemas

Um projeto de DW que hoje é chamado de “tradicional” (i.e., feito com metodologias de mais de 15 anos atrás) envolvia as seguintes etapas:

  1. Levantar os requisitos;
  2. Estudar os dados de origem;
  3. Desenhar o modelo dimensional;
  4. Desenhar o processo de ETL;
  5. Colocar em produção;
  6. Dar manutenção: propagar as mudanças dos sistemas de origem e adequar às novas necessidades do cliente.

Esse projeto em geral era tocado dentro de uma moldura PMI (a.k.a. Waterfall). Era um método tão certeiro e determinístico que até hoje todo mundo sabe que, feito assim, sempre falha.

Os problemas de um DW 'clássico'.
Os problemas de um DW ‘clássico’.

DW feito por cópia dos bancos de origem é a pior escolha possível, a menos que seja para uma padaria, uma farmácia, uma banca de jornais etc. ;-) Veja que não estou falando de palco (stage), mas de montar o DW como uma coleção de réplicas. Um modelo dimensional é o mínimo necessário para sobreviver aos problemas que serão apresentados ao final desta seção.


Com o advento do Manifesto Ágil e Data Vault, um projeto de DW moderno é tocado assim:

  1. Levantar os requisitos da próxima entrega (30 dias;)
  2. Estudar os dados de origem até encontrar o estritamente necessário para próxima entrega;
  3. Desenhar o DV;
  4. Gerar automaticamente o processo de ETL;
  5. Derivar dados para apresentação;
  6. Colocar em produção e reiniciar o ciclo.

A manutenção é incorporada nas sprints.

Veja que, grosso modo, o processo em si não mudou muito: de projeto waterfall passamos para Scrum, de modelo Dimensional no miolo do DW passamos para um Data Vault e o ETL principal é gerado automaticamente.

Os problemas que existem (existiam e vão continuar existindo) são:

  1. Integração: sem integrar e limpar 100% dos dados, todas as respostas são suspeitas. Ou você confiaria nos números sabendo que algo pode ter ficado de fora?
  2. Historiamento: não adianta montar um armazém que não guarda histórico. Fazer isso é cuidar de dados operacionais e jogar a água fora com o bebê – o maior valor dos dados está no histórico;
  3. Mudanças na origem: sistemas transacionais representam os processos que a empresa executa. Se a empresa muda, forçosamente os OLTPs precisam mudar, e o DW vai ter que ser adequado, sempre;
  4. Performance de ETL: a menos que a empresa esteja definhando, ela sempre vai crescer, sempre vai querer mais dados. O hardware para ETL sempre acaba ficando obsoleto, por um motivo ou outro, cedo ou tarde. O truque é extrair tudo que ele pode dar, e não desperdiçar nada;
  5. Velocidade de mudança: por fim, em cima de todos os problemas apresentados, temos o fato de que as coisas não estão ficando mais calmas, mais lentas, e sim mais rápidas, com mais demandas e mais complexidade.

Ferramentas…

As novas ferramentas de automação de DW se propõem a resolver esses problemas.

O Attunity propõe resolver um DW em dois passos:

  1. Usando o Attunity Replicate os dados são trazidos de diversas fontes de dados para um repositório centralizado;
  2. Daí, com o Attunity Compose, um DW é desenhado e carregado automaticamente.

Há um bom grau de magia negra envolvida (=coisas que acontecem sem entendermos claramente como), mas tudo faz um bom sentido. O Replicate se conecta aos bancos de dados de origem e fazem uma engenharia reversa total. Com essas informações ele vai ao banco de destino e recria o banco de origem, respeitando as diferenças de tecnologias. Por exemplo, ele pode replicar bancos MS SQL Server e Oracle para dentro de um único Postgres. Depois ele faz uma transferência inicial, em que replica as origem(ns) inteira(s) no(s) destino(s). A partir do final desta carga, o Attunity Replicate passa a ler o log de commits dos bancos de origem e replicar no destino, em tempo real.

Quem leu meu post Analítico ou Operacional? sabe que essa replicação não é um DW, e que fazer isso “não é BI”.

A Attunity também sabe, e dá o passo final em direção ao DW através do Compose. O que essa ferramenta faz é mais magia negra que a outra:

  1. Através de engenharia reversa e algoritmos especiais, o Compose “descobre” os relacionamentos entre as várias colunas de todas as tabelas das origens;
  2. Usando esse conhecimento, a ferramenta monta um DW – desenha um modelo de dados – automaticamente;
  3. Em seguida constrói (sempre automaticamente) o ETL para esse DW;
  4. Na última etapa ele monta uma área de apresentação de dados, seguindo indicações de que dados o cliente quer explorar.

A ferramenta ainda permite customizações e correções feitas pelo time de DW, de modo que qualquer interpretação incorreta pode ser ajustada.

Ou seja, ele automatizou 100% do processo moderno de desenvolvimento de DWs!!!! E digo mais: !!!!. Mas não pára por aí:

  • Esse DW guarda histórico;
  • A área de apresentação pode expor estrelas multidimensionais, com até mesmo SCDs tipo 2;
  • Ele detecta mudanças nas origens e ajusta o DW e o ETL;
  • Todas essas ferramentas são clusterizáveis, ou seja, podem ser escalonadas horizontalmente.

Isso são coisas que ouvi ou que perguntei durante a apresentação. Há coisas que eu não perguntei, mas presumo que também estejam no pacote, como tratamento de erros de ETL e monitoramentos diversos. Aliás, a parte de monitoramento é muito bacana, também – aprendi um negócio chamado “hot data, cold data”, sobre o qual vou fazer uns experimentos e, eventualmente, vou postar sobre.

… e Soluções

E como o Data Vault se encaixa nesse cenário? Simples: ele oferece tudo que as ferramentas oferecem, sem o custo monetário. Digo monetário explicitamente porque não existe almoço grátis, sempre precisamos pagar por algo. Se não é em dinheiro, vai ser em treinamento e capacitação, por exemplo, ou simplesmente mais trabalho.

DW 'moderno', re-organizado segundo DV.
DW ‘moderno’, re-organizado segundo DV.

Eis a lista de vantagens (ou problemas resolvidos) trazidos pela adoção de Data Vault no miolo do EDW:

  1. Velocidade de desenvolvimento: usar DV corta o tempo necessário para desenvolver e entregar em algumas ordens de grandeza. Por exemplo, coisas que levariam meses saem em dias;
    1. Modelo de dados: o diagrama de dados do Data Vault é construído através de regras simples, que capturam o negócio no modelo. Assim, uma vez que tenhamos a lista de esquemas, tabelas e colunas do sistema de origem, o ato de desenhar um DV é trivial e leva algumas horas, contra algumas semanas de outros formatos;
    2. Processo de ETL: usando o Pentaho Data Integration, o processo de ETL é gerado automaticamente, a partir do modelo elaborado anteriormente. Ainda é preciso juntar as partes (as diversas transformações) dentro de um job (pré-fabricado), mas isso é uma tarefa de minutos. O ETL inteiro sai em menos de um dia;
  2. Integração: o modelo de dados do Data Vault já arquiva os dados de maneira integrada. Ou seja, a integração ocorre via modelo, no momento em que os dados aterrisam no DV;
  3. Historiamento: 100% dos dados de um DV são historiados, automaticamente e por definição;
  4. Mudanças na origem: evidentemente não são tratadas automaticamente – um software pode fazer isso, não uma metodologia. Entretanto, esse impacto é mínimo:
    1. Qualquer mudança na origem não quebra o processo de ETL, ao contrário de DWs baseados em outros modelos;
    2. Mudanças na origem são resolvidas por um algoritmo simples, e qualquer manutenção leva praticamente o mesmo tempo de repetir o desenvolvimento (horas ao invés de semanas, portanto;)
    3. Nenhuma mudança na origem quebra a área de apresentação. A área de apresentação é reformada apenas em casos que afetem-na. Graças a esse fato, o impacto sobre a área de apresentação causada por mudanças nas origens é de mínimo a inexistente;
  5. Performance de ETL: várias vantagens ao usar um DV;
    1. Alta velocidade: por tratar apenas deltas (i.e., as diferenças) por meio de comparações simples, o processo é muito rápido;
    2. Paralelização: graças ao formato do ETL, todas as operações podem ser maciçamente paralelizadas, possibilitanto uso de hardware barato (COTS;)
    3. Resistente a erros: o ETL de um DV é auto-reinicializável por definição, e só é interrompido por falhas graves (hardware ou dados muito corrompidos;)
  6. Velocidade de mudança: é a mesma da velocidade de desenvolvimento – muito rápida.

Como vantagem extra, pelo fato de DV permitir atacar o problema por pedaços, ele se presta à:

  1. Modularização em sprints;
  2. Paralelização do desenvolvimento.

Por ser baseado em processos automatizados e algoritmos, a quantidade de erros é substancialmente menor, gerando projetos de qualidade maior, e mais padronizado.

Conclusão

Já há alguns anos a indústria de BI vem incorporando tecnologias que habilitam novas soluções de problemas complexos, como a construção, gerenciamento e manutenção de Armazéns de Dados. Essas tecnologias surgem como técnicas/metodologias e softwares.

Um software representante desta nova categoria é o Attunity, especificamente os módulos Replicate e Compose. O primeiro copia dados de diversas origens para um mesmo (ou vários) destino(s). O segundo modela um DW e cria o processo de ETL automaticamente a partir da réplica. Não sei com que qualidade, precisão e velovidade o Attunity entrega os resultados, mas a promessa é fantástica, para dizer o mínimo.

Esse produto é resultado de evoluções anteriores. Uma destas é a metodologia Data Vault, que oferece essa lista de vantagens:

  1. Alta velocidade de desenvolvimento: entrega em dia o que levava meses;
  2. Processo de ETL gerado automaticamente – maior velocidade, qualidade e padronização, com menos erros;
  3. Integração: dados são integrados na entrada;
  4. Historiamento: 100% dos dados de um DV são historiados;
  5. Mudanças: resiliente a mudanças na origem, processo de ETL não pára e impacto global (tanto ETL quanto usuários) é de mínimo a irrisório;
  6. ETL de alta performance, imune à erros, restartável e 100% paralelizável (é possível executar simultaneamente todas as etapas da carga do DV;)
  7. Adequado à processos de desenvolvimento ágil;
  8. Desenvolvimento do modelo (dada ferramenta adequada) e do ETL paralelizável.

Com um Data Vault podemos obter os mesmos resultados prometidos pelo Attunity, com menos automação, e com um custo diferente (menor?)

Clicando aqui você vê a lista dos meus posts marcados com Data Vault. Eis links para alguns do meus posts sobre o assunto:

E se você quiser ler sobre o assunto, o livro é este:

Livro sobre Data Vault.
Livro sobre Data Vault.

Só para não deixar vocês pendurados: eu ofereço os dois cursos, Requisitos Ágeis e Data Vault. Fazer essa propaganda dá impressão que eu montei um post para me auto-promover, mas juro que não é o caso deste aqui. Acredito no valor que esses cursos agregam e sentiria que estaria prejudicando você, meu leitor, ao evitar contar que eles existem. Quem me acompanha sabe que quando eu vou vender algo aqui, eu aviso no começo. ;-)


Até a próxima!

Balanced Scorecard & BI

A teoria do Balanced Scorecard por Norton e Kaplan, ou BSC para os íntimos, teve um impacto significativo no mundo do BI. Talvez, aliás, seja essa a raiz da mistura corrente entre OI e BI. Eu estava lá quando isso estava acontecendo, e vou dividir com vocês um pouco das minhas histórias sobre aqueles dias loucos.

O Mundo Até Então

Até meados do ano 2000, o top em BI de usuário era um DSS conhecido pelo acrônimo EIS, de Executive Information System. O EIS era composto por um DW e uma ferramenta OLAP, organizados de tal forma que um executivo poderia enxergar a empresa inteira a partir do topo, da maior agregação, e descer, seguindo o caminho que desejasse, até o nível mais baixo, da linha.

Assim, por definição, todo executivo ganhava o seu centro de controle ou painel de monitoração empresarial. O apelo do sistema é que ele dispensava o usuário de conhecer programação de qualquer tipo, pois um EIS era voltado para o nível gerencial, o nível tático-estrégico da organização.

Ao redor do EIS haviam uma gama de opções, entre produtos e soluções.

Por exemplo, o usuário poderia pedir um gerador de relatórios (um produto), para construir as listagens que bem entendesse, e quando desejasse. Ganhou alguma notoriedade, nesta época, o slogan “entregar o dado certo, no momento certo, para a pessoa certa”.

E haviam as soluções de BI (e ainda hão), que são pacotes fechados com um propósito definido. Soluções como CRM (gerenciamento da interação com cliente), Churn Detection (detecção e prevenção de atrito, como em call centers) ou Credit Scoring (concessão de crédito automatizado), eram desenvolvidas com uso de Data Mining sobre os dados das empresas.

E não esqueçamos dos DWs, projetos sempre complicados e difíceis, e quase sempre operando aos trancos e barrancos. A tecnologia de DWs passou por três momentos de inflexão: a criação de bancos de dados em dispositivos de acesso aleatório, por volta de 1960, foi o primeiro. DASDs habilitaram a existência de Bancos de Dados Relacionais, sem os quais não seria possível construir um serviço viável de exploração de dados – antes usavam-se fitas magnéticas, e qualquer coisa mais complexa que uma listagem agregada era um transtorno. Depois veio o Modelo Dimensional, no início dos anos 90, que resolveu a vida dos usuários ao montar os dados de uma forma inteligível, apta à exploração por analistas de negócios. Ainda faltava resolver o acúmulo de dados, que seguia também aos trancos e barrancos, atendido parcialmente por Modelagem Dimensional. O advento do Data Vault, já na década 2000, resolveu essa parte. Hoje em dia, DWs são problemas só para quem está desatualizado desde 2003.

Enquanto Isso, Na Sala de Monitoramento…

Quando alguém decide que quer gerenciar uma empresa quando crescer, esse alguém faz uma faculdade de Administração de Empresas. Dentro dessa especialidade existe um sem-número de técnicas e teorias voltadas a entender como uma empresa funciona e como tomar decisões para que ela cresca.

Dentro de Administração de Empresas existem subconjuntos de conhecimento que tratam do monitoramento de uma organização, bem como o planejamento estratégico dela. O termo “balanced scorecard” surgido durante a década de 90 refere-se, de maneira geral, a uma técnica de monitoramento de rendimento (performance) que usa indicadores financeiros e não-financeiros. Essa técnica acompanha a execução das atividades por grupos de profissionais e as consequências dessas atividades. Por algumas coincidências, e pelo movimento do mercado, criou-se a percepção que Robert Kaplan e David Norton criaram o conceito, o que não é verdade, pois a técnica já existia antes. Eles apenas desenvolveram um sistema de gerenciamento estratégico que usa a idéia de um balanced scorecard como pino central.

Balanced Scorecard

A premissa de um Balanced Scorecard é que uma empresa pode monitorar a execução de suas estratégias acompanhando certos indicadores-chaves. O Balanced Scorecard do Norton e Kaplan é uma formalização desse conceito em uma metodologia que, automatizada com auxílio da Informática, cristalizou-se em uma solução chamada Strategic Management System (SMS), ou Sistema de Gerenciamento Estratégico.

Essa metodologia está explicada no livro deles, o The Balanced Scorecard: Translating Strategy into Action. Em tese, qualquer um pode implementar o sistema em sua empresa, a partir deste livro. Eu consegui encontrar uma companhia, ESM, que vende tal sistema, aparentemente uma encarnação oficial das teorias da dupla. Eis alguns screenshots dele:

Exemplo de painel ESM.
Exemplo de painel ESM.

 

Exemplo de mapa estratégico ESM.
Exemplo de mapa estratégico ESM.

O grande truque, que deu fama e fortuna aos autores, é saber que parâmetros monitorar e entender como esses parâmetros surgem das métricas geradas pela empresa, como essas métricas se ligam aos objetivos estratégicos.

Exceto por toda essa teoria, um SMS é, nada mais, nada menos que uma coleção de painéis de instrumentos – os famigerados dashboards – com dados coletados dos sistemas da empresa.

So The Story Goes…

O livro deles saiu em 1996, mas eles já vinham fazendo sucesso com essas idéias desde 1992, quando saiu o primeiro paper sobre o tópico.

O mercado por SMS estava aquecido devido ao sucesso da dupla e suas idéias. Implementações desses conceitos começaram a surgir, e a face mais visível desses sitemas era… o dashboard! Mas não acabava aí, não! Os dados que eram apresentados nesses painéis vinham, em geral, dos sistemas informatizados da empresa.

  • BSC é voltado para administração empresarial;;
  • BI também;
  • BSC usa dados integrados;
  • DW, uma subseção de BI, integra dados da organização;
  • BSC apresenta dados em visualizações bacanas;
  • BI também.
  • Etc.

Entenderam o caminho que a coisa tomou? Até parece que BSC e BI estão ligados intimamente, mas o fato é que nem de longe BSC é uma solução de BI!

  • BSC foca em dados correntes e suas relações determinadas a priori, em monitorar os dados da empresa para aquilatar o consistência do planejamento estratégico e sua execução. Os dados são atualizados muito frequentemente (um dia ou menos) e, em boa parte das vezes, apenas a variação dos indicadores é acompanhada, não dos dados mais granulares. O histórico dos dados em si não é capturado, e portanto não é usado;
  • BI é voltado para acumular dados históricos e analisá-los para descobrir suas relações a posteriori, em busca de entender o negócio. Dizemos que os dados são usados para tentar modelar, matematicamente, o funcionamento da companhia. Fala-se em previsão, em estimativas, em correlações previamente ignordas entre as variáveis etc. etc. etc.

Não são coisas estranhas entre si, pois ambos usam dados gerados em sistemas informatizados (BSC menos, BI mais), mas não são a mesma coisa, ou sequer parentes próximos.

Mesmo assim formou-se, no mercado de BI, a percepção de que BSC faz parte de BI.

Ok, vamos relegar essa parte e focar na questão “empresas vendendo BSC, o pão quente do momento”. Imagine o que aconteceu: empresas de BSC, como a tal da ESM mencionada acima, tinham lá o seu produto, que era uma novidade então.

E as empresas que vendiam BI, tinham o quê para mostrar como sendo BSC? Coleta de dados e apresentação de dados – e a teoria do BSC em um livro! Quando vendedores de BSC mostravam seu produto, a aparência, a parte visual era importante. Quando os fornecedores de BI seguiam essa trilha, o que mais aparecia para os clientes eram… Os dashboards!!

Conclusão

Não posso afirmar, categoricamente, que a tecnologia de painéis de instrumentos foi incorporada ao BI por “culpa” do BSC. Mas eu posso contar para vocês que ao visitar clientes interessados em BSC, eu, gerente de soluções SAS, vendedor de BI, era cobrado para mostrar os painéis da solução SAS para BSC. Era contra esse aspecto que a solução oferecida pelo SAS era comparada.

Eu nunca consegui emplacar uma venda de BSC pelo SAS. O produto de BSC da concorrência (não-BI) era bom o bastante para anular as vantagens do SAS (integração de dados díspares e flexibilidade nos painéis) e conseguir o pedido, mesmo sendo mais caro. Na minha opinião, olhando para trás, eu diria que a concorrência tinha uma implementação formal de BSC, completa e pronta, enquanto que o SAS apenas tentava surfar nessa onda, reempacotando seu produto com outro público-alvo diferente do público regular de BI.

Só que, até então, painéis não eram coisas de BI. Caramba, não tinha nem no catálogo do SAS, que tem tudo!

Por isso, na minha humilde opinião, dashboards entraram para o rol de recursos de BI por contaminação do mercado de SMS, do qual o BSC Norton e Kaplan é um ilustre membro. Dashboards não são melhor ferramenta analítica que um cubo OLAP ou um projeto de Data Mining, mas são excelentes meios para levar informação e oferecer visões completas – para apresentação dos dados.

É isso. Até a próxima. ;-)

Analisando os Logs do PDI – Parte 3

No primeiro post da série vimos como configurar a captura de logs nos processos do PDI, e obter informações básicas sobre os resultados de um processo qualquer.

No segundo post eu mostrei como usar os dados de performance de uma transformação para “caçar” gargalos.

Na terceira e última parte vamos entender como usar as tabelas logging channel para montar um relatório que lista todas as transformações e jobs executados a partir de um job-pai.

Cenário

Eis um exemplo básico de ETL que carrega um Data Warehouse dimensional:

Job principal de refresh do DW Beltrano.
Job principal de refresh do DW Beltrano.

O job acima chama uma transformação que, como o nome diz, define as variáveis do processo, e depois segue chamando os subjobs, cada um com uma tarefa específica: atualizar dimensões, carregar fatos e por fim preencher as tabelas pré-agregadas para OLAP. Por último é chamada outra transformação que coleta informações sobre o estado do DW naquele dia.

Dentro de cada um daqueles subjobs temos uma sequência de transformações, como, por exemplo, a carga das dimensões:

Job de sequenciamento de carga das dimensões.
Job de sequenciamento de carga das dimensões.

E cada uma dessas transformações faz a real movimentação de dados:

Carga da dimensão Cliente.
Carga da dimensão Cliente.

Para sabermos se tudo funcionou precisamos consultar o log de cada uma delas. Como os jobs estão amarrados com avanços condicionais (setas verdes), se der algum problema, o processo inteiro é abortado. Isso dá alguma facilidade de monitoração. Rodando no Spoon, o erro fica aparente:

Problema no processamento das dimensões.
Problema no processamento das dimensões.

Só que em produção não temos Spoon, então precisamos examinar o log:

2016/03/19 10:44:20 - Spoon - Starting job...
2016/03/19 10:44:20 - Refresh DW Beltrano - Start of job execution
2016/03/19 10:44:20 - Refresh DW Beltrano - Starting entry [Seta Variáveis]
2016/03/19 10:44:20 - Seta Variáveis - Loading transformation from XML file [file:///home/beltrano/ETL_Beltrano/t_a_seta_variaveis.ktr]
2016/03/19 10:44:20 - BELTRANO - KTR - Seta Variáveis - Dispatching started for transformation [BELTRANO - KTR - Seta Variáveis]
2016/03/19 10:44:20 - Grava timestamp.0 - Connected to database [beltrano_dw] (commit=1000)
2016/03/19 10:44:20 - Recupera Timestamp do Refresh.0 - Finished processing (I=0, O=0, R=1, W=2, U=0, E=0)
2016/03/19 10:44:20 - Seta variável.0 - Setting environment variables...
2016/03/19 10:44:20 - Seta variável.0 - Set variable REFRESH_TIMESTAMP to value [2016/03/19 10:44:20.724]
2016/03/19 10:44:20 - Seta variável.0 - Finished after 1 rows.
2016/03/19 10:44:20 - Seta variável.0 - Finished processing (I=0, O=0, R=1, W=1, U=0, E=0)
2016/03/19 10:44:20 - Grava timestamp.0 - Finished processing (I=0, O=1, R=1, W=1, U=0, E=0)
2016/03/19 10:44:20 - Refresh DW Beltrano - Starting entry [Carga das Dimensões]
2016/03/19 10:44:20 - Refresh DW Beltrano - Carga das Dimensões - Starting entry [Dimensão Clientes]
2016/03/19 10:44:20 - Dimensão Clientes - Loading transformation from XML file [file:///home/beltrano/ETL_Beltrano/t_d_clientes.ktr]
2016/03/19 10:44:20 - Dimensão Clientes - Dispatching started for transformation [Dimensão Clientes]
2016/03/19 10:44:21 - Lê CNPJs.0 - Finished reading query, closing connection.
2016/03/19 10:44:21 - Lê CNPJs.0 - Finished processing (I=5000, O=0, R=0, W=5000, U=0, E=0)
2016/03/19 10:44:21 - Insere Tipo.0 - Finished processing (I=0, O=0, R=5000, W=5000, U=0, E=0)
2016/03/19 10:44:21 - Formata fluxo PJ.0 - Finished processing (I=0, O=0, R=5000, W=5000, U=0, E=0)
2016/03/19 10:44:21 - Lê CPFs.0 - Finished reading query, closing connection.
2016/03/19 10:44:21 - Lê CPFs.0 - Finished processing (I=50000, O=0, R=0, W=50000, U=0, E=0)
2016/03/19 10:44:21 - Insere Tipo e Cargo.0 - Finished processing (I=0, O=0, R=50000, W=50000, U=0, E=0)
2016/03/19 10:44:21 - Formata fluxo PF.0 - Finished processing (I=0, O=0, R=50000, W=50000, U=0, E=0)
2016/03/19 10:44:21 - Une fluxos.0 - Finished processing (I=0, O=0, R=55000, W=55000, U=0, E=0)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 - ERROR (version 5.4.0.0-128, build 1 from 2015-06-03_13-41-59 by buildguy) : Unexpected error
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 - ERROR (version 5.4.0.0-128, build 1 from 2015-06-03_13-41-59 by buildguy) : org.pentaho.di.core.exception.KettleDatabaseException: 
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 - An error occurred executing SQL: 
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 - SELECT count(*) FROM d_clientes WHERE cliente_sk = 0
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 - ERROR: relation "d_clientes" does not exist
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -   Position: 22
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 - 
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.pentaho.di.core.database.Database.openQuery(Database.java:1722)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.pentaho.di.core.database.Database.openQuery(Database.java:1652)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.pentaho.di.core.database.Database.openQuery(Database.java:1648)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.pentaho.di.core.database.Database.openQuery(Database.java:1635)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.pentaho.di.core.database.Database.getOneRow(Database.java:2963)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.pentaho.di.trans.steps.dimensionlookup.DimensionLookup.checkDimZero(DimensionLookup.java:1681)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.pentaho.di.trans.steps.dimensionlookup.DimensionLookup.processRow(DimensionLookup.java:216)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.pentaho.di.trans.step.RunThread.run(RunThread.java:62)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at java.lang.Thread.run(Thread.java:745)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 - Caused by: org.postgresql.util.PSQLException: ERROR: relation "d_clientes" does not exist
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -   Position: 22
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:561)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:405)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:285)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     at org.pentaho.di.core.database.Database.openQuery(Database.java:1711)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 -     ... 8 more
2016/03/19 10:44:21 - Ordena lista.0 - Finished processing (I=0, O=0, R=55000, W=15882, U=0, E=0)
2016/03/19 10:44:21 - Dimensão Clientes - ERROR (version 5.4.0.0-128, build 1 from 2015-06-03_13-41-59 by buildguy) : Errors detected!
2016/03/19 10:44:21 - Estado.0 - Finished processing (I=28, O=0, R=6154, W=6154, U=0, E=0)
2016/03/19 10:44:21 - Carrega Dimensão Clientes.0 - Finished processing (I=0, O=0, R=1, W=0, U=0, E=1)
2016/03/19 10:44:21 - Dimensão Clientes - Transformation detected one or more steps with errors.
2016/03/19 10:44:21 - Dimensão Clientes - Transformation is killing the other steps!
2016/03/19 10:44:21 - Cidade.0 - Finished processing (I=9715, O=0, R=8553, W=8552, U=0, E=0)
2016/03/19 10:44:21 - Dimensão Clientes - ERROR (version 5.4.0.0-128, build 1 from 2015-06-03_13-41-59 by buildguy) : Errors detected!
2016/03/19 10:44:21 - Refresh DW Beltrano - Carga das Dimensões - Finished job entry [Dimensão Clientes] (result=[false])
2016/03/19 10:44:21 - Refresh DW Beltrano - Finished job entry [Carga das Dimensões] (result=[false])
2016/03/19 10:44:21 - Refresh DW Beltrano - Finished job entry [Seta Variáveis] (result=[false])
2016/03/19 10:44:21 - Refresh DW Beltrano - Job execution finished
2016/03/19 10:44:21 - Spoon - Job has ended.

Lendo o log descobrimos, facilmente, que o problema é a tabela d_clientes, que não foi criada no DW.

“Facilmente”?

Talvez em um processo simples, com poucos passos – e quando o erro aparece logo no começo. Mas achar o erro em um log desses, que pode chegar a vários megabytes, é qualquer coisa, menos “fácil”.

Você pode argumentar que basta fazer uma busca por ERROR. Verdade, mas precisaria fazer a busca no log inteiro, até o fim! E depois outra: onde é que apareceu mesmo esse erro? Examine o log outra vez: depois que achar o erro, você precisa seguir o log para cima, para descobrir em que arquivo (job ou transformação) ele ocorreu, ou para baixo, até encontrar o nome do job/transformação – mas não o nome do arquivo!

Resumindo: dá para fazer, mas é um porre.

Encontrando Nemo. Digo, Erros!

Eu sempre digo que sou um cara prático (preguiçoso é feio, ainda que seja mais franco, hehe) e gosto de usar computadores para fazer qualquer tarefa que possa ser feita por eles.

Uma forma mais fácil de encontrar erros é montar uma consulta como a do primeiro artigo e listar tudo que possuir o campo status igual a stop:

 (SELECT
       id_job,
       'Job' as tipo,
       jobname as nome,
       status,
       to_char(replaydate, 'DD/MM/YY HH24:MI:SS') as replaydate
  FROM job
  WHERE status='stop')
UNION
  (SELECT
       id_batch,
       'Transformação' as tipo,
       transname as nome,
       status,
       to_char(replaydate, 'DD/MM/YY HH24:MI:SS') as replaydate
  FROM transformation
  WHERE status='stop')
ORDER BY replaydate,nome

Resultado:

id tipo nome status replaydate
3 Job Popula Empresa-Case stop 23/02/16 20:48
8 Job Empresa-Case – Popula Tabelas Indepentes stop 23/02/16 20:55
2037 Transformação BELTRANO – KTR – Seta Variáveis stop 19/03/16 10:32
2039 Transformação Dimensão Clientes stop 19/03/16 10:33
2041 Transformação Dimensão Clientes stop 19/03/16 10:35
2043 Transformação Dimensão Clientes stop 19/03/16 10:44

Bem melhor, não? O problema aqui é que ele traz todo mundo. Ainda precisaríamos fazer algum filtro para pegar só o do dia anterior, ou até uma semana para trás, ou algo assim.

Mas podemos fazer melhor.

16.3 Árvore Genea-LOG-ica

Segundo Matt Casters, a tabela de logging channels surgiu como uma forma de amarrar os diversos logs: todas as coisas que são geradas no PDI ganham um ID particular, que é usado sempre que precisam – internamento ou no registro de log – se referir à aquele objeto. (Pelo menos foi o que eu entendi.) Isso é uma evolução em relação ao sistema antigo, que usava um ID sequencial para cada item, o que, convenhamos, é algo um tanto quanto noob.

O sistema de logs do PDI grava os canais de log em um tabela com o seguinte layout:

Coluna Tipo Descrição
id_batch int4 ID do lote
channel_id varchar ID do canal
log_date timestamp Data de registro nesta tabela
logging_object_type varchar Tipo do objeto: job, stransformação, banco de dados etc.
object_name varchar Nome do objeto
object_copy varchar Número da cópia do objeto
repository_directory varchar Caminho do objeto (repositório em banco)
filename varchar Diretório e nome do arquivo que contém este objeto
object_id varchar ID do objeto no repositório (repositório em banco)
object_revision varchar Versão do objeto (só para versão EE)
parent_channel_id varchar ID do canal do objeto-pai, que criou este objeto
root_channel_id varchar ID do canal do objeto-ancestral, que deu origem a todos os outros

O PDI pode salvar jobs e transformações em um sistema de arquivos, como um arquivo XML, ou em um repositório em banco de dados. As colunas da tabela que se referem a atributos válidos apenas para artefatos gravados no repositório em banco de dados recebem nulo quando o job ou transformação é gravado como um arquivo ordinário.


Pelo fato de os IDs serem gerados como um hash, o risco de colisão é próximo de nulo. Tanto é assim que as tabelas para canais de job e transformação tem o mesmo layout, e a Pentaho recomenda usar uma só tabela para registrar os dois.

Eis o conteúdo de algumas destas colunas:

Algumas colunas da tabela logging Channels.
Algumas colunas da tabela logging Channels.

Podemos usar essa tabela para listar todos os jobs e transformações envolvidos em um único processo. Depois, usando as tabelas de log de job e transformação, podemos adicionar o status e ordená-los pela data e hora de inicialização (replaydate.) Podemos montar um relatório com esse resultado. Daí poderemos revisar o processamento do dia e encontrar eventuais falhas muito mais – agora sim! – facilmente.

Vamos fazer isso, então.

Lista de Jobs-Raiz

Um job-raiz, por falta de um termo melhor, é um job que está na raiz de um processamento qualquer, e corresponde à lista de todos os tipos de objeto (coluna logging_object_type) JOB, cujo pai é nulo e que as tem a coluna root_channel_id igual à channel_id. Por exemplo, na figura anterior, o último job do ID_BATCH igual à 1023 é um job-raiz.

A consulta que traz isso é:

SELECT id_batch,
       channel_id,
       log_date,
       object_name
FROM job_logging_channels
WHERE logging_object_type = 'JOB'
      AND parent_channel_id IS NULL
      AND channel_id = root_channel_id

E eis o resultado:

id_batch channel_id log_date object_name
18 f411e0d2-… 2016-02-23 21:45:12.588 Popula Empresa-Case
22 9e142006-… 2016-02-23 22:27:00.323 Popula Tabelas de Pedidos
1023 b604142b-… 2016-03-19 10:27:20.576 Refresh DW Beltrano

Essa lista é o primeiro filtro do relatório: o conteúdo da coluna object_name será apresentado ao usuário como um prompt. E como cada job pode ter sido executado diversas vezes, um segundo prompt vai apresentar a lista de datas em que aquele processo foi executado, para que o usuário escolha que corrida analisar.

A lista de datas de execução é obtida com uma consulta na tabela de log do job, filtrada pelo object_name. Usando o job Popula Empresa-Case como exemplo, a lista de datas vem desta consulta:

SELECT DISTINCT
       channel_id,
       replaydate
FROM job
WHERE jobname = 'Popula Empresa-Case'

Usando essas consultas eu comecei o relatório:

Relatório de linhagem do job, com prompts de job e corrida.
Relatório de linhagem do job, com prompts de job e corrida.

Lista de Descendentes

A forma como a tabela de canais foi bolada permite construir uma consulta recursiva, para recuperar todas as partes de um processo, descendo até o último nível. Essa é a forma correta de consultar essa tabela. Porém, como eu não sei tanto SQL para poder construir uma consulta recursiva, vou apenas ser criativo e fazer de outra forma.

Os descendentes daquele job-raiz tem todos uma coisa em comum: o mesmo job-raiz (duhn.) Logo, podemos selecionar todos os elementos – jobs e transformações – que foram executados no mesmo pacote fazendo outra consutla à tabela de log. Eis como selecionar somente os jobs e transformações disparados pelo job principal:

SELECT channel_id,
       logging_object_type,
       object_name
FROM job_logging_channels
WHERE logging_object_type IN ('JOB','TRANS')
      AND root_channel_id = ${job_raiz}

O resultado, especificamente para o caso do job-raiz 9e142006-fb5d-4b28-8b87-1ff0c706919e, é:

channel_id logging_object_type object_name
d4d5227e-c07b-45d1-a6a9-715310de2e7e TRANS Gera Pedidos
56639da7-cb6d-435f-8d1e-c3a1f99c8687 TRANS Gera Parâmetros para Itens de Pedidos
06af3232-75ea-4b7f-b178-eab915e190df TRANS Seta Variáveis de Subitens
ee44ed8d-dbcc-431b-9b9d-d8220fe78838 TRANS Gera Pedidos Detalhes
aa0a4992-be94-4f8e-b0bf-98d14c0baaef JOB Popula Itens de Pedidos
957dc288-16e1-462c-9f1a-89efb026a2a2 TRANS Seta Variáveis de Subitens
4f2927bf-14c5-4b5a-a0d3-8a4c8eb597d7 TRANS Gera Pedidos Detalhes
a4dbea3e-6731-4fc3-92fb-1230888847d9 TRANS Seta Variáveis de Subitens
095dd255-20ec-4b96-a1d5-cf3a316f248d TRANS Gera Pedidos Detalhes
9e142006-fb5d-4b28-8b87-1ff0c706919e JOB Popula Tabelas de Pedidos

Pronto! Temos a nossa lista de jobs e transformações que compõe o job principal! Agora precisamos apenas dos detalhes de cada um deles, que estão nas respectivas tabelas de log de job e de transformação.

Detalhando a Lista

Como os detalhes de jobs e transformações estão em tabelas separadas, vamos fazer dois JOINs e depois reuni-los. Primeiro, os detalhes dos jobs:

SELECT logging_object_type,
       object_name,
       status,
       replaydate
FROM job_logging_channels, job
WHERE logging_object_type = 'JOB'
      AND job_logging_channels.channel_id = job.channel_id
      AND root_channel_id = ${job_raiz}

E agora os das transformações:

SELECT logging_object_type,
       object_name,
       status,
       replaydate
FROM job_logging_channels, transformation
WHERE logging_object_type = 'TRANS'
      AND job_logging_channels.channel_id = transformation.channel_id
      AND root_channel_id = ${job_raiz}

Unindo as duas consultas, temos o resultado completo:

Relatório completo, mostrando a linhagem de execução, ordenada por data/hora.
Relatório completo, mostrando a linhagem de execução, ordenada por data/hora.

Conclusão & Encerramento

O Pentaho Data Integration é uma das mais modernas e sofisticadas ferramentas de integração de dados disponíveis. Entre seus vários recursos estão a captura de logs muito detalhados, dos quais podemos extrair um gama de informaçôes sobre os processos executados por ele.

Nesta série vimos como configurar e usar o sistema de logs do PDI para obter uma visão simples, ainda que minimamente completa, sobre o que se passou em uma dada corrida (primeiro post).

No segundo post vimos como analisar os logs das transformações para detectar os gargalos, isto é, os pontos que puxam a velocidade da dita transformação para baixo.

Com este terceiro post concluímos a série. Vimos como usar um recurso fundamental do sistema de logs, a tabela de “canais” de log (logging channels), para montar uma listagem que sequencia todos os jobs e transformações executados em um processo (clique aqui para baixar o relatório.)

Esses três artigos formam um exemplo simples e prático para monitorar o processo diário, mas há muito que podemos fazer para melhorar a gestão de um DW. Por exemplo, temos todas as possibilidades de automação de detecção de erros e acionamentos por e-mail.

Até a próxima. ;-)

Analisando os Logs do PDI – Parte 2

No primeiro post da série Logs do PDI vimos como configurar as transformações e jobs do PDI para capturar os logs de processamento e como usá-los para monitorar as execuções. Neste segundo post veremos como usar esses dados para identificar gargalos.

Pias & Transformações

Imagine uma pia, na qual uma torneira despeja água. Se entrar mais água do que a pia consegue escoar, a água vai começar a se acumular. Se nada for feito, o nível de água na pia vai subir, e subir, até transbordar. Há duas formas de se evitar que a água transborde: reduzir a entrada ou aumentar a saída. Em termos mais genéricos, para evitar que a água transborde devemos condicionar a entrada à restrição. A “restrição” é justamente a válvula de escoamento da pia.

A velocidade de uma transformação, medida em linhas por segundo, l/s, está condicionada à restrição existente na transformação: a velocidade de uma transformação será igual à velocidade do seu passo mais lento. Esse passo mais lento é o gargalo.


Se uma transformação possuir passos de ordenação de linhas, agrupamentos etc., que represam linhas, a velocidade média da transformação perde essa relação direta. Ainda vai haver uma relação entre a velocidade da transformação e a velocidade do seu passo mais lento, apenas não será mais 1 para 1. Mas, para manter o didatismo do post, vamos assumir uma transformação perfeitamente esférica e sem atrito, na qual essa condição vale. ;-)


Para aumentar a velocidade de uma transformação, portanto, devemos aumentar a velocidade do fluxo (em l/s) no gargalo. Quando a velocidade no gargalo tiver subido o bastante, algum outro passo vai ser o responsável por restringir a velocidade da transformação, se transformando no novo gargalo. Removemos esse novo gargalo, aumentando a velocidade da transformação, e outro aparecerá, reiniciando o processo. Eventualmente, chegaremos num ponto de rendimento máximo da transformação, no qual uma nova mudança em qualquer passo não vai resultar em aumento de velocidade da transformação.

Simples, não?

Engarrafamento de Linhas

E como descobrimos gargalos em uma transformação?

Usando o Spoon para detectar gargalos: notou um pontilhado em volta de algum passo? É um gargalo!
Usando o Spoon para detectar gargalos: notou um pontilhado em volta de algum passo? É um gargalo!

Se você estiver rodando-a no Spoon, a interface gráfica do PDI, é muito fácil. O PDI detecta o gargalo, definido por ele como “o passo que recebe mais linhas do que é capaz de processar”, e faz com que o Spoon apresente um pontilhado animado em volta de cada passo identificado como gargalo. Esse monitoramento ocorre em tempo real, e causa efeitos curiosos: em certas situações o gargalo parece “pular” entre dois ou mais passos, e em outras vários passos são marcados como gargalos, simultaneamente. A dinâmica que causa isso está fora do escopo deste post, mas não é difícil de entender se você parar para pensar um pouco.

Para que seu Spoon mostre esse passo na sua transformação você precisa habilitar o checkbox Show bottleneck transformation steps, conforme visto na figura abaixo. Essa janela aparece quando selecionamos o item Options, no menu Tools.

Onde fica o checkbox que habilita a exibição do gargalo.
Onde fica o checkbox que habilita a exibição do gargalo.

Essa opção é muito boa durante o processo de desenvolvimento, mas o que fazer para transformações que rodamos em produção? É um ambiente diferente – memória diferente, disco diferente, carga (tarefas simultâneas) diferentes! Se bobear até o sistema operacional é diferente! Não dá para rodar uma por uma no Spoon e ficar olhando, esperando encontrar um passo-gargalo.

Você adivinhou: consultamos o log de performance.

Entendendo o Gargalo

Conforme o próprio PDI coloca, um gargalo (ou restrição) é “um passo que recebe mais linhas do que é capaz de processar”. Para entender isso você precisa saber um pouco sobre a estrutura interna de um passo.

Um passo possui, grosso modo, três partes:

  1. Buffer de entrada: onde são gravadas as linhas que chegam do passo anterior, e onde elas ficam esperando ser processadas;
  2. Motor do passo: retira uma linha do buffer de entrada, processa e grava o resultado no buffer de saída, repetindo esse processo enquanto o passo anterior estiver mandando linhas;
  3. Buffer de entrada: onde são gravadas as linhas processadas pelo passo, e onde elas aguardam até o engine do PDI movê-las para o passo seguinte.
Todo passo possui dois buffers: entrada e saída.
Todo passo possui dois buffers: entrada e saída.

Assim, se o motor do passo, o processamento em si, não for rápido o bastante, ele começa a ficar para trás: as linhas começam a se acumular no buffer de entrada. Se, além disso, se o passo seguinte for no mínimo tão rápido quanto o passo atual, as linhas processadas não “esquentam cadeira” no buffer de saída, e vão sendo levadas adiante. Por exemplo, na transformação simples mostrada abaixo, com três passos, o passo do meio é um gargalo:

O passo do meio é um gargalo: buffer de saída com menos linhas que o de entrada.
O passo do meio é um gargalo: buffer de saída com menos linhas que o de entrada.

Note que os buffers do passo do meio, representados pelas caixas de entrada e saída, aparecem vazio na saída e cheio na entrada. Essa é a condição de gargalo, ou de restrição. Se pudermos aumentar (elevar) a vazão dessa restrição, a velocidade da transformação, como um todo, aumentará.

Como vemos isso nos logs? Bom, quando rodamos uma transformação no Spoon, este monta um quadro de métricas dos passos, e atualiza-o conforme a transformação vai sendo executada, conforme as linhas vão sendo processadas.

Passos e seus parâmetros durante execução.
Passos e seus parâmetros durante execução.

A coluna input/output, última à direita na imagem anterior, exibe a relação entre a quantidade de linhas presentes no buffer de entrada, aguardando processamento, e quantidade de linhas no buffer de saída, aguardando transporte até o passo seguinte. Sempre que um passo possui mais linhas em sua entradas que em sua saída, ele está “segurando” a transformação. Para encontrarmos os gargalos de uma transformação, então, basta analisarmos os passos dela, em busca de buffers de entrada cheios e buffers de saída vazios (ou com bem menos linhas.)

Analisando Vazão em Transformações

O log que captura as métricas de cada passo, segundo a segundo, chama-se Performance. Veja como ativá-lo no primeiro post da série. Essa tabela possui as seguintes colunas:

  • id_batch
  • seq_nr
  • logdate
  • transname
  • stepname
  • step_copy
  • lines_read
  • lines_written
  • lines_updated
  • lines_input
  • lines_output
  • lines_rejected
  • errors
  • input_buffer_rows
  • output_buffer_rows

Reparou nas duas últimas? São as que nos interessam.


Não vou montar uma solução pronta, mas mostrar como usar essa tabela para desenhar algo que atenda à sua necessidade – e depois vou mostrar um exemplo do relatório que eu uso para “debugar” transformações em produção.


Precisamos de uma consulta que traga os buffers, por cada passo, por transformação. Além disso, como cada transformação pode ter sido executada várias vezes, precisamos filtrar também por lote (id_batch.) Essa consulta ficaria assim:

SELECT
  id_batch,
  transname,
  stepname,
  input_buffer_rows,
  output_buffer_rows
FROM transformation_performance
WHERE
  id_batch = X AND
  transname = 'x'

Filtrando para lote 2080 e transformação Carga da Lista de Clientes PF, temos:

id_batch transname stepname input_buffer_rows output_buffer_rows
2080 Carga da Lista de Clientes PF Gera strings aleatórias 224 276
2080 Carga da Lista de Clientes PF Cria CEP, Telefone e Fax 0 0
2080 Carga da Lista de Clientes PF Cria CEP, Telefone e Fax 0 0
2080 Carga da Lista de Clientes PF Lê nomes 0 0
2080 Carga da Lista de Clientes PF Cria as partes de CEP, Telefone e Fax 0 0
2080 Carga da Lista de Clientes PF Muda rnd_telefone/fax para string 0 0
2080 Carga da Lista de Clientes PF Seleciona endereço 2 0
2080 Carga da Lista de Clientes PF Lê sobrenomes 0 61
2080 Carga da Lista de Clientes PF Acerta tamanho das strings 0 0
2080 Carga da Lista de Clientes PF Seleciona sobrenome 61 0
2080 Carga da Lista de Clientes PF Lê lista de enderecos 0 0
2080 Carga da Lista de Clientes PF Seleciona nome 0 0
2080 Carga da Lista de Clientes PF Cria ID do Cliente 1560 225
2080 Carga da Lista de Clientes PF Insere cidade_id 1 3
2080 Carga da Lista de Clientes PF Limpa fluxo 0 0
2080 Carga da Lista de Clientes PF Cria índice do endereço 276 125
2080 Carga da Lista de Clientes PF Gerar linhas 0 2444
2080 Carga da Lista de Clientes PF Cria índices de nome 147 110
2080 Carga da Lista de Clientes PF String operations 3 1
2080 Carga da Lista de Clientes PF Absoluto de rnd_cpf 110 3
2080 Carga da Lista de Clientes PF Grava tabela 0 0
2080 Carga da Lista de Clientes PF Gera strings aleatórias 1778 5755
2080 Carga da Lista de Clientes PF Cria CEP, Telefone e Fax 0 0

E aí, consegue dizer se algum destes passos é um gargalo? Nem eu. Vamos melhorar nossa consulta: vamos agrupar por passo, remover o nome da transformação e lote da execução, já que ambos são previamente conhecidos (estão no filtro.) Fica assim:

SELECT
  stepname,
  sum(input_buffer_rows) as buffer_entrada,
  sum(output_buffer_rows) as buffer_saida
FROM transformation_performance
WHERE
  id_batch = 2080 AND
  transname = 'Carga da Lista de Clientes PF'
GROUP BY
  stepname
ORDER BY
  stepname

Resultado:

stepname buffer_entrada buffer_saida
Absoluto de rnd_cpf 4289 2770
Acerta tamanho das strings 10117 10100
Cria as partes de CEP, Telefone e Fax 100 10098
Cria CEP, Telefone e Fax 10101 20099
Cria ID do Cliente 21021 11892
Cria índice do endereço 15660 3458
Cria índices de nome 3483 4289
Gerar linhas 0 21902
Gera strings aleatórias 11889 15658
Grava tabela 20281 0
Insere cidade_id 202 259
Lê lista de enderecos 0 0
Lê nomes 0 0
Lê sobrenomes 0 61
Limpa fluxo 20099 20281
Muda rnd_telefone/fax para string 125 100
Seleciona endereço 258 714
Seleciona nome 714 100
Seleciona sobrenome 161 125
String operations 2770 202

Já dá para dizer se alguém é gargalo? Não! Veja, buffer de entrada e buffer de saída são métricas não-aditivas: somá-las ao longo do tempo não dá nenhuma informação sobre o processo. Nem somando-as ao longo dos passos, ou das transformações, nada! No máximo, como métricas não-aditivas, talvez uma média ao longo do tempo possa dar alguma idéia do que está acontecendo.

Mesmo assim, a média não ajudaria. Lembra-se que o monitoramento de gargalo do Spoon ocorre em tempo real? E que os gargalos podem pular de um passo para outro? Só conseguimos identificar um gargalo olhando o comportamento dele ao longo do tempo, momento a momento.

Incluíndo o tempo na consulta, temos:

SELECT
  stepname,
  logdate,
  sum(input_buffer_rows) as buffer_entrada,
  sum(output_buffer_rows) as buffer_saida
FROM transformation_performance
WHERE
  id_batch = 2080 AND
  transname = 'Carga da Lista de Clientes PF'
GROUP BY
  stepname,
  logdate
ORDER BY
  stepname

Vai nos dar a seguinte saída:

stepname logdate buffer_entrada buffer_saida
Absoluto de rnd_cpf 2016-02-21 16:34:41 110 3
Absoluto de rnd_cpf 2016-02-21 16:34:41 110 3
Absoluto de rnd_cpf 2016-02-21 16:34:42 87 100
Absoluto de rnd_cpf 2016-02-21 16:34:43 4092 2667
Absoluto de rnd_cpf 2016-02-21 16:34:44 0 0
Absoluto de rnd_cpf 2016-02-21 16:34:45 0 0
Absoluto de rnd_cpf 2016-02-21 16:34:46 0 0
Absoluto de rnd_cpf 2016-02-21 16:34:46 0 0
Acerta tamanho das strings 2016-02-21 16:34:41 0 0
Acerta tamanho das strings 2016-02-21 16:34:42 0 0
Acerta tamanho das strings 2016-02-21 16:34:43 120 100
Acerta tamanho das strings 2016-02-21 16:34:44 9997 10000
Acerta tamanho das strings 2016-02-21 16:34:45 0 0
Acerta tamanho das strings 2016-02-21 16:34:46 0 0
Acerta tamanho das strings 2016-02-21 16:34:46 0 0
Cria as partes de CEP, Telefone e Fax 2016-02-21 16:34:41 0 0
Cria as partes de CEP, Telefone e Fax 2016-02-21 16:34:42 0 0
Cria as partes de CEP, Telefone e Fax 2016-02-21 16:34:43 100 101
Cria as partes de CEP, Telefone e Fax 2016-02-21 16:34:44 0 9997
Cria as partes de CEP, Telefone e Fax 2016-02-21 16:34:45 0 0
Cria as partes de CEP, Telefone e Fax 2016-02-21 16:34:46 0 0
Cria as partes de CEP, Telefone e Fax 2016-02-21 16:34:46 0 0
Cria CEP, Telefone e Fax 2016-02-21 16:34:41 0 0
Cria CEP, Telefone e Fax 2016-02-21 16:34:42 0 0
Cria CEP, Telefone e Fax 2016-02-21 16:34:43 101 100
Cria CEP, Telefone e Fax 2016-02-21 16:34:44 10000 10000
Cria CEP, Telefone e Fax 2016-02-21 16:34:45 0 9999
Cria CEP, Telefone e Fax 2016-02-21 16:34:46 0 0

Agora podemos dizer, se em algum instante, um passo se comportou como um gargalo. Claro que examinar os dados assim é uma bobagem – podemos montar um gráfico com isso.

Relatório de Análise de Fluxos

Juntando essa consulta com os relatórios do primeiro post, montamos um relatório de análise de fluxo de transformações:

Relatório de análise de fluxo em transformações.
Relatório de análise de fluxo em transformações.

Esse relatório traça a velocidade daquele passo em linhas por segundo no gráfico de cima, e o volume de linhas presentes nos buffers, no gráfico de baixo, tudo instante a instante. O que vemos é que esse passo possui uma vazão boa, até, de 20.000 l/s, e que ele nunca esteve em condição de gargalo. Muito pelo contrário: no instante 5 ele teve o seu buffer de saída completamente cheio, sugerindo que o passo seguinte poderia ser um gargalo.

Eis o trecho da transformação que estamos analisando:

Trecho final da transformação de carga de clientes PF da Beltrano S/A.
Trecho final da transformação de carga de clientes PF da Beltrano S/A.

Os passos seguintes são um Select Values e um Table Output. Eis os buffers do Select Values:

Buffers do Select Values.
Buffers do Select Values.

E os do Table Output:

Buffers do Table Output.
Buffers do Table Output.

A-há! Veja ali, do momento 3 ao momento 6, como o buffer de entrada (a linha vermelha) sobe até atingir 10.000 linhas, enquanto o buffer de saída permanece em zero! Esse passo é um gargalo! Ele ficou com o buffer de entrada cheio, que fez com que as linhas “transbordassem” para o passo anterior, o Select Values. Tanto esse Select Values não é um gargalo que os dois buffers sobem e descem juntos. Mais ainda: foi justamente entre os momentos 3 e 6 (comuns a todos os passos, aliás, pois o log de performance captura todo mundo junto) que o buffer de saída do passo Cria CEP, Telefone e Fax saturou, isto é, atingiu seu limite de 10.000 linhas, e começou a se refletir no buffer de entrada, mesmo que por apenas um segundo (cada momento equivale a um segundo nesta escala.)

Conclusão

A partir da consulta mostrada podemos criar um relatório que exibe o estado dos buffers de cada passo momento a momento. Usando a transformação como guia, podemos analisar cada um dos passos em busca do sintoma de restrição de fluxo.

Essa não é a melhor análise, já que nos obriga a olhar um por um. Como você faria essa análise automaticamente? Como deixar para o Report Designer detectar os gargalos de uma transformação?

E apenas para fechar o problema encontrado neste exemplo: um gargalo em um passo que grava dados no banco significa que a rede e o banco é que são os gargalos. Dependendo da influência da rede e do banco na força da restrição, podemos levar o processamento para mais perto (reduzindo o custo da rede) ou melhorar o banco com, por exemplo, discos mais rápidos.

Na próxima semana terminaremos a série com um relatório de genealogia de um processo de ETL.

Até lá!


Novo Lançamento!

Sexta-feira, 11 de março de 2016, será o lançamento do meu novo livro, Autopublicação na Prática. Não deixe de passar por aqui, porque – como sempre – ele será lançado por R$ 0,00!

Analisando os Logs do PDI – Parte 1

O Pentaho Data Integration, antigamente conhecido por Kettle, é a ferramenta de integração de dados da Suite Pentaho. É, de longe, a ferramenta de maior sucesso deles e tanto é assim que fornecedores tradicionais desse mercado “sentiram o calor” da concorrência.

Neste post eu não vou falar sobre o PDI em si, mas sobre uma de seus recursos: o log.

Toco Cru

Em inglês, log significa “tora de madeira”.

Those are the logs.
Those are the logs.

Ou diário, como em captain’s log, o diário do capitão, ou lab log, que é aquele caderninho preto em que cientistas anotam o que aconteceu nos experimentos. :-) Quando dizemos que um programa gera logs, estamos querendo dizer que ele registra, em algum lugar, informações sobre o que está acontecendo. Podem ser erros, avisos ou simplesmente uma narração das ações do programa. Em geral, cada entrada no registro possui uma etiqueta de tempo, ou timestamp, para que seja possível saber quando tal evento ocorreu, e colocá-los em sequência, para estudo.

Transformações e jobs do PDI geram uma profusão de dados durante seu processamento, e a maioria dos usuários do PDI vê parte desses dados na saída do processamento:

geekbi@dw:/opt/pentaho/5.1/data-integration$ ./pan.sh -file=/home/Beltrano/00_Beltrano_1.0/ETL/t_d_date.ktr
2016/02/21 10:50:04 - Pan - Start of run.
2016/02/21 10:50:05 - Dimensão Data - Dispatching started for transformation [Dimensão Data]
2016/02/21 10:50:05 - d_date.0 - Connected to database [beltrano_dw] (commit=10000)
2016/02/21 10:50:05 - Days of week.0 - Finished processing (I=0, O=0, R=0, W=7, U=0, E=0)
2016/02/21 10:50:05 - Months.0 - Finished processing (I=0, O=0, R=0, W=12, U=0, E=0)
2016/02/21 10:50:05 - 10000 dias: 25 anos.0 - LineNr : 5000
2016/02/21 10:50:05 - Days_since.0 - linenr 5000
2016/02/21 10:50:05 - 10000 dias: 25 anos.0 - LineNr : 10000
2016/02/21 10:50:05 - 10000 dias: 25 anos.0 - Finished processing (I=0, O=0, R=0, W=10000, U=0, E=0)
2016/02/21 10:50:05 - Days_since.0 - linenr 10000
2016/02/21 10:50:05 - Days_since.0 - Finished processing (I=0, O=0, R=10000, W=10000, U=0, E=0)
2016/02/21 10:50:05 - Calc Date.0 - Linenr 5000
2016/02/21 10:50:05 - DayOfWeekDesc.0 - linenr 5000
2016/02/21 10:50:05 - MonthDesc.0 - linenr 5000
2016/02/21 10:50:05 - Select values.0 - linenr 5000
2016/02/21 10:50:05 - d_date.0 - linenr 5000
2016/02/21 10:50:06 - Calc Date.0 - Linenr 10000
2016/02/21 10:50:06 - Calc Date.0 - Finished processing (I=0, O=0, R=10000, W=10000, U=0, E=0)
2016/02/21 10:50:06 - Quarter.0 - Finished processing (I=0, O=0, R=10000, W=10000, U=0, E=0)
2016/02/21 10:50:06 - DayOfWeekDesc.0 - linenr 10000
2016/02/21 10:50:06 - DayOfWeekDesc.0 - Finished processing (I=0, O=0, R=10007, W=10000, U=0, E=0)
2016/02/21 10:50:06 - MonthDesc.0 - linenr 10000
2016/02/21 10:50:06 - MonthDesc.0 - Finished processing (I=0, O=0, R=10012, W=10000, U=0, E=0)
2016/02/21 10:50:06 - Select values.0 - linenr 10000
2016/02/21 10:50:06 - Select values.0 - Finished processing (I=0, O=0, R=10000, W=10000, U=0, E=0)
2016/02/21 10:50:06 - d_date.0 - linenr 10000
2016/02/21 10:50:06 - d_date.0 - Finished processing (I=0, O=10000, R=10000, W=10000, U=0, E=0)
2016/02/21 10:50:06 - Pan - Finished!
2016/02/21 10:50:06 - Pan - Start=2016/02/21 10:50:04.785, Stop=2016/02/21 10:50:06.757
2016/02/21 10:50:06 - Pan - Processing ended after 1 seconds.
2016/02/21 10:50:06 - Dimensão Data -
2016/02/21 10:50:06 - Dimensão Data - Step Days_since.0 ended successfully, processed 10000 lines. ( 10000 lines/s)
2016/02/21 10:50:06 - Dimensão Data - Step Calc Date.0 ended successfully, processed 10000 lines. ( 10000 lines/s)
2016/02/21 10:50:06 - Dimensão Data - Step DayOfWeekDesc.0 ended successfully, processed 10007 lines. ( 10007 lines/s)
2016/02/21 10:50:06 - Dimensão Data - Step MonthDesc.0 ended successfully, processed 10012 lines. ( 10012 lines/s)
2016/02/21 10:50:06 - Dimensão Data - Step Select values.0 ended successfully, processed 10000 lines. ( 10000 lines/s)
2016/02/21 10:50:06 - Dimensão Data - Step d_date.0 ended successfully, processed 10000 lines. ( 10000 lines/s)
2016/02/21 10:50:06 - Dimensão Data - Step Quarter.0 ended successfully, processed 10000 lines. ( 10000 lines/s)
2016/02/21 10:50:06 - Dimensão Data - Step Days of week.0 ended successfully, processed 7 lines. ( 7 lines/s)
2016/02/21 10:50:06 - Dimensão Data - Step Months.0 ended successfully, processed 12 lines. ( 12 lines/s)
2016/02/21 10:50:06 - Dimensão Data - Step 10000 dias: 25 anos.0 ended successfully, processed 10000 lines. ( 10000 lines/s)

Essa é só a narração dos eventos, mas muitos outros dados são capturado durante o processamento: quantidade de linhas lidas e gravadas em bancos e arquivos, quantidade de linhas processadas em cada passo, conteúdo de variáveis carregadas, conexões feitas, erros, aviso – o PDI captura tudo, tudo, até a vazão da pia da cozinha. Esses dados podem ser descarregados diretamente num banco, o que habilita o gestor do projeto a monitorar a carga minuciosamente. Por exemplo, podemos criar indicadores de performance e acompanhá-los diariamente, ou buscar informações sobre o que aconteceu durante uma corrida qualquer do ETL.

Está série é composta de três posts. Nesta primeira parte vamos mostrar como configurar o PDI para injetar os dados capturados em um banco de dados e como construir um relatório bem simples, com indicadores básicos sobre o processamento.

Na Parte 2 veremos como descobrir gargalos, que são pontos de lentidão no fluxo de dados. Por fim, na parte 3, veremos um relatório que dá a genealogia (quem chamou quem, a que horas e quanto tempo levou) de um job, uma informação crucial para o monitoramento da “saúde” do processo.

Ativando a Captura de Log

O PDI descarrega seu log apenas em bancos de dados. Por isso você precisa ter um banco de destino para gravar seus logs. Normalmente eu mantenho um esquema de log nos mesmos bancos dos DWs, pois isso simplifica tanto o desenvolvimento quanto a análise.

Uma vez que você tenha um banco/esquema, precisamos definir quais tabelas receberão os logs. De novo, eu adoto um padrão: trans_LOG para log das transformações, e job_LOG para jobs. Neste caso, LOG é o nome do log capturado na tabela.

Na versão 5.4 o PDI captura os seguintes logs (com o nome da tabela que eu uso entre parênteses):

  • Transformações:
    1. Transformation (transformation): registra uma linha por transformação, por corrida. O campo LOG_FIELD contém o log de texto do processamento;
    2. Step (transformation_steps): registra um sumário do processamento de cada passo, em cada transformação, por corrida, em uma linha por passo. Ligado à anterior pela coluna ID_BATCH;
    3. Performance (transformation_performance): mede a vazão de linhas através de cada passo, segundo a segundo, em cada corrida de uma transformação, uma linha por passo, por segundo. Ligado à tabela de log de transformações pela coluna ID_BATCH;
    4. Logging channels (transformation_lc): registra os nomes e propriedades dos “canais” de dados em uma transformação ou job;
    5. Metrics (não coleto esta): http://forums.pentaho.com/showthread.php?137582-Output-steps-metrics-How-to-use
  • Jobs:
    1. Jobs (jobs): equivalente à da transformação, registra os dados de cada execução de um job em uma linha. Assim como na transformação, o mesmo campo LOG_FIELD contém toda saída de texto do processamento;
    2. Job Entry (job_entry):
    3. Job Logginc Channels (job_lc): registra os nomes e propriedades dos “canais” de dados em uma transformação ou job. Possui o mesmo layout que a logging channels das transformações. Pelo que entendi, a “boa prática” é serem a mesma.

Eu simplifiquei um pouco essas descrições, ou a coisa viraria um livro. Por exemplo, cada log possui parâmetros de tempo de vida e latência de atualização. Consultem o Pentaho Infocenter, a Wiki, o Kettle Solutions ou o Pentaho na Prática para mais informações. Nosso foco hoje é aprender a capturar e usar.


Todos esses parâmetros são entrados na aba de log das janelas de propriedades das transformações…

Aba de logs de uma transformação.
Aba de logs de uma transformação.

 

… e jobs:

Aba de logs de um job.
Aba de logs de um job.

Para chamar essa janela clique com o botão direito sobre qualquer parte em branco de um job ou transformação e, no menu que aparecer, escolha Transformation settings (ou Job settings.)

Esses parâmetros podem ser preenchidos de três maneiras:

  1. Manualmente, entrando os nomes de tabelas e valores dos parâmetros um por um, em toda transformação e job que você criar. Essa alternativa é boa para testes e estudos, enquanto você não está em projeto, por que é mais rápida e prática. Só que, se estiver em um projeto e definir todos os valores manualmente, você vai ter um trampo cabuloso para mudar qualquer coisa, pois vai ter que editar todos os artefatos, um por um, do processo inteiro;
  2. Por meio de variáveis definidas pelo desenvolvedor: defina uma variável para cada parâmetro no arquivo kettle.properties e insira-as nos lugares adequados usando a sintaxe ${VARIÁVEL}. O início é tedioso, como na opção anterior, mas é mais flexível pois basta mudar a variável no kettle.properties para propagar seu valor por todo processo. É a melhor opção quando temos vários projetos, pois podemos criar lotes de variáveis para cada um;
  3. Definindo valores das variáveis-default do PDI: esse método é de longe o mais prático para quem lida com um só projeto, pois você não precisa alterar nada em nenhuma transformação ou job. Cada campo das definições de log possui uma variável default. Definindo o valor destas no kettle.properties, o PDI configura a captura do log automaticamente. Por outro lado, se você trabalhar em mais de um projeto, vai precisar trocar essas variáveis sempre que mudar de projeto.

Alguns truques facilitam a vida do desenvolvedor: ao invés de configurar manualmente o log em todos os artefatos, crie modelos de transformação e job já configurados. Daí, quando precisar criar uma nova transformação/job, use o modelo: duplique o arquivo ou abra e salve com outro nome e comece dali. Meus modelos não apenas possuem os logs pré-configurados, como ainda deixo notas e padrões de documentação pré-preenchidos.


As variáveis são definidas no arquivo <diretório do usuário>/.kettle/kettle.properties. O Spoon oferece uma interface para fazer essa edição sem precisar sair da interface gráfica: clique no menu Edit e escolha a opção Edit the kettle.properties file. Aparecerá uma janela listando todas as variáveis default, mesmo que estejam vazias, além de todas as variáveis definidas pelo desenvolvedor:

Janela de edição do conteúdo do arquivo kettle.properties (variáveis.)
Janela de edição do conteúdo do arquivo kettle.properties (variáveis.)

Lembre-se de fechar o Spoon antes de editar o arquivo diretamente. Caso contrário, não apenas ele não vai ver os novos valores e variáveis, como ainda corre-se o risco de elas serem apagadas.

Um último detalhe: quase todos os logs são capturados por default. Quase: o de performance de passo, que é o que mais gera linhas no banco, está desligado por default. Para ativá-lo marque o checkbox Enable step performance monitoring? na aba Monitoring (a última na versão 5.4) das propriedades da transformação:

Ligue o checkbox para capturar o rendimento de cada passo da transformação.
Ligue o checkbox para capturar o rendimento de cada passo da transformação.

Criando as Tabelas

Como tudo no Spoon, sempre que algo escreve em uma tabela, um botão que permite criar ou ajustar essa tabela automaticamente. Para criar qualquer tabela de log basta preencher seus dados de conexão e nome, e clicar no botão SQL no fundo da janela de propriedades:

Criando as tabelas de log de transformação com ajuda do botão SQL.
Criando as tabelas de log de transformação com ajuda do botão SQL.

Se você preencher todos os parâmetros antes e deixar o botão de SQL para o fim, o Spoon vai te dar um monte de janelas, uma para cada tabela. O mesmo vale os logs de jobs.

Analisando Logs

Para os exemplos vamos usar o log gerado pela repetição do processo de carga do Beltrano S/A, de mil pedidos. Esse backup está disponível aqui, como um pacote RAR. Consulte as instruções de restauração da base Beltrano, lembrando apenas de substituir o nome do arquivo para o do arquivo da base de logs.

Vamos ver dois relatórios tão simples quanto úteis:

  • Logs de jobs e transformações
  • Histórico de performance

Logs de Jobs e Transformações

Quem cuida de processos de ETL sabe que a principal pergunta que se faz é “Rodou? Deu certo? O que aconteceu?”

Ok, são três perguntas, mas no fundo todas elas querem saber a mesma coisa: se o processo funcionou ou não, e o que aconteceu, se tiver dado erro.

A forma mais simples de respondê-las seria olhar o log de texto, o relato de tudo que se passou durante o processamento. É o primeiro lugar que devemos olhar porque é ali que estão as mensagens de erros. Eu chamo esse tipo de relatório simplesmente de “Relatório de Log”: Log de Jobs e Log de Transformações. Ele mostra um cabeçalho com parâmetros do objeto sendo examinado, como datas, status e duração, e logo abaixo o conteúdo de texto do processamento. A consulta que eu uso é assim:

Transformação

SELECT
     'Duracao em Segundos' as categoria,
     id_batch,
     transname,
     status,
     lines_read,
     lines_written,
     lines_updated,
     lines_input,
     lines_output,
     lines_rejected,
     replaydate,
     logdate,
     extract(hour from (logdate - replaydate))*60*60 +
          extract(minute from (logdate - replaydate))*60 +
          extract(second from (logdate - replaydate)) as duracao,
     log_field
FROM
     transformation

Job

SELECT
     'Duracao em Segundos' as categoria,
     id_job,
     jobname,
     status,
     lines_read,
     lines_written,
     lines_updated,
     lines_input,
     lines_output,
     lines_rejected,
     replaydate,
     logdate,
     extract(hour from (logdate - replaydate))*60*60 +
          extract(minute from (logdate - replaydate))*60 +
          extract(second from (logdate - replaydate)) as duracao,
     log_field
FROM
     job

Note a diferença entre os nomes dos campos dos dois artefatos (job e transformação), mas como mesmo assim são parecidos.

Essas consultas retornam todos os logs, de todas as transformações e jobs, o que é uma coisa inútil – imagine ter que varrer centenas, milhares de páginas atrás de um job ou outro! Por isso eu filtro essa consulta com dois prompts: um para nome do artefato e outro para seu batch, ou lote. As consultas para nomes são assim:

Lista de nomes de transformações:

SELECT DISTINCT transname
FROM transformation
ORDER BY transname ASC

Lista de nomes de jobs:

SELECT DISTINCT jobname
FROM job
ORDER BY jobname ASC

Quando o prompt de nome é preenchido, o prompt de lote fica disponível. As consultas para lotes são:

Lista de lotes de transformações:

SELECT id_batch,replaydate
FROM transformation
WHERE transname=${nome_transformacao}
ORDER BY id_batch DESC

Lista de lotes de jobs:

SELECT id_job,replaydate
FROM job
WHERE jobname=${nome_job}
ORDER BY id_job DESC

Com os dois prompts preenchidos (que estão marcados como obrigatórios, a propósito), o relatório roda:

Relatório de log de transformação.
Relatório de log de transformação.

Histórico de Performance

O mesmo resultado é obtido no relatório de jobs e seria redundante mostrá-lo tal como está. Vamos avançar um pouco, e mostrar o relatório de jobs com um pouco mais de informações: um histórico de duração.

Depois de saber “se deu certo”, o aspecto mais importante do ETL é sua repetibilidade. Afinal, se montamos um processo acreditando que, todo dia, ele vai rodar em menos de uma hora, precisamos saber se isso está acontecendo ou não.

Poderíamos usar o relatório anterior e, manualmente, examinar os tempos de um mesmo job ou transformação, em várias corridas ao longo de um período – uma semana, por exemplo. Trabalhoso. Bom, nós somos o pessoal da Inteligência de Negócios ou não? Como seria um vexame ter tanto trabalho, vamos ser mais práticos: vamos colocar um gráfico das várias execuções.

Pegamos o mesmo relatório anterior e acrescentamos uma nova consulta: a lista da duração das últimas X execuções em ordem crescente:

SELECT * FROM
(SELECT
     'Duracao em Segundos' as categoria,
     id_job,
     to_char(replaydate, 'DD/MM/YY HH24:MI:SS') as replaydate,
     extract(hour from (logdate - replaydate))*60*60 +
     extract(minute from (logdate - replaydate))*60 +
     extract(second from (logdate - replaydate)) as duracao
FROM job
WHERE jobname=${nome_job}
ORDER BY id_job DESC
LIMIT 30) AS X
ORDER BY id_job ASC

O SELECT interno obtém uma lista das últimas 30 execuções do job nome_job (o nome do parâmetro que contém a seleção do usuário). O SELECT externo inverte a ordem para que o gráfico seja plotado corretamente. O resultado dessa consulta para, por exemplo, o job Popula Tabelas Dependentes, é:

categoria id_job replaydate Duracao
Duracao em Segundos 2 23/02/16 20:34:24 1.064
Duracao em Segundos 5 23/02/16 20:51:37 0.671
Duracao em Segundos 7 23/02/16 20:54:54 0.655
Duracao em Segundos 11 23/02/16 21:01:08 0.652
Duracao em Segundos 14 23/02/16 21:07:54 0.742

Como um relatório pode ter apenas uma consulta ativa, e o relatório tal como está já usa uma, precisamos adicionar um sub-relatório para poder usar essa nova query. Neste sub-relatório, que herda essa consulta, adicionamos apenas o elemento de chart. Eu usei um gráfico de linhas, mas poderíamos usar qualquer outro tipo – barras, bullets, área etc.

Sub-relatório com consulta e parâmetro herdados do relatório principal.
Sub-relatório com consulta e parâmetro herdados do relatório principal.

Rodando o relatório o PRD vai exibir o prompt, já visto na figura acima. Já ao selecionar um job o gráfico será preenchido. Após selecionarmos um dos lotes – uma das corridas ou execuções do job – aparece o log logo (hehe) abaixo do plot.

Resultado: log do job selecionado, com visão simultânea das últimas execuções.
Resultado: log do job selecionado, com visão simultânea das últimas execuções.

Você pode baixar esses relatórios neste link.


Todos os materiais foram criados com a suite 5.4 do Pentaho. Se você tentar usar, e não conseguir, deixe um comentário que eu tento te ajudar.


Conclusão

Com um pouco mais de trabalho – configurar a captura de log e criar os relatórios – o gestor de ETL pode conseguir uma riqueza de informações sobre seu processo. Entre outros benefícios, o gerente de ETL passa a ser capaz de dizer, em poucos minutos, com poucos cliques, se o processo rodou hoje, se demorou mais, se deu algum erro e vários outros detalhes (incluindo volume processado e tempo de cada processamento.)

Outra função importante servida pelos logs é apoio na melhoria do processo. No próximo post veremos como usar os dados de performance das transformações para analisar o perfil de processamento e identificar gargalos.

Até lá! ;-)