GPO ( Grupo de Profissionais Oracle )
A maior comunidade Oracle do Brasil !

Integrando o Oracle Database com o NoSQL Database MongoDB

Cada documento tem uma chave especial, “ID”, que é exclusivo em todas as coleções do documento.

A idéia básica é substituir o conceito de uma “linha” com um modelo mais flexível, o “Documento.” A abordagem orientada a documento torna possível representar complexas relações hierárquicas com um único registro.

Isso se encaixa muito naturalmente na maneira como os desenvolvedores nas modernas linguagens orientadas a objeto pensam sobre seus dados.

MongoDB é também um esquema livre, as chaves de um documento não são predefinidas ou fixas de qualquer maneira.

Chaves novas ou ausentes podem ser tratadas no nível do aplicativo, em vez de utilizar constraints para todos os dados terem a mesma forma. Isso dá aos desenvolvedores uma grande flexibilidade em como eles funcionam com a evolução de modelos de dados.

MongoDB foi projetado desde o início para escalar. Seu modelo de dados orientado a documento lhe permite dividir automaticamente dados entre vários servidores. Ele pode balancear dados e carga de um cluster, redistribuindo documentos automaticamente. Isso permite que os desenvolvedores se concentrem na programação do aplicativo. Quando eles precisam de mais capacidade, apenas podem adicionar novas máquinas no cluster e deixar o banco de dados descobrir como organizar tudo.

Caso de Uso: Separar Querys( Ou Relatórios) de Transações (Inserções, Updates, Deletes)

Para muitas aplicações chega um momento em que consultas ou relatórios não podem mais competir com as transações. Quando este ponto chega se faz necessário levantar uma nova base e replicar os dados, para que as consultas ou relatórios possam ser direcionados para essa nova base que terá uma carga menor que a base transacional.

A maioria dos casos de uso abordados como exemplo de uso dos bancos NoSQL e do próprio MongoDB são para aplicações Web que não necessitam das integridades referenciais e são totalmente migradas para os bancos NoSQL. Nesse artigo vamos levantar uma nova possibilidade de uso.

Vamos imaginar que temos uma loja online que precise das regras de negócio para realizar suas transações, porém como o número de vendas é muito alto, com muitas transações por minuto, as consultas e os principais relatórios estão começando a sofrer com desempenho e vamos necessitar separar as consultas das transações.

Nesse ponto poderíamos replicar a nossa base utilizando soluções como o streams, um data guard físico aberto em read only, um novo RDBMS replicado com o Oracle Golden Gate e outras soluções disponíveis no mercado, porém todas envolveriam um custo considerável e um tempo de projeto que muitas vezes poderia ser poupado com uma solução mais simples.

Nesse caso de uso, utilizando o MongoDB recebendo os dados de uma base Oracle, obtive tempos de resposta incríveis. Consultas que rodavam em segundos passaram a rodar em milésimos, tudo com um processo de replicação rápido, simples,vamos visualizar ao longo do artigo os benefícios e cuidados que precisamos para obter o melhor desta tecnologia.

Schema Oracle:

Para criarmos as tabelas podemos efetuar o download do script tabelas_model.txt que pode ser obtido nesse link:

Todos os arquivos usados e referenciados no artigo estão disponíveis neste link.

Segue o Modelo.

Vamos realizar o donwload dos scripts charge_tables.sql que serve para carregar as tabelas e o vendas.sql que é um bloco anônimo para realizar inserções e simular vendas, o processo tem o objetivo de realizar um estresse mínimo no banco para servir de comparação nesse estudo de caso.

Execute o script charge_tables.sql para popular as tabelas.

Querys e estressando o Oracle Database

Após a criação e a carga das tabelas podemos começar a realizar os testes de desempenho no banco de dados, para isso realize o download do arquivo querys.sql. Neste arquivo temos diversas consultas e views que serão utilizadas.

Em primeiro momento vamos realizar as consultas e monitorar o tempo de cada uma delas, mas antes de realizar as consultas vamos executar o bloco anônimo contido no arquivo vendas.sql[e1]  para simular vendas e transações e gerar um estresse maior.

O Meu ambiente de testes foi uma máquina com 4GB de Ram, Um Processor com 4 núcleos um HD Sata.

Os Resultados obtidos no meu ambiente foram

Consulta

Tempo em Segundos

100 Produtos mais Vendidos do dia

00:00:17.21

VENDAS POR CATEGORIA

00:00:13.76

VENDAS POR ESTADO

00:00:05.45

VENDAS POR ESTADO QUE USUARAM CREDITO

00:00:13.79

VENDAS POR FABRICANTES

00:00:18.78

VENDAS POR FABRICANTES PARA USUARIO DO RJ E SP

00:00:15.09

VENDAS POR FABRICANTES E CATEGORIAS PARA USUARIO DO RJ E SP

00:00:19.68

VENDAS POR USUARIOS QUE USARAM DEBITO

00:00:15.56

VENDAS POR USUARIOS DO ESTADO DE SP QUE COMPRARAM NA CATEGORIA ELETRONICO

00:00:14.03

Testando via Web com PHP conectando no Oracle

Para realizarmos testes mais reais, incluindo uma camada de aplicação, vamos utilizar o apache e o PHP.

Nesse Link do Site da Oracle tem o step by step de como instalar o apache e configurar o PHP para se conectar ao Oracle.

Após realizar a instalação vamos criar o arquivo relat_oracle.php com o conteúdo abaixo para monitorar em quanto tempo ele se conecta ao Oracle, realiza a consulta e retorna os resultados.

<?php

 // Create connection to Oracle

 $conn = oci_connect('loja_app', 'abc123', 'localhost/catete');

 $x=0;

 echo 'Begin:       '. date('Y-m-d-H-i-s') ."\n";

 $query = 'SELECT U.UF,COUNT(*) FROM USUARIO U INNER JOIN VENDA V ON (U.ID=V.ID_USUARIO)

 INNER JOIN TIPO_PAGAMENTO T ON (V.ID_PAGAMENTO=T.ID)

 WHERE T.ID=3

 GROUP BY U.UF';

 $stid = oci_parse($conn, $query);

 $r = oci_execute($stid);

 // Fetch each row in an associative array

 print '<table border="1">';

 while ($row = oci_fetch_array($stid, OCI_RETURN_NULLS+OCI_ASSOC)) {

   print '<tr>';

   foreach ($row as $item) {

        print '<td>'.($item !== null ? htmlentities($item, ENT_QUOTES) : '&nbsp').'</td>';

    }

   print '</tr>';

}

print '</table>';

echo 'End:       '. date('Y-m-d-H-i-s') ."\n";

?>

No meu ambiente obtive o tempo de 30 segundos na execução desse script.

Instalando e Testando o MongoDB

A Instalação do MongoDB pode ser realizada utilizando esse link da pagina oficial do MongoDB que tem o procedimento para seguir de acordo com o S.O que você vai utilizar.

Depois da instalação é necessário realizar configuração do PHP para utilizar o MongoDB, basta seguir os passos dessa página de acordo com o seu S.O.

Depois desses passos, existe um software chamado moadmin que é uma pagina web utilizada para “administrar” e gerenciar o mongoDB, é bem útil para quem não conhece nada da ferramenta.

O download pode ser realizado nesse link.

Migrando os dados do Oracle Database para o MongoDB

Após a instalação e configuração do MongoDB vamos migrar os dados do Oracle, para podermos prosseguir com os testes.

Para isso vamos utilizar um script que fiz e já disponibilizei  no meu blog, quem quiser ler basta ir neste link.

Para efetuar o download do conversor basta baixar o arquivo conn_mongo.php.  Apos o download configure as variáveis abaixo e execute o script em php que ira realizar a conversão das tabelas do Oracle (schema usado na conexão para o MongoDb) :

$db -> Vai receber o nome do database do mongo

$conn – > Vai receber os dados da sua conexão (user,pass,tns)

Verificando a estrutura dos Dados e realizando consultas.

Quando o script de migração termina de ser executado, podemos logar na pagina do moadmin escolher o banco de dados desejado e verificar as nossas collections que são semelhantes às tabelas no Oracle.

A Figura mostra em destaque no meio o nome do banco de dados (Catete) e suas collections

Ou então podemos executar o Shell do mongodb, dentro da pasta Bin da instalação e executar os comandos para visualizar as collections criadas:

use catete

switched to db catete

> show collections

FABRICANTE
CATEGORIAS
PRODUTO
USUARIO
BANCO
PERADORA
TIPO_PAGAMENTO
VENDA

Utilizando o moadmin podemos realizar consultas apenas clicando nas collections, mas se quisermos utilizar o Shell para efeutar queries no MongoDB não utilizamos SQL.

Nesse link tem um ótimo mapeamento de conversão dos principais comandos SQL para a linguagem do MongoDB.

Realizei todas as consultas do arquivo query.sql no MongoDB e todas tiveram o mesmo tempo 1 segundo( 00:00:01.00)

Migrando Views ao invés de Tabelas

Para facilitar a forma que são escritas as principais consultas do sistema criei views no banco de dados, para quando for replicar os dados no mongodb o os documentos vão ter exatamente o formato dos dados que necessitam ser extraídos.

Então agora vamos criar as views do arquivo query.sql, dropar o banco criado no MongoDB e executar o script migrat_view_mongo.php, para ele migrar as views do Oracle database para o Mongo.

Para dropar o banco no mongo, podemos clicar em drop database no moadmin ou executar o comandos

-Use (O banco que você criou)

èdb.dropDatabase();

Agora vamos efetuar o dowload e executar o arquivo migrat_view_mongo.php.

Depois vamos verificar que as collection criadas são as views migradas do Oracle.

Agora todas as consultas que realizarmos no MongoDB já estão no formato necessário para o nosso output .

Testando performance realmente com o Jmeter 

Todos os testes realizados anteriormente tiveram mais o objetivo de saber se era válido continuar com os testes, se realmente o MongoDB oferecia performance e se realmente era simples. Com esses testes singulares a diferença de tempo de 17 segundos para 1 segundo foi satisfatória para prosseguir com esses testes e a idéia de utilizá-lo quando precisamos separar transações de consultas e relatórios.

Agora vamos usar o jmeter para testar mais profundamente uma aplicação consultando no banco de dados.

JMeter é uma ferramenta utilizada para testes de carga em serviços oferecidos por sistemas computacionais. Esta ferramenta é parte do projeto Jakarta da Apache Software Foundation.

Para a realização de testes, a ferramenta JMeter disponibiliza diversos tipos de requisições e assertions (para validar o resultado dessas requisições), além de controladores lógicos como loops(ciclos) e controles condicionais para serem utilizados na construção de planos de teste, que correspondem aos testes funcionais.

O JMeter disponibiliza também um controle de threads, chamado Thread Group, no qual é possível configurar o número de threads, a quantidade de vezes que cada thread será executada e o intervalo entre cada execução, que ajuda a realizar os testes de stress. E por fim, existem diversos listeners, que se baseando nos resultados das requisições ou dos assertions, podem ser usados para gerar gráficos e tabelas.

Montando o Ambiente Para Testes.

Primeiramente vamos efetuar o download do jmeter no site.

E descompactar em alguma pasta do S.O

Para criar o ambiente vamos seguir os passos desse site.

No step 2 vamos configurar 10 threads e 10 interaçoes ( Do mesmo jeito que o tutorial indica)

No step 3 vamos apontar para o arquivo relat_oracle.php criado anteriormente.

Quando o Teste com o Jmeter for concluído, vamos testar novamente porém agora vamos criar o arquivo relat_mongo.php que faz uma consulta em uma collection que tem o conteúdo de uma view do Oracle.

No step 3 vamos alterar para apontar para esse novo arquivo.

É necessário alterar a variável $db com o nome do seu banco de dados no mongodb.

<?php

try {

  // open connection to MongoDB server

  $conn = new Mongo('localhost');

  //

access database

  $db = $conn->catete;

  //

access collection

$collection = $db->VW_VD_EST_CR;

  //

execute query

  // retrieve all documents

$cursor = $collection->find();

  //

iterate through the result set

  // print each document

  echo 'Begin:       '. date('Y-m-d-H-i-s') ."\n";

  echo "<br>";

  echo $cursor->count() . ' document(s) found. <br/>';

foreach ($cursor as $obj) {

echo 'UF: ' . $obj['UF'] . '<br/>';

echo 'Quantity: ' . $obj['QUANTIDADE'] . '<br/>';

echo '<br/>';

  }

  //

disconnect from server

$conn->close();

} catch (MongoConnectionException $e) {

die('Error connecting to MongoDB server');

} catch (MongoException $e) {

die('Error: ' . $e->getMessage());

}

echo 'End:       '. date('Y-m-d-H-i-s') ."\n";

?>

Resultados

Os resultados da comparação de performance quando separamos as consultas para o MongoDB foram extremamente mais rápidas, na minha monitoração o jmeter terminou os testes no Oracle em 5 Minutos, enquanto no MongoDB o resultado foi em 2 Segundos.

Eu monitorei o campo “Inicio da Amostra” conforme print abaixo e mostrei o tempo contabilizado nas tabelas abaixo:

Oracle

Tempo da requisição Http Inicial

Tempo da requisição Http Inicial

15:36:10

15:41:20

Mongo

Tempo da requisição Http Inicial

Tempo da requisição Http Inicial

15:45:00

15:45:02

Obviamente existem outras variáveis as quais não foram citadas nos testes, a ideia era mostrar o poder dessa ferramenta e que ela realmente pode ajudar muito quando o assunto é escalar aplicações.

Conclusão

Nesse artigo abordamos conceitualmente os bancos NoSQL e especificamente o banco orientado a documento MongoDB, utilizamos ele como caso de um em uma situação comum na vida de um DBA, quando é necessário escalar um banco de dados. Nessa solução o MongoDB se mostrou útil e eficaz.

Mas nessa solução podem ser apontadas limitações, como a questão da replicação dos dados nesse caso não ser em tempo real, nessa solução as cargas com os dados do Oracle para o MongoDB teria que ser realizada com um intervalo de tempo o que em algumas soluções pode não ser aceitável.

Nessa solução o MongoDB seria uma base exclusiva para relatórios ou somente para receber as consultas de uma aplicação, enquanto as transações e comandos DML continuariam no Oracle Database.

Seria necessário um esforço da equipe de desenvolvimento para criar um filtro na aplicação.

Ele também se mostrou apto a diversas abordagens, é possível pensar em diversas arquiteturas aproveitando ao Maximo os seus benefícios, pensando sempre em formas simples, rápidas e baratas quando se é necessário escalar um banco de dados.

Referencias

You may also like...

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Sair da versão mobile