Como armazenar 3 milhões de registros no formato de valor-chave?

10

Temos que armazenar informações básicas sobre 3 milhões de produtos. Atualmente, a informação é de um CSV de 180 mb, que é atualizada trimestralmente.

Haverá cerca de 30.000 consultas por dia, mas as consultas são apenas um armazenamento de valor de chave muito simples. Precisamos apenas procurar o ID do produto e exibir o restante das informações (que seriam todas em um registro).

Isso é para a web, portanto, um desempenho rápido é essencial.

Devemos usar o MySQL, mesmo que realmente não precisemos de um banco de dados relacional? Deveríamos apenas gerar 3 milhões de arquivos html estáticos a cada trimestre? Devemos armazenar um CSV de uma linha para cada produto em algo como Amazon S3 ou Rackspace Cloud Files? Qual é a melhor maneira de fazer isso?

    
por Phil 04.07.2011 / 00:42

9 respostas

16

Como o MySQL é amplamente suportado e isso é realmente uma coisa muito trivial, eu sugiro seguir com ele. A menos que o servidor tenha pelo menos alguns GB de memória, eu sugiro ficar com o MySQL em vez de usar um sistema na memória.

Uma vez que você comece a colocar seus dados em um banco de dados, seja o MySQL ou qualquer outra coisa, você provavelmente encontrará mais usos para ele. No momento, você está falando apenas sobre pares de valores-chave, mas o restante dos dados relacionados a seus produtos deve ser armazenado em algum lugar. Se não estiver em um banco de dados, não consigo imaginar o armazenamento de dados sendo muito eficiente.

Não importa o que você faça, não crie esses três milhões de arquivos. Já vimos várias perguntas aqui resultantes dos problemas que muitos arquivos criam.

    
por 04.07.2011 / 02:19
13

Você pode usar o tipo de valor-chave dedicado do banco de dados NoSQL que é otimizado para esse tipo de tarefa. Dê uma olhada:

  • Redis - O Redis é um armazenamento avançado de valor-chave de código aberto. É geralmente chamado de servidor de estrutura de dados, pois as chaves podem conter strings, hashes, listas, conjuntos e conjuntos de classificação.
  • MemcacheDB - O MemcacheDB é um sistema de armazenamento de valor-chave distribuído projetado para persistente.
  • outros (uma dessas listas pode ser encontrada aqui: link )

É claro que você pode usar o MySQL ou qualquer outro banco de dados relacional, mas soluções especialmente projetadas para tipos de dados de valor-chave supostamente melhores (caso contrário, qual é o sentido de projetá-los em primeiro lugar? exceto possivelmente o fato de que será muito menor (em termos de RAM e HDD) solução).

    
por 04.07.2011 / 00:57
5

E agora para algo completamente diferente:

Dado:

  • Produtos de 180MB / 3M = 62 bytes / produto em média.
  • 30.000 consultas por dia = 0,34 consultas por segundo
  • Atualizado trimestralmente = dados essencialmente estáticos

Solução fora da caixa:

Despeje cada produto como um registro de recurso TXT e armazene-o no DNS, por exemplo:

$origin products.example.com.

product_1_name IN TXT "product 1 description"
product_2_name IN TXT "product 2 description"
...
product_3000000_name IN TXT "product 3000000 description"

Benefícios:

  • extremamente confiável e confiável (você já depende disso todos os dias)
  • pode ser construído em praticamente qualquer plataforma
  • praticamente todo idioma tem suporte para consultas DNS de uma forma ou de outra
  • servidores comerciais e de código aberto suportam diferentes tipos de bancos de dados de back-end
  • pode ser replicado trivialmente (basta especificar vários servidores de nomes)
  • lida com atualizações atômicas, mesmo quando replicadas em uma dúzia de servidores
  • pode ser assinado criptograficamente para garantir a integridade dos dados
  • pode processar ordens de magnitude com maior taxa de consulta por segundo (10.000 consultas por segundo são facilmente tratadas com hardware de commodity)

Razões pelas quais isso pode ser uma má ideia:

  • você precisa pesquisar os dados (o DNS é puramente pesquisa de chave / valor)
  • você precisa ocultar os dados (o DNS não tem confidencialidade)
por 04.07.2011 / 22:48
4

MySQL com MyISAM e alguns bons índices soam perfeitos para isso. Existem muitas outras opções, é claro, mas o MySQL é amplamente suportado (se não universalmente) em qualquer host comercial. Dependendo da velocidade que você precisa, memcached também pode valer a pena olhar , mas sem saber o tamanho de cada par de chave / valor, armazenando 3 milhões de eles na memória podem ser uma idéia ainda pior do que um arquivo CSV de 180Mb (espere, é um arquivo CSV de 180Mb, então sabemos o quão grande eles são. Eles devem ser pares muito pequenos, então o memcached pode ser ainda melhor). p>

Você não quer 3 milhões de arquivos HTML estáticos, isso prejudicará seu sistema de arquivos. Um CSV de uma linha, mesmo no S3, terá o mesmo problema. Ninguém quer 3 milhões de arquivos em uma pasta.

    
por 04.07.2011 / 00:45
4

Você poderia usar o banco de dados de Berkeley, que faz exatamente esse tipo de coisa, mesmo que não tenha sido muito atual desde o surgimento do Perl5. O Berkeley suporta apenas pares de valores de chave e você vincula o banco de dados inteiro a um hash e o acessa como tal.

Usar o Berkeley é bem detalhado em muitas das referências mais antigas do Perl em sua prateleira ou tentar Perldoc para o módulo CPAN BerkeleyDB . Eu geralmente evito usar o Berkeley DB (embora meu empregador tenha muito código antigo no qual ele desempenha proeminentemente, e alguns dos DBs são tão grandes quanto o seu), porque não é divertido quando os dados ficam mais complexos.

    
por 04.07.2011 / 06:16
4

Você sinalizou sua pergunta como amazon S3.

Gostaria de chamar sua atenção para um de seus outros produtos relacionados chamado Amazon SimpleDB.
Parece que o modelo de dados do SimpleDB se ajustaria bem ao seu tipo de aplicativo.

Este não é um plug para isso, mas vale a pena olhar especialmente se você estiver planejando usar os serviços em nuvem da Amazon.

O modelo de dados do SDB se parece com uma planilha.

Veja aqui para mais informações: link E o modelo de dados: link

    
por 04.07.2011 / 06:40
1

Mesmo que 180MB de dados possam ser facilmente manipulados por qualquer banco de dados relacional, eu recomendo o MongoDB ( link ) acima do MySQL, Redis , MemcacheDB e outros armazenamentos de valor de chave mais simples ou bancos de dados relacionais. O motivo é que, para esse tipo de problema, o MongoDB é o sistema mais rápido e expressivo de usar, permitindo atualizações dinâmicas super rápidas sem restrições de esquema, para que seus documentos possam ter formatos diferentes se você gostar deles. Eu estava em uma apresentação do guardian.co.uk outro dia e eles tomaram uma decisão política de banir todos os bancos de dados relacionais e usar o MongoDB exclusivamente para servir suas notícias. Você pode ter uma ideia de quão rápido é o site deles e que está on-line desde 1995 (o mais antigo jornal on-line do Reino Unido). Eles também passaram por todos os tipos de gargalos no passado por causa de bancos de dados relacionais. Para 180MB, o MongoDB servirá de tudo, desde a memória, portanto, os tempos de carregamento da sub-ms provavelmente serão o caso.

    
por 04.07.2011 / 12:55
0

There will be about 30,000 queries per day, but the queries are just a very simple key value store. We only need to look up the product ID and display the rest of the information (which would all be in one record).

Você disse que suas consultas são apenas pesquisas de chave simples, com pesquisa binária você precisa de 21 iterações no pior caso, com chaves com hash suas consultas são ainda mais rápidas. Três milhões de registros são pequenos contanto que você evite associações (ou outras operações de tipo de produto cartesianas) e buscas lineares.

Eu diria que praticamente qualquer coisa faria bem. Sua carga é de 30000 consultas / dia significa que (supondo que sua carga seja constante ao longo do dia), você tem uma única consulta a cada 20 segundos; isso não é tão ruim.

Eu recomendaria implementar a tecnologia com a qual você está mais familiarizado primeiro e, em seguida, avaliar se esse é realmente o gargalo do sistema.

    
por 04.07.2011 / 09:50
0

A melhor maneira de fazer isso depende da qualidade e natureza de seus dados e consultas. Para começar, 180 MB de dados em uma única tabela de produtos não é um problema, seja qual for a maneira como você os examina. E 30 mil consultas por dia é ainda menos problemático. Com um banco de dados configurado corretamente, qualquer área de trabalho antiga pode manipular essa carga.

Outros já apontaram suas duas principais opções, o MySQL ou um banco de dados noSQL.

Se você tiver um determinado número de atributos que existem para cada produto (como fabricante, preço, número de depósito, etc., sua melhor opção é ter colunas para esses atributos e converter seus pares de chave / valor em um plano formato de tabela, com um ID de produto como a chave primária para essa tabela.Isso funcionará muito bem, mesmo que algumas colunas sejam usadas apenas pela metade das linhas, pois para a maioria dos produtos você precisará executar apenas uma consulta para recuperar todos os seus atributos Considerando que se trata de dados sobre produtos, eu acho que é bastante provável que essa seja a estrutura dos seus dados.

Se os atributos variarem bastante na presença e no tipo de dados, talvez seja melhor usar um banco de dados noSQL, que lida com esse cenário de maneira mais eficiente do que os bancos de dados SQL tradicionais.

Em relação ao desempenho: trabalhei anteriormente para uma empresa de comércio eletrônico, onde por muito tempo o site recebeu dados de um servidor MySQL. Este servidor tinha 2GB de RAM, o banco de dados no total foi de aprox. 5GB de tamanho e sob carga máxima o servidor lidou com milhares de consultas por segundo. Sim, fizemos muita otimização de consulta, mas isso é definitivamente factível.

    
por 04.07.2011 / 12:15