database non Quais problemas de escalabilidade você encontrou usando um armazenamento de dados NoSQL?




rdbms (12)

O NoSQL refere-se a armazenamentos de dados não relacionais que quebram o histórico de bancos de dados relacionais e garantias ACID. Os armazenamentos de dados NoSQL de código aberto populares incluem:

  • Cassandra (tabular, escrito em Java, usado pela Cisco, WebEx, Digg, Facebook, IBM, Mahalo, Rackspace, Reddit e Twitter)
  • CouchDB (documento escrito em Erlang, usado pela BBC e pela Engine Yard)
  • Dynomite (valor-chave, escrito em Erlang, usado por Powerset)
  • HBase (valor-chave, escrito em Java, usado pelo Bing)
  • Hypertable (tabular, escrito em C ++, usado pelo Baidu)
  • Kai (valor-chave, escrito em Erlang)
  • MemcacheDB (valor-chave, escrito em C, usado pelo Reddit)
  • MongoDB (documento, escrito em C ++, usado pela Electronic Arts, Github, NY Times e Sourceforge)
  • Neo4j (gráfico, escrito em Java, usado por algumas universidades suecas)
  • Projeto Voldemort (valor-chave, escrito em Java, usado pelo LinkedIn)
  • Redis (valor-chave, escrito em C, usado pelo Craigslist, Engine Yard e Github)
  • Riak (valor-chave, escrito em Erlang, usado pela Comcast e pela Mochi Media)
  • Ringo (valor-chave, escrito em Erlang, usado pela Nokia)
  • Scalaris (valor-chave, escrito em Erlang, usado por OnScale)
  • Terrastore (documento, escrito em Java)
  • ThruDB (documento, escrito em C ++, usado pelo JunkDepot.com)
  • Tokyo Cabinet / Tokyo Tyrant (valor-chave, escrito em C, usado pelo Mixi.jp (site de rede social japonesa))

Eu gostaria de saber sobre problemas específicos que você - o leitor de SO - resolveu usando armazenamentos de dados e o armazenamento de dados do NoSQL que você usou.

Questões:

  • Quais problemas de escalabilidade você usou no armazenamento de dados NoSQL para resolver?
  • Que armazenamento de dados NoSQL você usou?
  • Qual banco de dados você usou antes de mudar para um armazenamento de dados NoSQL?

Estou à procura de experiências em primeira mão, então, por favor, não responda a menos que você tenha isso.


Eu usei o Couchbase no passado e encontramos problemas de rebalanceamento e host de outros problemas. Atualmente estou usando Redis em vários projetos de produção. Estou usando o redislabs.com, que é um serviço gerenciado para o Redis, que cuida do dimensionamento de seus clusters Redis. Publiquei um vídeo sobre persistência de objetos no meu blog em http://thomasjaeger.wordpress.com que mostra como usar o Redis em um modelo de provedor e como armazenar seus objetos C # no Redis. Dê uma olhada.


Peço desculpas por contrariar seu texto em negrito, já que não tenho experiência em primeira mão, mas esse conjunto de postagens de blog é um bom exemplo de solução de um problema com o CouchDB.

CouchDB: um estudo de caso

Essencialmente, o aplicativo textme usava o CouchDB para lidar com seu problema explosivo de dados. Eles descobriram que o SQL era lento demais para lidar com grandes quantidades de dados de arquivamento e os moviam para o CouchDB. É uma excelente leitura, e ele discute todo o processo de descobrir quais problemas o CouchDB poderia resolver e como eles acabariam resolvendo-os.


Eu não tenho experiências em primeira mão, mas achei this blog muito interessante.


Nós movemos parte de nossos dados do mysql para o mongodb, não tanto para escalabilidade, mas mais porque é um ajuste melhor para arquivos e dados não tabulares.

Na produção, atualmente armazenamos:

  • 25 mil arquivos (60GB)
  • 130 milhões de outros "documentos" (350 GB)

com um volume de negócios diário de cerca de 10 GB.

O banco de dados é implantado em uma configuração "pareada" em dois nós (6x450GB sas raid10) com clientes apache / wsgi / python usando o mongodb python api (pymongo). A configuração do disco é provavelmente um exagero, mas é o que usamos para o mysql.

Além de alguns problemas com os pimongo threadpools e a natureza de bloqueio do servidor mongodb, tem sido uma boa experiência.


Meu projeto atual, na verdade.

Armazenar 18.000 objetos em uma estrutura normalizada: 90.000 linhas em 8 tabelas diferentes. Levou 1 minuto para recuperar e mapeá-los para o nosso modelo de objeto Java, que está com tudo indexado corretamente, etc.

Armazenando-os como pares chave / valor usando uma representação de texto leve: 1 tabela, 18.000 linhas, 3 segundos para recuperá-los e reconstruir os objetos Java.

Em termos de negócios: a primeira opção não era viável. Segunda opção significa que nosso aplicativo funciona.

Detalhes da tecnologia: rodando em MySQL para SQL e NoSQL! Continuando com o MySQL para um bom suporte a transações, desempenho e histórico comprovado para não corromper dados, dimensionar muito bem, suportar clustering etc.

Nosso modelo de dados no MySQL é agora apenas campos-chave (inteiros) e o grande campo "valor": apenas um grande campo TEXTO basicamente.

Nós não escolhemos nenhum dos novos jogadores (CouchDB, Cassandra, MongoDB, etc), porque apesar de cada um oferecer ótimos recursos / desempenho, sempre houve desvantagens para nossas circunstâncias (por exemplo, suporte a Java ausente / imaturo).

Benefício extra de (ab) usando o MySQL - os bits do nosso modelo que funcionam relacionalmente podem ser facilmente vinculados aos nossos dados de armazenamento de chave / valor.

Update: aqui está um exemplo de como representamos o conteúdo de texto, não o nosso domínio de negócios real (não trabalhamos com "produtos"), pois meu chefe me matou, mas transmite a ideia, incluindo o aspecto recursivo (uma entidade aqui um produto, "contendo" outros). Espero que fique claro como em uma estrutura normalizada isso pode ser algumas tabelas, por exemplo, unindo um produto à sua gama de sabores, que outros produtos estão contidos, etc.

Name=An Example Product
Type=CategoryAProduct
Colour=Blue
Size=Large
Flavours={nice,lovely,unpleasant,foul}
Contains=[
Name=Product2
Type=CategoryBProduct
Size=medium
Flavours={yuck}
------
Name=Product3
Type=CategoryCProduct
Size=Small
Flavours={sublime}
]

Eu encorajaria qualquer um a ler isso para tentar o Couchbase mais uma vez, agora que o 3.0 está fora da porta. Existem mais de 200 novos recursos para iniciantes. O desempenho, a disponibilidade, a escalabilidade e os recursos fáceis de gerenciamento do Couchbase Server criam um banco de dados extremamente flexível e altamente disponível. A UI de gerenciamento é integrada e as APIs descobrem automaticamente os nós do cluster, portanto, não há necessidade de um balanceador de carga do aplicativo para o banco de dados. Embora não tenhamos um serviço gerenciado no momento, você pode executar o couchbase em coisas como AWS, RedHat Gears, Cloudera, Rackspace, contêineres Docker, como o CloudSoft, e muito mais. Quanto ao rebalanceamento, depende do que você está especificamente se referindo, mas o Couchbase não reequilibra automaticamente após uma falha no nó, como projetado, mas um administrador pode configurar o failover automático para a falha do primeiro nó e usando nossas APIs você também pode obter acesso ao replica vbuckets para leitura antes de ativá-los ou usar o RestAPI você pode impor um failover por uma ferramenta de monitoramento. Este é um caso especial, mas é possível ser feito.

Nós tendemos a não reequilibrar em praticamente qualquer modo, a menos que o nó esteja completamente offline e nunca retorne ou um novo nó esteja pronto para ser balanceado automaticamente. Aqui estão alguns guias para ajudar qualquer pessoa interessada em ver o que é um dos bancos de dados NoSQL de maior desempenho.

  1. Couchbase Server 3.0
  2. Guia de administração
  3. API REST
  4. Guias para desenvolvedores

Por último, gostaria de encorajar você a verificar o N1QL para consultas distribuídas:

  1. Tutorial N1QL
  2. Guia N1QL

Obrigado pela leitura e deixe-me saber se você precisa de mais ajuda!

Austin


Nós movemos alguns dos nossos dados que usamos para armazenar no Postgresql e Memcached no Redis . Os principais armazenamentos de valores são muito mais adequados para armazenar dados de objetos hierárquicos. Você pode armazenar dados blob muito mais rapidamente e com muito menos tempo e esforço de desenvolvimento do que usar um ORM para mapear seu blob para um RDBMS.

Eu tenho um cliente open source c # redis que permite armazenar e recuperar todos os objetos POCO com uma linha:

var customers = redis.Lists["customers"]; //Implements IList<Customer>
customers.Add(new Customer { Name = "Mr Customer" });

Os principais armazenamentos de valores também são muito mais fáceis de 'escalar', já que você pode adicionar um novo servidor e particionar sua carga uniformemente para incluir o novo servidor. Importante, não há servidor central que irá limitar sua escalabilidade. (embora você ainda precise de uma estratégia para hashing consistente para distribuir suas solicitações).

Eu considero o Redis como um 'arquivo de texto gerenciado' em esteroides que fornece acesso rápido, simultâneo e atômico para múltiplos clientes, então qualquer coisa que eu usei para usar um arquivo de texto ou banco de dados embutido agora eu uso o Redis. Por exemplo, para obter um registro de erros de rolamento combinado em tempo real para todos os nossos serviços (o que notoriamente tem sido uma tarefa difícil para nós), agora é realizado com apenas algumas linhas apenas antecipando o erro para uma lista de servidores Redis e então aparando a lista para que somente os últimos 1000 sejam mantidos, por exemplo:

var errors = redis.List["combined:errors"];
errors.Insert(0, new Error { Name = ex.GetType().Name, Message = ex.Message, StackTrace = ex.StackTrace});
redis.TrimList(errors, 1000);

Eu acho que o esforço para mapear objetos de domínio de software (por exemplo, aSalesOrder, aCustomer ...) para banco de dados relacional bidimensional (linhas e colunas) exige muito código para salvar / atualizar e instanciar uma instância de objeto de domínio de várias tabelas . Sem mencionar o impacto no desempenho de ter todas essas junções, todas as leituras de disco ... apenas para visualizar / manipular um objeto de domínio, como um pedido de vendas ou registro de cliente.

Mudamos para o ODBMS (Object Database Management Systems). Eles estão além das capacidades dos sistemas noSQL listados. O GemStone / S (para Smalltalk) é um exemplo. Existem outras soluções ODBMS que possuem drivers para vários idiomas. Um benefício importante para o desenvolvedor, sua hierarquia de classes é automaticamente seu esquema de banco de dados, subclasses e tudo. Apenas use sua linguagem orientada a objeto para tornar os objetos persistentes no banco de dados. Os sistemas ODBMS fornecem uma integridade de transação no nível do ACID, portanto também funcionaria em sistemas financeiros.


Substituímos um banco de dados postgres por um banco de dados de documentos do CouchDB porque não ter um esquema fixo era uma grande vantagem para nós. Cada documento tem um número variável de índices usados ​​para acessar esse documento.


Mudei do MySQL (InnoDB) para o cassandra para um sistema M2M, que basicamente armazena séries temporais de sensores para cada dispositivo. Cada dado é indexado por (device_id, date) e (device_id, type_of_sensor, date). A versão do MySQL continha 20 milhões de linhas.

MySQL:

  • Configuração na sincronização mestre-mestre. Alguns problemas apareceram em torno da perda de sincronização . Era estressante e, especialmente no começo, podia levar horas para consertar.
  • O tempo de inserção não era um problema, mas a consulta exigia mais e mais memória à medida que os dados aumentavam. O problema é que os índices são considerados como um todo. No meu caso, eu estava usando apenas uma parte muito fina dos índices que eram necessários para carregar na memória (apenas alguns por cento dos dispositivos eram monitorados com freqüência e estavam nos dados mais recentes).
  • Foi difícil fazer backup . O Rsync não é capaz de fazer backups rápidos em grandes arquivos de tabela do InnoDB.
  • Rapidamente ficou claro que não era possível atualizar o esquema de tabelas pesadas , porque demorava muito tempo (horas).
  • A importação de dados levou horas (mesmo quando a indexação foi feita no final). O melhor plano de resgate era manter sempre algumas cópias do banco de dados (arquivo de dados + logs).
  • Mover-se de uma empresa de hospedagem para outra foi realmente um grande negócio . A replicação teve que ser tratada com muito cuidado.

Cassandra:

  • Ainda mais fácil de instalar do que o MySQL.
  • Requer muita RAM. Uma instância de 2 GB não pôde executá-la nas primeiras versões, agora ela pode funcionar em uma instância de 1 GB, mas não é uma ideia (muitos dados são liberados). Dando 8GB foi o suficiente no nosso caso.
  • Depois de entender como você organiza seus dados, o armazenamento é fácil. Solicitar é um pouco mais complexo. Mas quando você dá a volta, é muito rápido (você não pode realmente cometer erros a menos que você realmente queira).
  • Se o passo anterior foi feito corretamente, é e permanece super-rápido.
  • Quase parece que os dados estão organizados para backup. Todos os novos dados são adicionados como novos arquivos. Eu pessoalmente, mas não é uma coisa boa, liberar dados todas as noites e antes de cada desligamento (geralmente para atualização) para que a restauração leve menos tempo, porque temos menos logs para ler. Não cria muitos arquivos, eles são compactados.
  • Importar dados é rápido como o inferno. E quanto mais hosts você tem, mais rápido. Exportar e importar gigabytes de dados não é mais um problema.
  • Não ter um esquema é uma coisa muito interessante porque você pode fazer com que seus dados evoluam para seguir suas necessidades. O que pode significar ter diferentes versões de seus dados ao mesmo tempo na mesma família de colunas.
  • Adicionando um host foi fácil (embora não rápido), mas eu não fiz isso em uma configuração multi-datacenter.

Nota: Eu também usei o elasticsearch (orientado a documentos baseado no lucene) e acho que ele deve ser considerado como um banco de dados NoSQL. Ele é distribuído, confiável e muitas vezes rápido (algumas consultas complexas podem ter um desempenho muito ruim).


Eu troquei um pequeno subprojeto do MySQL para o CouchDB, para poder lidar com a carga. O resultado foi incrível.

Cerca de dois anos atrás, nós lançamos um software auto-escrito em http://www.ubuntuusers.de/ (que é provavelmente o maior site da comunidade Linux alemã). O site está escrito em Python e nós adicionamos um middleware WSGI que foi capaz de capturar todas as exceções e enviá-las para outro site pequeno com o MySQL. Este pequeno website usou um hash para determinar diferentes bugs e armazenou o número de ocorrências e a última ocorrência também.

Infelizmente, logo após o lançamento, o site traceback-logger não estava mais respondendo. Tivemos alguns problemas de bloqueio com o banco de dados de produção do nosso site principal, o que gerou exceções em quase todas as solicitações, bem como vários outros bugs, que não foram explorados durante a fase de testes. O cluster de servidores do nosso site principal, chamado de página de envio do registrador de rastreamento, várias vezes por segundo. E isso era demais para o pequeno servidor que hospedava o registrador de rastreamento (já era um servidor antigo, que era usado apenas para fins de desenvolvimento).

Naquela época, o CouchDB era bastante popular, então decidi testá-lo e escrever um pequeno registrador de rastreamento. O novo criador de logs consistia apenas em um único arquivo python, que fornecia uma lista de erros com opções de classificação e filtro e uma página de envio. E no fundo eu iniciei um processo do CouchDB. O novo software respondeu extremamente rapidamente a todas as solicitações e pudemos ver a grande quantidade de relatórios automáticos de bugs.

Uma coisa interessante é que a solução anterior estava sendo executada em um antigo servidor dedicado, onde o novo site baseado no CouchDB, por outro lado, estava sendo executado apenas em uma instância de xen compartilhada com recursos muito limitados. E nem usei a força dos armazenamentos de valores-chave para dimensionar horizontalmente. A capacidade do CouchDB / Erlang OTP de lidar com solicitações simultâneas sem bloquear nada já era suficiente para atender às necessidades.

Agora, o registrador do CouchDB-traceback rapidamente escrito ainda está em execução e é uma maneira útil de explorar bugs no site principal. De qualquer maneira, cerca de uma vez por mês o banco de dados fica muito grande e o processo do CouchDB é morto. Porém, o comando compact-db do CouchDB reduz o tamanho de vários GBs para alguns KBs novamente e o banco de dados está ativo e em execução novamente (talvez eu deva considerar a inclusão de um cronjob lá ... 0o).

Em resumo, o CouchDB foi certamente a melhor escolha (ou pelo menos uma escolha melhor do que o MySQL) para este subprojeto e faz bem o seu trabalho.


Eu não. Eu gostaria de usar um armazenamento de valor-chave simples e gratuito que eu possa chamar no processo, mas tal coisa não existe afaik na plataforma Windows. Agora eu uso o Sqlite, mas gostaria de usar algo como o Tokyo Cabinet. O BerkeleyDB tem "problemas" de licença.

No entanto, se você quiser usar o sistema operacional Windows, sua escolha de bancos de dados NoSQL é limitada. E nem sempre há um provedor de c #

Eu tentei o MongoDB e ele foi 40 vezes mais rápido que o Sqlite, então talvez eu deva usá-lo. Mas ainda espero por uma solução simples em processo.





distributed-database