Introdução ao NoSQL parte II

Ter, Abr 6, 2010

NoSQL

No post anterior nós falamos sobre os problemas que levaram a criação dos bancos de dados NoSQL.Uma diferença importante é que na maior parte dos casos estes procedimentos são feitos automaticamente facilitando assim a vida dos desenvolvedores. O nosso leitor @loboweissmann levantou a questão de como os bancos de dados NoSQL resolvem os problemas de escalabilidade que apontamos para os bancos de dados relacionais.

Técnicas mais usadas para escalar bancos de dados

As técnicas utilizadas pelos bancos NoSQL são muitas vezes as mesmas que os programadores experientes em bancos de dados relacionais tem utilizados por anos para escalar seus sistemas mas de uma maneira otimizada e muitas vezes automática. Como bem lembrado no post anterior pelo @dirs “O que vale é usar a ferramenta certa.” não esperem que um banco de dados NoSQL vai ser uma silver bullet para os seus problemas de escalabilidade, em alguns casos vai ser tão difícil escalar um banco não relacional quanto um banco relacional. Por isso é importante entender as ferramentas disponíveis para fazer o melhor uso possível das suas capacidades.

Replicação – Escalar por duplicação de informações

Neste caso nós copiamos as informações em mais de um banco para aumentar nossa capacidade de recuperar estas informações. Podemos dividir em duas “arquiteturas” principais :

Master-Slave:

Cada escrita em banco resulta em N x escritas onde N é o número de slaves. Neste caso temos um banco “Master” que propaga cada write para os bancos “slaves”. Isto aumenta a nossa velocidade de leitura mas não melhora em nada nossa capacidade de escrita. Muitos desenvolvedores entendem hoje como “escalabilidade” simplesmente adicionar mais um slave em seu banco de dados. Isto pode ser uma boa solução inicial caso a maior parte da carga do seu banco venha de leituras. Porém esta estratégia não é recomendada para casos em o volume de escrita é muito grande.

Multi-Master:

Aumentamos o número de Masters em nosso sistema e assim aumentamos nossa capacidade de escrita. Esta abordagem pode gerar conflitos. Existem muitas técnicas para resolução de conflitos. Isto vai além do escopo deste post. Se você quiser se aprofundar mais no assunto leia este paper da microsoft.

Sharding – Escalando por divisão

Uma alternativa muito conhecida é o Sharding. Dividimos os dados em múltiplas tabelas do banco para escalar tanto nossas leituras como nossas escritas. Isto traz o grande problema de “quebrar” a lógica de relacionamentos o que é o grande forte dos bancos relacionais. As aplicações tem que resolver a complexidade gerada pela partição de informações como por exemplo a execução de joins e outros comandos. Fazer sharding manualmente não é simples e exige considerável esforço da equipe de desenvolvimento.

No caso dos bancos de dados NoSQL muitas destas mesmas técnicas que eu acabei de descrever são utilizadas. Porém em geral elas são invisíveis para o desenvolvedor o que facilita o desenvolvimento de aplicações para dados em larga escala. Porém o ecossistema que está surgindo em torno do termo “NoSQL” é muito grande e diversificado tornando assim difícil a tarefa de fazer generalizações. Vamos então tentar utilizar algumas das características básicas dos bancos não relacionais para poder classificá-los.

Classificação de bancos de dados NoSQL

Existem hoje um grande número de sistemas que se enquadram no conceito de NoSQL vamos separar estes sistemas de acordo com 4 características principais : Arquitetura,Armazenamento, Modelo de Dados.

Arquitetura

Quanto a arquitetura podemos dividir os bancos de dados NoSQL em dois tipos : distribuídos e não distribuídos.  Os distribuídos tomam a responsabilidade pela partição dos dados e pela sua replicação.

Distribuidos :

  • Amazon Dynamo
  • Scalaris
  • Voldemort
  • CouchDb (thru Lounge)
  • Riak
  • MongoDb (in alpha)
  • BigTable
  • Cassandra
  • HyperTable
  • HBase

Não distribuídos:

  • Redis
  • Tokyo Tyrant
  • MemcacheDb
  • Amazon SimpleDb

Armazenamento

Podemos dividir os sistemas entre aqueles que armazenam dados em disco e os que armazenam na memória.  Esta diferenciação é importante por que no caso da gravação em disco você vai precisar de um cache explicito.  Já os dados armazenados em memória não são duráveis.

Memória:

  • Scalaris
  • Redis

Disco:

  • CouchDb
  • MongoDb
  • Riak
  • Voldemort

Configurável

  • BigTable
  • Cassandra
  • Hbase
  • HyperTable

Modelo de dados

Chave/Valor

  • Amazon Dynamo
  • Amazon S3
  • Redis
  • Scalaris
  • Voldemort

Documento

  • Amazon SimpleDb
  • Apache Couchdb
  • MongoDb
  • Riak

Colunas

  • Cassandra
  • Google BigTable
  • HBase
  • Hyperbase

Grafo

  • Neo4j
  • InfoGrid
  • Sones
  • HyperGraphDB
, , , ,

Por:

Que escreveu 39 posts em Escalabilidade.


Fale com o autor

  • http://pomoti.com Dirceu Pauka Júnior

    Legal o post :)

    Não conhecia o Lounge, cool…
    http://code.google.com/p/couchdb-lounge/

    Sobre a falta de durabilidade no Redis, pode ser resolvida com “Append only file”
    http://code.google.com/p/redis/wiki/AppendOnlyF

  • http://www.sanainside.com Diego Sana

    De fato o post tem umas caneladas em relação ao Redis :)

    Quanto ao armazenamento, a classificação dele seria “Configurável”. Por padrão, o Redis faz um snaspshot do que está armazenado em memória e salva isso no disco a cada X minutos ou X modificações. Como o dirs falou, pode-se usar também persistência via append only, que funciona de forma semelhante a um transaction log de um rdbms, e é configurável em relação a quando é feito o fsync com o disco. E se vc quiser, pode desabilitar tudo isso e usar como um cache em memória apenas.

    Quanto ao modelo de dados, ele é mais do que só chave/valor. Acho que o redis teria uma categoria própria, algo do tipo “Banco distribuído de estruturas de dados básicas”, já que nele vc pode armazenar os dados em listas, sets, tabelas hashs.. ou seja, as estruturas de dados que os tios da computação ensinam nos primeiros períodos da faculdade :)

  • http://loogica.net/blog Felipe

    Opa..
    Qual o critério para dizer que o CouchDB é distribuído e o Redis não?

    Conceitualmente o CouchDB não é distribuido porque o poder de processamento nao aumenta na grandeza O(n) onde N seriam o número de instancias… as escritas são serializadas.. nao podem ser feitas em paralelo…

  • edmarferreira

    Oi Felipe,

    Interessante o seu questionamento. Você vai notar em muitas descrições de bancos NoSQL como o Cassandra esta característica de ser um bando distribuído. Quando estamos falando de banco de dados o termo não se refere diretamente a “Sistemas Distribuídos” que muitos aprendem na faculdade e sim a um conceito especifico.
    O fato de um banco ser ou não distribuído não está de modo algum relacionado diretamente ao aumento proporcional do poder de processamento. O conceito se refere a um banco de dados que funciona de maneira distribuída ou seja é como se você tivesse uma única instancia de banco que funciona ao longo de varias maquinas
    sendo que isto é na maior parte dos casos completamente invisível ao desenvolvedor. Perceba que isto é diferente de simplesmente replicar um banco em esquemas Master/Slave como é feito com o Redis nestes casos o que você tem são instâncias diferentes de banco que se comunicam. Nos bancos distribuídos como é o caso do HBase que funciona sobre o HFS ( equivalente open source ao GFS, Google File System ) você tem o processo de replicação e acesso as várias máquinas feito pelo próprio gerenciador automaticamente.

    Caso você queira se aprofundar mais no assunto veja as seguintes páginas da documentação do CouchDB :

    Na introdução do CouchDB ( http://couchdb.apache.org/docs/intro.html)

    What CouchDB is

    Distributed, featuring robust, incremental replication with bi-directional conflict detection and management.

    No Technical Overview ( http://couchdb.apache.org/docs/overview.html )

    CouchDB is a peer-based distributed database system, it allows for users and servers to access and update the same shared data while disconnected and then bi-directionally replicate those changes later.

  • http://alertachuvario.loogica.net/ felipe

    Eu discordo.. a partir do momento em que o banco de diz distribuido, e o seu poder de processamento não aumenta com a inclusão de um nó, pra mim ele é um banco com replicação.

    Sugiro que leia mais atentamente a documentação do couchdb.. Só pode existir uma escrita por vez: http://horicky.blogspot.com/2008/10/couchdb-imp

    Dada essa premissa, pra mim o couchdb é um banco de dados com a feature de replicação e não um banco de dados distribuido

    Quote:
    O fato de um banco ser ou não distribuído não está de modo algum relacionado diretamente ao aumento proporcional do poder de processamento

    Sim, está.. caso contrário é um banco de dados com replicação. E sim.. um banco de dados distribuido tem que ser um sistema distribuido, como se aprende na faculdade..

    Se a replicação é transparente.. é outra coisa..

    Cassandra e dynomite são distribuidos de verdade.

  • http://alertachuvario.loogica.net/ felipe

    Outro ponto..

    “Quando estamos falando de banco de dados o termo não se refere diretamente a “Sistemas Distribuídos” que muitos aprendem na faculdade e sim a um conceito especifico. “

    Não quero ser rude, mas “quanto estamos falando”.. quem?

    Eu entendo um banco distribuido como um sistema distribuido de banco de dados. Oracle, cassandra, etc..

  • edmarferreira

    Quote:
    “Sugiro que leia mais atentamente a documentação do couchdb.. Só pode existir uma escrita por vez”

    O ponto é que “Distribuído” não é igual a “Paralelo” .

    São dois conceitos diferentes que pelo que eu estou entendendo do seu argumento você considera como uma única coisa. Em boa parte dos casos vamos ter sim bancos com escrita em Paralelo ( Veja que no caso do CouchDB as leituras são em paralelo ) E distribuídos mas isto não se aplica sempre uma vez que não necessariamente se um banco é distribuído ele vai ser paralelo.

    Sua argumentação falha no sentido de dizer que o CouchDB não é Distribuído por que não escreve em paralelo.

    Neste artigo disponibilizado no site da Stanford sobre bancos Oracle tem uma definição interessante que pontua a diferença a que eu estou me referindo :

    http://www.stanford.edu/dept/itss/docs/oracle/1

    The terms distributed database and distributed processing are closely related, yet have distinct meanings. There definitions are as follows:

    Distributed database

    A set of databases in a distributed system that can appear to applications as a single data source.

    Distributed processing

    The operations that occurs when an application distributes its tasks among different computers in a network. For example, a database application typically distributes front-end presentation tasks to client computers and allows a back-end database server to manage shared access to a database. Consequently, a distributed database application processing system is more commonly referred to as a client/server database application system.

    Veja que a definição de Bancos Distribuídos não leva em conta a necessidade de escritas em paralelo, para ser sincero nunca vi uma definição que tenha esta exigência a que você está se referindo.

    Vamos a definição da wikipédia :

    A distributed database is a database that is under the control of a central database management system (DBMS) in which storage devices are not all attached to a common CPU. It may be stored in multiple computers located in the same physical location, or may be dispersed over a network of interconnected computers.

    http://en.wikipedia.org/wiki/Distributed_database

    Em muitos casos vamos ter sim um processamento completo distribuído como esclarecido no primeiro artigo. Mas em nenhuma das definições é explicito ou implícito que writes paralelos precisam acontecer.

    Gostaria de saber de onde vem esta definição de serem considerados bancos de dados distribuídos apenas bancos que fazem writes em paralelo.

  • http://alertachuvario.loogica.net/ felipe

    Existe uma diferença conceitual entre banco de dados e sistemas de gerenciamento de banco de dados.

    O couchdb tem seu banco de dados distribuidos. OK. Os dados realmente estão distribuidos.

    O sistema de gerenciamento de banco de dados do couchdb não é distribuido. Ele não é capaz de realizar como um sistema distribuido, ou seja, na sua definição, processamento paralelo, todo o dominio de suas funções

    DB != RDBMS.. é simples..

    Como voce se atém muito a detalhes, vamos la. O couchdb se diz um banco de dados distribuido. Não é. É um sistema de gerenciamendo de banco de dados com replicação.

    É falácia se vender como distribuído porque quem escolher o Couchdb para sua aplicação e instanciar 10 nós em 10 máquinas diferentes, vai ver que o desempenho de escrita é amarrado ao nó de pior performance.

    As suas menções a papers e artigos da wikipedia não te ajudam em nada porque no final das contas oq vc esta afirmando é: basta ter várias instancias distribuidas e essa distribuição ser transparente pra dizer que um banco é distribuido.

    Pra mim, é necessário muito mais que isso… é necessário que todo o dominio de operações possa ser processado paralelamente entre os nós para que exista um ganho em poder de processamento.

  • http://readwriteweb.com.br/ dttg

    Discussão bacana por aqui.

  • http://alertachuvario.loogica.net felipe

    Do proprio site de stanford que voce mencionou..

    Distributed database systems employ a distributed processing architecture.

    Bancos de dados distribuidos empregam uma arquitetura de processamento distribuido.

    O meu ponto todo é de que é injusto colocar Cassandra e Couchdb como distribuidos, na mesma categoria..A 'distribuição' do couchdb é parcial.. do cassandra é total.. como o autor do post disse q existem 3 caracteristicas que classificam os bancos NoSQL, por favor, pelo menos separe o couchdb do cassandra e dos outros… o couchdb tem uma limitação séria e ele não funciona como a maioria das pessoas vai achar q ele funciona..

    só isso..

  • http://readwriteweb.com.br/ dttg

    Quando você diz “para mim” é porquê este é um conceito pessoal que você criou ou é algo amplamente aceito? Eu entendo que o Couch tem algumas restrições com relação ao cassandra, mas isso não o torna não distribuído…. Tanto CouchDB qto MongoDB tem usos bem diferentes do Cassandra. Mas isso não os torna não distribuídos.

  • edmarferreira

    O próprio pessoal do Redis se define como “advanced key-value store” ou como “data structures server” :) .
    Não acredito que o fato de ter values como estruturas mais complexas faz com que o Redis deixe de ser considerado key-value.

    Quanto ao armazenamento o Redis eu não consideraria Configurável. O padrão como o Sana disse é gravar de tempos em tempos no disco. Ou seja no modo padrão do Redis os dados não são armazenados direto no disco. E mesmo caso você escolha persistir tudo em disco o que você vai ter será um tipo de arquivo de backup para reconstruir o estado do banco na memória, até onde eu sei não tenho a opção de configurar o Redis para usar disco ao invés de memória o que a principio mataria a própria premissa do banco.

  • http://loogica.net/blog Felipe

    Isso o torna PARCIALMENTE distribuído, porque a restrição simplesmente nao faz com que ele escale com o aumento no número de nós..

    Eu nao sou o unico a falar disso.. http://spyced.blogspot.com/2008/12/couchdb-not-

    E quando eu falei pra mim, me desculpe, pareceu leviano demais. Mas o proprio artigo apontado pelo edmar disse:

    Distributed database systems employ a distributed processing architecture.

    Se o couchdb nao emprega o processamento distribuido, logo ele não é um sistema de gerenciamento de dados distribuído.

    é um sistema de gereciamento de dados com replicação transparente. ou PARCIALMENTE distribuido…

    Não sei se vc leu o ultimo post.. mas eu(ai sim, uma opinião pessoal) acho injusto colocar na mesma categoria quem é TOTALMENTE e quem é PARCIALMENTE distribuido.

    abs

  • http://readwriteweb.com.br/ dttg

    Eu acho que entendi o seu ponto. Vc sugere uma categorização por um critério diferente. Ao invés de distribuição, vc quer categorizar pela capacidade de gravar em paralelo, é isso?
    Eu concordo que os bancos orientados a documentos tem aplicações bem diferentes de um cassandra ou um hbase.
    Seu ponto é que dentro dos bancos distribuídos teriamos 2 categorias de bancos, separadas pela capacidade distribuir e paralelizar processos?

  • http://loogica.net/blog Felipe

    da uma olhada aqui: http://escalabilidade.com/2010/03/08/introducao

    repare que o termo “scale out”: Aumentar o número de máquinas de servidores

    No couchdb qdo vc aumenta o numero de nós, voce nao tem ganho de desempenho para escrita.. isso é terrivel.. várias outras opções escalam aumentando o numero de nós.. para TODAS as operações..

    meu reciocinio é simples..

    um brinco de ouro é um brinco feito de ouro e prata ou apenas ouro?
    um banco distribuido é um que processa de forma distribuida e indepentende TODAS as operações ou apenas leituras?

    talvez eu tenha sido um pouco detalhista demais.. pense como um cliente comprando um produto que se diz distribuido.. e quando voce monta seu setup com 10 maquinas e ve que as escritas nao sao paralelas.. voce nao ficaria insatisfeito?

    repare que eu nao estou desmerecendo o projeto muito menos o post.. so quis complementar com uma informação que eu julgo importante

  • carribeiro

    É interessante comparar a evolução do NoSQL com o estado da arte do mercado de banco de dados *antes* que o SQL varresse a concorrência, lá em meados nos anos 90.

    Quem mexia com software em PCs nos anos 80 certamente se lembra de sistemas como o dBase, de onde vieram depois o Clipper e o FoxPro, e também das bibliotecas de indexação. Era comum ter que implementar algoritmos como B-Tree manualmente, para gerar os arquivos de índice. Nos mainframes, existiam diversas soluções, várias delas eram do tipo “file of record” (quem já leu um programa em COBOL sabe do que eu estou falando). Nessa época, a maioria dos programadores jamais tinha ouvido falar do que seria um “join”.

    Nessa época, o trabalho com banco de dados era caracterizado por uma mentalidade de “processamento em lotes”. Um programa fazia um loop sobre uma tabela (oops, “arquivo”) e ia buscando dados em outros, para compor o resultado desejado. Para otimizar o processo, os índices eram mantidos manualmente. Era comum gravar resultados parciais e agregados dentro das próprias tabelas, para evitar um loop completo sobre o arquivo (obs: qualquer semelhança com a nova onda de denormalização nao é mera coincidência). Isso era especialmente importante se você considerar a taxa de transferência dos discos da época. Outra técnica comum era dispor de programas que deveriam ser executados uma vez por dia, manualmente ou de forma agendada, para limpar registros deletados, compactar índices, e recalcular agregados.

    A migração em massa para o SQL aconteceu em meio a uma revolução composta de vários fatores. As novas interfaces gráficas permitiram separar a camada de apresentação da camada de negócio. O conceito de “cliente servidor” encontrou estações poderosas para rodar “clientes ricos”, e servidores com novas tecnologias (NT!) capazes de rodar programas genéricos com relativa facilidade. A capacidade de processamento e memória dos servidores tornou o overhead da interpretação da linguagem SQL aceitável. E a capacidade (e velocidade) dos HDs foi crescendo, viabilizando a manutenção de bases cada vez maiores e mais sofisticadas dentro do servidor.

    O uso intensivo do SQL gerou como efeito colateral uma postura “comodista” em relação ao banco de dados. Ao contrário da geração anterior, a maioria dos programadores que aprendeu sua profissão nos últimos 10 ou 15 anos jamais teve que se preocupar com os “detalhes ocultos” do banco de dados. Eu acredito que isso é um dos culpados pela percepção prevalente de que “SQL não escala”. Na verdade, SQL “padrão” tem problemas e limites de escalabilidade, que se tornam evidentes na escala de um Google, Facebook ou Twitter. No entanto, para a maioria dos programadores, o problema não é o SQL em si, mas a falta de conhecimento sobre como o banco de dados funciona.

    É interessante olhar as coisas sob essa perspectiva histórica, porque ela nos mostra de forma muito clara que vários problemas que tratamos hoje com NoSQL já existiam antigamente, em outro nível de escala e de performance, mas seguindo princípios muito similares. A grande diferença do cenário atual para aquele de 20 anos atrás está no uso intensivo de paralelismo e comunicação em redes (praticamente inexistentes até o fim dos anos 80); mesmo assim, por mais simplista que possa parecer, algumas das técnicas mais recentes tem raízes no antigo processamento em lotes. O que estes exemplos nos mostram é que existem técnicas simples para contornar vários problemas; com um pouco de criatividade, e com *muito* pragmatismo, é possível criar soluções inteligentes e largamente escaláveis. Só que isso exige que o programador tenha um conhecimento mínimo sobre a arquitetura do banco de dados e seu funcionamento interno – coisa que para a maioria dos programadores, é como falar grego. Daí, fica mais fácil aderir a uma nova onda – que é o NoSQL mas poderia ser qualquer outra coisa, sem que necessariamente tenham conhecimento suficiente para explorar as plataformas atuais ao máximo.

    Digo isso tudo para argumentar que o SQL “tradicional” ainda tem MUITA lenha para queimar, especialmente agora que o assunto está sendo tratado seriamente. Para mim, o mais importante no debate do NoSQL não é o “not only” e nem mesmo o “no” que alguns insistem em lembrar; é trazer para a discussão aspectos da tecnologia que muita gente jamais se preocuparia em pesquisar, se não fosse o tema da moda.

  • suissa

    Muito boa a discussão sobre sistemas distribuídos, mas no meu ver todas as operações deveriam ser distribuídas e não só a leitura.

  • Pingback: NoSQL, A evolução das bases de dados. | Coruja de TI

  • Pingback: » Introdução ao NoSQL : Uma tecnologia emergente ## Johnatan Oliveira ~~ joww.net – Internet, Tecnologia, Música e Vida Profissional

  • Gray

    Depende do caso. Em um dos projetos de onde eu trabalho, notamos que em produção, é feito em torno de 150 selects pra cada insert/update (somados)

    Portanto, otimizamos somente para leitura, o que tornou o processo muito menos complicado