Bancos de dados não relacionais e o movimento NoSQL

Nas grandes aplicações web é cada vez mais comum a quantidade de informações ser enorme, e ainda temos uma certeza: amanhã teremos mais dados para armanezar. Como lidar com isso de maneira eficiente?

Muito se fala ultimamente sobre os novos bancos não relacionais. Houve um encontro inicial e a segunda conferência também já aconteceu. O movimento acabou ganhando o nome de NoSQL, até mesmo por que cada banco de dados tem uma maneira diferente de se escrever queries.

A grande motivação para NoSQL é resolver o problema de escalabildade dos bancos tradicionais. Pode ser muito caro ou/e complexo escalar um banco SQL.

Esse movimento está bastante enraizado no open source. Dá para perceber isso até mesmo pelos curiosos nomes dos projetos: Voldemort, MongoDB, Tokyo Tyrant e CouchDB.

Apesar de grande quantidade desses bancos serem open source, o movimento ganhou muita força com a publicação de dois papers sobre implementações proprietárias: o Google Bigtable (que a Caelum usa atualmente) e o Amazon Dynamo. Não por acaso são duas empresas que lidam com uma quantidade enorme informações. Outros grandes nomes participam do movimento NoSQL: Yahoo! (Hadoop com HBase, Sherpa), Facebook e Digg (Cassandra), LinkedIn (Voldemort), Mixi (Facebook do Japão) (Tokyo Cabinet) e a Engine Yard (MongoDB).

Muitos acham que esses bancos de dados escalam simplesmento por causa da ausência de um schema (schema free), logo não há verificação de integridade e de relacionamentos. Mas seria só isso? O MySQL, nos seus primórdios, quando não fazia tais verificações, ainda assim não era rápido como esses novos competidores. Quais são então os segredos para tanta escalabilidade?

O Amazon Dynamo se destacou por causa da forma como o sistema escala. Cada nó no cluster comunica com outros nós (p2p) e faz ativamente parte da partição/replicação. Não tem um single-point-of-failure, mas essa facilidade de escalar não vem sem custo.

Todos os novos bancos tem em comun que eles são key-value stores, ou seja salvam, como o nome sugere, um conjunto de enradas formadas por uma chave associada a um valor e o valor poderia ser de qualquer tipo, um binário ou string que está sendo salvo de forma denormalizada (schema-free). Diferentemente dos bancos SQL não existe uma esquema forte. Essa abordagem facilita a distribuição dos dados entre vários servidores onde cada servidor possui apenas uma fatia dos dados (shard).

O CouchDB é um dos mais famosos no time dos key-value stores. Ele usa documentos para definir uma estrutura no banco, armazenando uma chave associada ao um documento. Um documento é apresentado como JSON. Por exemplo:

{
  "Subject": "Bancos não relacionais"
  "Author": "Nico Stepat"
  "PostedDate": "10/15/2009"
  "Tags": ["database", "nosql", "rest"]
}

Repare a estrutura dos dados é definido através da aplicação, o CouchDB não exige nada, apenas um documento JSON.

Talvez o CouchDB ficou famoso por causa da simples API REST e do uso do JSON, ou da interface grafica bonita ou por causa dos views interessantes usando Map-Reduce ou da replicação Multi-Master ou por que foi escrito em Erlang (como esse e esse também). Seja que for, a promessa principal do NoSQL – sendo escalável – o CouchDB não compriu ainda. Ele não é distribuído sozinho, e precisa de ajuda externa para tal.

Outra forma de dar alguma estrutura aos dados ficou famosa por causa do Google Bigtable. A idéia é não salvar os dados em linhas como estamos acustomados pelos bancos relacionais. Os dados serão salvos através de colunas. Veja a diferença:

Row-Oriented (3 rows presentes – Nome, Salário, Data):

João,1432.00,15/10/2009
Maria,1511.00,13/10/2009
Pedro,1721.00,01/10/2009

Column-Oriented (mesmo exemplo):

João,Maria,Pedro
1432.00,1511.00,1721.00
15/10/2009,13/10/2009,01/10/2009

No column-oriented vem primeiro TODOS os dados da primeira coluna Nome, depois a segunda coluna Salario e por último a coluna Data.

E isso altera algma coisa? Para o desenvolvedor que vai utilizar o banco de dados, a idéia é que isso seja transparente, mas para quem desenvolveu o banco, há enormes melhorias.

Isso não é muito vantajoso quando for salvo apenas um registro, como cada coluna tem que ser accessada separadamente. Também complica mais na recuperação de um registro específico (random-access) pelo mesmo motivo. Aqui a abordagem row-oriented tem vantagens.

Por outro lado, usando colunas, podemos empacotar os dados melhor já que os dados semelhantes, de mesmo formato, estão próximos um do outro. Gravando dados empacotados em BDs traz grandes vantagens, porque podemos recuperar e armanezar mais informações em menos tempo.

Com colunas também podemos aplicar projeções sobre os dados mais fácil. A segunda vantagem é importante principalmente para sistemas OLAP (online analytic process) que usam esse tipo de pesquisas pesadamente.

Banco de dados orientados a coluna vão além de um simples key-value store. Eles representam normalmente um array/hash de 4 ou 5 dimensões, usando ou adaptando o modelo proposto pelo BigTable.

Primeiramente, também temos tabelas só que eles chamem column-families. Como o nome indica um column-family são váras colunas. Quais são essas colunas, a aplicação define.

Cada coluna salva um valor. O grupo de colunas dentro de uma familia é acessível atraves de uma chave (row-key). O esquema fica:

  • columnFamily – parecido com uma tabela (tabela de colunas)
  • rowKey – ID do grupo de colunas
  • column – nome da coluna
  • value – valor a salvar

<columnFamily>.<rowKey>.<column> = <value>

Por exemplo, para apresentar dados sobre um DVD com a ID 234:

    <dvds>.<234>.<nome> = 'Beleza americana'
    <dvds>.<234>.<ator_principal> = 'Kevin Spacey'
    <dvds>.<234>.<ano> = '1999'

ou para apresentar um usuário com joao.silva:

    <usuarios>.<joao.silva>.<nome> = 'Joao Silva'
    <usuarios>.<joao.silva>.<email> = 'joao.silva@foo.com'

e o relacionamento:

   <usuarios_dvds>.<joao.silva>.<234> = ‘data que ele comprou’

Normalmente é salvo uma data automaticamente, ou seja, a estrutura completa fica:

   <columnFamily>.<rowKey>.<column>.<timestamp> = <value>

Os bancos orientados a coluna não oferecem joins entre column-families nem chaves compostas. A Google AppEngine, por exemplo, não aceita chaves compostas porque usa o BigTable por baixo. Existem pequenas diferenças entre implementações orientadas a coluna.

Seria o “início do fim” dos bancos relacionais? Aderindo a um banco de dados não relacional muita da responsibilidade de cuidar dos dados fica a cargo da aplicação. É ela que define como funcionam e como se relacionam os documentos. O banco fica com certeza mais simples, escalavél e rápido, mas perdemos as conhecidas garantias dos bancos relacionais. Como toda decisão arquitetural, escolher por bancos de dados não relacionais apresenta um trade off: ACID ou BASE ou alguma coisa no meio. Vale a pena? Cada caso deve ser estudado com cuidado. Algumas aplicações usam bancos de dados não relacionais para uma leitura e escrita temporária, atualizando um banco relacional de tempos em tempos, tirando vantagem das duas estratégias.

Semana que vem, no Caelum Day in Rio conversaremos sobre muitos outros detalhes do movimento NoSQL. Nos encontramos lá!

35 Comentários

  1. Paulo Silveira 30/10/2009 at 20:43 #

    Boa Nico!

    A Amazon ja esta indo um passo alem, e oferecendo no cloud do EC2 acesso a um MySQL modificado, que dizem estar bem rápido e oferecendo a consistencia de dados de sempre, mas com certeza não tão rapido quanto os bancos key-value!

    http://www.infoq.com/news/2009/10/Amazon-RDS-MySQL

  2. Nico Steppat 02/11/2009 at 17:46 #

    Oi Paulo,

    Só alguns pensamentos referente ao seu comentario no blog:

    Mesmo sendo no cloud, um banco de dados relacionais continuam com os
    mesmos vantagens/desvantagens. Não tem como fugir das regras do CAP
    theorem. Nesse caso vc vai sacrificar network partition tolerance
    (além do desempenho e limite de espaço – que talvez não importe). Por
    isso a Amazon fala que a chance de erros aumenta quanto maior o block
    device (EBS), e fala o tempo todo sobre o backup no S3. RDS só
    funciona no mesmo availablity zone (diminuindo a chance de network partitions).

    Sistemas que precisam tolerar network partitions não vão escolher
    RDS, pq em caso de uma falha no EBS o banco fica fora de ar.
    De fato o RDS não é distribuido (o que é distribuido, é o EBS). Por
    exemplo, existe um downtime uma vez por semana para fazer uma
    manutenção.

    Em geral, a cloud não pode resolver os problemas de RDBMS, pq o
    problema tem a raiz em sistemas distribuidos que compartilham dados. É o tradeoff que vc paga. RDS não é concorrencia para NoSQL.

    Acho que o RDS é fantastico porque é PaaS, oferencendo o banco como
    servíco, oferencendo em um quase SAN no cloud (EBS), tirando a dor de cabeça
    da configuração e administração e gastos para dba, liçencas, hardware etc.

    Vou falar sobre isso na palestra.

    Abraços!

  3. Germano 03/11/2009 at 08:18 #

    Ótimo artigo! O nível de vocês está fora do comum, ainda bem que temos a caelum no Brasil! hehehe. Só que poderia ter aqui em SC também :)
    Valeu

  4. Edmilson Prata 04/11/2009 at 11:24 #

    Acho essa tendência muito perigosa considerando que, mesmo com todos os recursos que um banco relacional oferece temos bases de dados de péssima qualidade e os profissionais da área se “descabelam” para tentar torná-las minimamente consistente.

    Outra coisa que não vejo com bons olhos é a falta de uma linguagem comum entre estes produtos. Qualquer profissional que já viveu momentos assim sabe muito bem o mal que isso faz ao mercado.

    Acredito que estas soluções têm seu lugar no mercado, mas que bancos relacionais, com os recursos que conhecemos, não deixarão de existir.

  5. Leandro 04/11/2009 at 14:27 #

    Muito bom o artigo. Vários links importantes. Parabéns!

  6. krico 04/11/2009 at 18:02 #

    A oracle já se manifestou a respeito?

  7. Nico Steppat 04/11/2009 at 20:31 #

    @Edmilson:

    Como vc falou, NoSQL não é um substituto para os bancos relacionais. É uma ferramenta para um lugar onde bancos relacionais falham ou se tornam muito complexos.

    Além disso, nem todos os bancos “novos” são eventualmente consistente. Por exemplo, HBase, BigTable ou Scalaris são fortemente consistente. Os que não são, alguns oferecem recursos para evitar a falta de consistência (por exemplo Cassandra com Quorum Reads).

    E sim falta uma linguagem comum entre os bancos, mas com Lucene, Pig ou Hive (e tem esse jaql) tem soluções.

    Obrigado pelo comentário!

    Nico

  8. Nico Steppat 04/11/2009 at 20:36 #

    @Crico

    Pelo que eu sei não. Talvez pq já existe o Oracle RAC que traz escalabilidade para o banco relacional e o Oracle Coherence, um cache e datagrid que pode ser usado na frente do banco.

    Nico

  9. brunoric 05/11/2009 at 13:33 #

    Edmilson Prata disse que isso faz mal ao mercado. Eu discordo e acho que faz é muito bem que não exista um padrão estabelecido. Os padrões são bons em assuntos onde as soluções padrão são claramente as melhores ou as de melhor custo/benefício. Talvez a falta de uma linguagem única leve a um desenvolvimento maior dessas tecnologias em separado. Enfim post muito interessante!

  10. Bruno Borges 05/11/2009 at 21:57 #

    Tem um forte movimento a favor de Apache CouchDB e Hadoop.

    Aqui na ApacheCon, tem mais de 150 pessoas de olho no Hadoop, e hoje na sessao do CouchDB, tinha mais de 40. Muita gente migrando pro movimento NoSQL… :-)

  11. Bruno Fuster 12/11/2009 at 19:24 #

    Excelente post. Obrigado!

  12. Bispo 17/11/2009 at 11:44 #

    Lendo esse artigo penso – é aquilo, quando comecamos a trabalhar com BD relacionais, demos Gracas a Deus que nossos problemas de quebra de integridade e outros ‘pelos’ foram resolvidos, principalmente pq na minha época quando tínhamos grandes sistemas feitos em Clipper com DBF.

  13. Nico Steppat 17/11/2009 at 12:44 #

    @Bispo

    Isso aqui é diferente. A possível quebra de integridade ou/e consistência não é uma abandono da engenharia dos últimos 20 anos, é o sacrifício (tradeoff) que vc paga em um sistema distribuído.

    Serviços como S3 ou GAE (BigTable) são exemplos populares que mostram que isso é viável.

    []’s,
    Nico

  14. Flávio R. C. Sousa 23/11/2009 at 21:22 #

    Link relacionado muito interessante:
    http://horicky.blogspot.com/2009/11/nosql-patterns.html

  15. André (ASOBrasil) 25/11/2009 at 13:49 #

    Achei esse post sensacional! Parabéns!

  16. Sérgio Luiz Araújo Silva 12/03/2010 at 09:27 #

    Com relação à padronização dos modelos propostos penso que tão logo um tipo em particular ganhar destaque ele tenderá a tornar-se um padrão, sem bem que o SQL tem seus dialetos em cada banco. Certamente os tempos são outros, a quantidade de informações cresce exponencialmente. O fato de o google que tem lá alguns bites armazenados :) estar de olho nesta novidade deveria ser uma boa indicação para os profissionais, não acham? Aproveito pra perguntar, o google usa python só porque é divertido? ou isto lhe traz vantagem competitiva?

  17. Suissa 05/05/2010 at 15:48 #

    Estamos começando um blog apenas sobre NOSQL e tive que linkar esse artigo lá, muito bom PARABÉNS!

  18. Bruno Ambrozio 08/05/2010 at 19:53 #

    Caros,
    Só tenho que agradecer… Estou adentrando a este mundo open source e cada artigo, site, evento, tweets, (etc) que acompanho só aumenta minha lista de “a pesquisar!” (:P
    Muito bacana esta discussão, estou entusiasmado para alcançar este nível de intelectualidade! Espero que logo possa participar e contribuir também! Por enquanto, só os parabenizo e os agradeço por aumentarem meu leque de conhecimento!

  19. Marcus Danilo R. Cabral 17/08/2013 at 11:25 #

    eu gostaria de saber como vocês vejam essa realidade no atual mundo web?em relação ao banco de dado não convencional?

  20. José Cristiano Graciliano Rocha 22/09/2013 at 17:49 #

    Interessante sua matéria:
    O sistema Column-Oriented é de certa forma um cross-table;
    Penso sempre em uma forma de dar semântica aos dados principalmente os vindos da web – facebook por exemplo, e o grande problema que vejo e enfrento é a redundância nas informações; Não consegui ainda uma forma associar uma chave ou um conjunto delas fazendo chave composta.
    Acho que este vai ser o meu TCC.

  21. Paulo Silveira 23/09/2013 at 18:50 #

    José Cristiano, poste seu TCC pra gente quando estiver pronto!

  22. Vantuir 01/12/2013 at 19:42 #

    Boa noite,
    Estou com uma duvida, tenho q entregar meu tcc no proximo semestre, e meu tcc é montar uma rede social estudantil interna, somente podera participar quem for da escola, qual bando de dados seria eu ultilizar, um relacional ou não relacional?

    DEUS abençoe……

Deixe uma resposta