Technè

Tecnologia & Experiência do Usuário no C.E.S.A.R

Introdução ao MongoDB – parte 1

Posted by Eric Cavalcanti On abril - 27 - 2011

Neste artigo vamos conhecer o MongoDB que é um banco de dados Open Source, de alto desempenho, com esquemas dinâmicos, orientado a documentos e escrito na linguagem C++.  Segundo os criadores, o MongoDB foi criado do zero, utilizando suas experiências na construção de sistemas escaláveis, de alta disponibilidade e robustez. O MongoDB também está na lista dos bancos de dados NoSQL por não ser relacional.

Instalação

O processo de instalação do MongoDB é bastante simples, basta realizar o download da versão Production Release de acordo com seu Sistema Operacional aqui. Neste artigo abordaremos a instalação no Windows, mas o processo é basicamente o mesmo em outros Sistemas Operacionais.
Após o download vamos descompactar o MongoDB é uma pasta qualquer, no meu caso D:\ e opcionalmente podemos renomear de mongo-xxxxxxx para apenas mongodb, ficando então em D:\mongodb.
O MongoDB  precisa da seguinte estrutura de pastas \data\db para armazenamento dos dados, só que a mesma não é criada automaticamente.  Então como nossa instalação está na unidade D:, vamos criar a estrutura de pastas D:\data\db.

Executando o servidor

Com tudo pronto, agora vamos executar o servidor do MongoDB. Para isso vamos executar o arquivo mongod.exe localizado na pasta bin pelo Explorer ou pela linha de comando conforme figura 1.


Figura 1. Executando o servidor MongoDB pela linha de comando.

Utilizando o cliente

Agora vamos iniciar um Shell administrativo executando o mongo.exe que também está localizado na pasta bin conforme figura 2.


Figura 2. Executando o cliente mongo.exe

Podemos perceber que por padrão o cliente conecta a base de dados test no servidor localhost. Digitando help o console exibe todos os comandos disponíveis.
Vamos digitar agora o comando:

> use mydb
switched to db mydb

Diferentemente de muitos bancos de dados existentes percebam que não é preciso executar um comando para criar um banco de dados. O mais interessante ainda é que o banco só é criado fisicamente quando os primeiros dados forem inseridos. Para confirmar executaremos o comando show dbs para exibir todos os bancos de dados:

> show dbs
admin   (empty)
local   (empty)
test    0.03125GB

Está na hora de adicionarmos algumas informações e consultá-las.

> objeto1 = { nome : "mongo" };
{ "nome" : "mongo" }
> registroNovo = { x : 3 };
{ "x" : 3 }
> db.minhaTabela.save(objeto1);
> db.minhaTabela.save(registroNovo);
> db.minhaTabela.find();
{ "_id" : ObjectId("4db5bda2eac9332a080885e8"), "nome" : "mongo" }
{ "_id" : ObjectId("4db5bdbdeac9332a080885e9"), "x" : 3 }

Agora vamos analisar o que foi executado. Inicialmente criamos dois objetos (documentos na nomenclatura do MongoDB): objeto1 e registroNovo. Percebam que eles possuem uma estrutura de campos totalmente diferente. Em seguida, adicionamos os dois objetos à tabela (coleção na nomenclatura do MongoDB) minhaTabela através do comando save(), na última linha realizamos uma consulta aos dados da tabela através do comando find().

Com isso passamos a entender o que seria o esquema dinâmico, onde não existe o conceito de estrutura de campos para uma tabela. Sendo o campo (chave na nomeclatura do MongoDB) _id criado automaticamente no momento do insert.

Bem pessoal, por enquanto é só. Aguardem os próximos posts sobre o MongoDB.

Uso de NOLOCK no Microsoft SQL Server

Posted by Thiago Veras On agosto - 13 - 2010

Para um melhor entendimento de todos e contextualização do uso de NOLOCK dentro do Microsoft SQL Server é interessante passarmos antes por algumas definições.

O LOCK é um mecanismo usado pelo Banco de Dados para bloquear conteudo na tentativa de sincronizar os múltiplos acessos de diversos usuários à mesma informação.

O uso do lock está diretamente ligado ao controle de concorrência. Este controle pode ser classificado como otimista ou pessimista. No caso do SQL Server, ele possui suporte a ambos, no entanto, o pessimista é o padrão.

Controle de Concorrência Otimista (Optimistic Concurrency Control)
No controle de concorrência otimista, o usuário não cria Locks quando faz a leituras dos dados. Desta forma, quando o usuário for atualizar dados, o sistema verifica se outro usuário está alterando os mesmos dados. Caso positivo, um erro será gerado. O controle é chamado de controle otimista porque é principalmente utilizado em ambientes onde a disputa dos dados é baixa e o custo de ocasionais Rollbacks das transações é menor do que o custo de utilizar Locks em comandos de leitura.

Controle de Concorrência Pessimista (Pessimistic Concurrency Control)
No controle de concorrência pessimista, a base de dados cria Locks que impedem usuários modificarem dados que podem afetar outros usuários de algum modo. No momento em que um usuário faz uma ação, o banco de dados cria um Lock para aquele conteúdo, desta forma, outros usuários ficam impedidos de realizarem ações que conflitem com o Lock até que o primeiro usuário acabe sua transação. O controle é chamado de controle pessimista porque é usado principalmente em ambientes onde a disputa dos dados é alta e o custo da proteção dos dados com Locks é menor do que o custo dos Rollbacks das transações se ocorrerem conflitos.

Com a definição do lock e dos controles de concorrência, fica mais fácil o entendimento do recurso NOLOCK do Microsoft SQL Server.
O NOLOCK permite executar consultas ao banco de dados sem bloquear o conteúdo. Com esta breve descrição é importante a reflexão que o recurso do NOLOCK só faz sentido no uso do Controle de Concorrência Pessimista.

Considerando este cenário, vamos nos aprofundar um pouco mais no recurso NOLOCK do Microsoft SQL Server. Ele possui duas características bem importantes:
1. Permite executar uma instrução SQL sem causar bloqueio da tabela que está sendo lida;
2. Permite ler dados não commitados.

A primeira característica é bem interessante, principalmente quando se busca performance e paralelismo. No entanto, a segunda característica precisa ser bem observada para evitar um uso indevido do NOLOCK e causar problemas no sistema. Diante disto, é muito importante que o desenvolvedor saiba exatamente o que está fazendo quando estiver utilizando o NOLOCK.
Vamos entender a sintaxe para utilização deste recurso. Segue abaixo um exemplo:

– Instrução SQL Normal:
SELECT * FROM NOTA_FISCAL ORDER BY CD_NOTA_FISCAL;

– Instrução SQL com NOLOCK:
SELECT * FROM NOTA_FISCAL WITH (NOLOCK) ORDER BY CD_NOTA_FISCAL;

Vamos agora analisar o uso para uma aplicação com as seguintes características:
1. A tabela de Nota Fiscal é modificada apenas com comandos de INSERT ou DELETE. Nunca UPDATE, pois devido ao negócio da aplicação não existe atualização das Notas.
2. Quem modifica esta tabela é apenas um procedimento de importação que roda através de um scheduler e não permite multi-threads do mesmo tipo. Ou seja, não temos nunca 2 importações de notas fiscais rodando em paralelo, elas ficam em fila se por algum motivo existir uma concorrência.
3. Existem diversas consultas e reports que precisam de acesso rápido a esta tabela de Nota Fiscal.
4. Todos os reports possuem horário de geração.

Diante destas características do sistema, o uso de NOLOCK pode ser recomendado e trazer um beneficio bem interessante a performance das consultas e reports relacionados as notas fiscais.

Vamos entender melhor esta conclusão..

Quando NÃO usamos NOLOCK e estamos no controle de concorrência pessimista, precisamos esperar que os outros procedimentos na tabela acabem para que consultas possam ser realizadas. Desta forma, denegrindo a performance de relatórios que estão rodando em paralelo a procedimentos de importação. No entanto, com o uso do NOLOCK em uma aplicação com as características descritas acima, podemos consultar os dados sem a necessidade de esperar que as importações realmente terminem, pois teremos lá o conteúdo de momento.
O report vai marcar a hora que ele foi gerado e como não são feitos UPDATES nas notas, nunca teremos dados inconsistentes. No pior caso, poderíamos ter uma nota que posteriormente ela seria cancelada (deletada), mas isto é algo comum dentro do negocio da aplicação.

O uso do NOLOCK implica em abrir mão da consistência em nome da melhor concorrência e tem suas aplicabilidades. No entanto, é importante sempre entender bem do negocio da aplicação e utilizá-lo com bom senso para que suas desvantagens não te tragam problemas piores que um problema de performance.

:BIND_VARIABLE, um detalhe que faz diferença.

Posted by Matheus Mendonça On agosto - 11 - 2010

Existem duas maneiras de enviar comandos e suas variáveis para o SGBD.  A primeira consiste em concatenar, na aplicação, antes de enviar o comando para o banco de dados o valor de todas as variáveis.  A segunda maneira é utilizando bind variables, que consiste em enviar o comando e suas variáveis separadamente.

Poucos desenvolvedores sabem os benefícios do uso de bind variables no que diz respeito à escalabilidade e desempenho, e por isso, não dão a devida importância.

Quando o SGBD recebe um comando para ser executado, o primeiro passo é realizar o parse do comando.  Durante o parse o banco de dados realiza diversas validações como verificação de sintaxe do comando e validações de segurança. Uma vez que o comando é validado o SGBD faz seu plano execução, que consiste em determinar a melhor forma para se executar o comando solicitado.  Devido ao elevado custo associado à realização da atividade de parse de um comando os SGBDs guardam em memória um histórico dos planos de execução.  Assim, nas próximas execuções do mesmo comando, o banco reutiliza as informações armazenadas anteriormente eliminando a necessidade de realizar novamente o parse desse comando.

Como, normalmente, os comandos de uma aplicação são fixos e o que muda são apenas os valores das variáveis, a utilização de bind variables permite a reutilização dos planos de execução armazenados em memória, o que resulta em um ganho de performance significativo.

Como eu acredito que o texto acima não é suficiente para convencer a maioria dos desenvolvedores vejamos na prática. O exemplo abaixo mostra um código em PL/SQL bem simples que faz um loop e executa mil vezes o mesmo select.

No primeiro caso as variáveis são concatenadas ao comando antes de enviá-lo para execução no SGBD.  A execução demorou 25.05 segundos. Agora vejamos o mesmo código utilizando bind variables.

Como o uso de bind variables a execução do mesmo código demorou apenas 0.19 segundos.

Agora esse mesmo exemplo sem o uso de bind variables em Java.

Como podemos ver acima, a execução do exemplo em JAVA sem o uso de bind Variables demorou 27,658 segundos.  Agora vejamos o mesmo código utilizando bind variables.

Como o uso de bind variables a execução demorou apenas 0.828 segundos.

Assim como no exemplo em PL/SQL, o ganho de performance obtido com o uso de bind variables no JAVA também é significativo.

Então a regra é tirar toda e qualquer concatenação dos comandos que serão enviados para o banco?  Não.  Essa técnica só se aplica para variáveis.  Além disso, comandos que não são executados freqüentemente não se beneficiarão do uso de bind variables.