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 é um CSV de 180 mb que é atualizado trimestralmente.

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

Isso é para a web, portanto, o desempenho rápido é fundamental.

Devemos usar o MySQL, mesmo que realmente não precisemos de um banco de dados relacional? Devemos 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?

Phil
fonte

Respostas:

16

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

Depois de começar a colocar seus dados em um banco de dados, seja MySQL ou qualquer outra coisa, você provavelmente descobrirá que encontrará mais usos para ele. No momento, você está falando apenas de pares de valores-chave, mas o restante dos dados relacionados aos seus produtos devem ser armazenados em algum lugar. Se isso não estiver em um banco de dados, não consigo imaginar o armazenamento de dados muito eficiente.

Faça o que fizer, não crie esses três milhões de arquivos. Vimos várias perguntas aqui já resultantes dos problemas que muitos arquivos criam.

John Gardeniers
fonte
13

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

  • Redis - Redis é um armazenamento avançado de valores-chave de código aberto. É frequentemente chamado de servidor de estrutura de dados, pois as chaves podem conter cadeias, hashes, listas, conjuntos e conjuntos classificados.
  • MemcacheDB - MemcacheDB é um sistema de armazenamento de valor-chave distribuído projetado para persistência.
  • outros (uma dessas listas pode ser encontrada aqui: http://nosql-database.org/ )

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

LazyOne
fonte
Poderíamos usar Redis, mas você acha que isso funcionaria em um P4 com 2 GB de RAM?
Phil
@ Phil Considerando que o seu arquivo CSV é de cerca de 180 MB - tudo bem. Embora o tenhamos usado em um projeto (apenas uma vez até agora), com cerca de 200 mil registros e servidor com 8 GB de RAM, é difícil para mim comparar.
LazyOne
6

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
  • Trimestral atualizado = dados essencialmente estáticos

Solução fora da caixa:

Despejar cada produto como um registro de recurso TXT e armazená-lo 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 todos os idiomas têm suporte para consultas DNS de uma forma ou de outra
  • servidores de código aberto e comerciais suportam diferentes tipos de bancos de dados 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 lidar com ordens de magnitude taxas mais altas de consultas por segundo (10.000 consultas por segundo são facilmente manipuladas com hardware comum)

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

  • você precisa pesquisar os dados (o DNS é uma pesquisa puramente de chave / valor)
  • você precisa ocultar os dados (o DNS não tem confidencialidade)
Theobroma Cacao
fonte
1
Se eu pudesse dar um ponto de bônus por originalidade, isso teria meu voto. Porém, eu não diria que o DNS é confiável, pois em uma rede doméstica típica parece mágica se funcionar e uma maldição se não funcionar.
Martin Vilcans
1
Estou intrigado. Na verdade, eu realmente gosto desta idéia, mas para mim, eu iria com algo um pouco mais tentou / testado como CouchDB
Tom O'Connor
Estive assistindo algum Monty Python?
Mark Henderson
Presumivelmente, isso seria dentro de uma rede corporativa. A confiabilidade do DNS se torna um problema quando os pacotes precisam enfrentar os perigos da Internet. Como, por padrão, o DNS usa UDP, é necessário confiar na política de retransmissão do resolvedor de DNS se um pacote for descartado. Dentro de uma rede corporativa, as chances de você obter uma perda significativa de pacotes são (provavelmente) insignificantes. E você sempre pode forçar o DNS a usar o TCP (embora com impacto no desempenho, que não é significativo neste caso). E garanto que o DNS recebe mais pesquisas do que todas as instalações do CouchDB combinadas :-).
Theobroma Cacao
Capitão Hindsight aqui. Uma palavra: blockchain.
datashaman 25/02/19
4

O MySQL com MyISAM e alguns bons índices parecem perfeitos para isso. É claro que existem muitas outras opções, mas o MySQL é amplamente suportado (se não universalmente) em qualquer host comercial. Dependendo da velocidade que você precisa, vale a pena examinar o memcached , mas sem saber o tamanho de cada par de chave / valor, armazenar 3 milhões deles na memória pode ser uma ideia ainda pior do que um arquivo CSV de 180 Mb (oh, espere, é um arquivo CSV de 180Mb, então sabemos quão grandes eles são. Eles devem ser pares muito pequenos, para que o memcached possa ser ainda melhor).

Você não deseja 3 milhões de arquivos HTML estáticos, isso prejudicará gravemente o 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.

Mark Henderson
fonte
São pares muito pequenos ... são dados muito básicos, como preço, data de fabricação, número do armazém, etc. Menos de 10 colunas. Então você acha que o MySQL é o caminho a seguir, realmente? O servidor em que ele está rodando é um P4 com 2 GB de RAM - acho que deve ficar bom?
Phil
@ Phil - So you think MySQL is the way to go, really?- não, na verdade não, mas é muito flexível e, como mencionei, suportado quase universalmente. No entanto, LazyOne postou algumas boas alternativas acima. Eu não conseguia lembrar o termo NoSQL, mas estava flutuando ao redor em minha em algum lugar do cérebro
Mark Henderson
4

Você pode usar o banco de dados Berkeley, que faz exatamente esse tipo de coisa, mesmo que não seja tão bom desde o início do Perl5. Berkeley suporta apenas pares de valores-chave e você vincula o banco de dados inteiro a um hash e o acessa como tal.

O uso de Berkeley é bem detalhado em muitas das referências mais antigas do Perl disponíveis na sua estante ou tente o Perldoc para o Módulo CPAN do BerkeleyDB . Geralmente, evito usar o Berkeley DB (embora meu empregador tenha muito código antigo em que ele seja reproduzido com destaque e alguns dos DBs sejam tão grandes quanto o seu), porque não é divertido quando seus dados ficam mais complexos.

brainbuz
fonte
2
O BDB é um skool antigo, mas muito eficaz e apropriado para essa situação.
Womble
Cuidado com a licença do Berkely DB pt.wikipedia.org/wiki/Sleepycat_license , requer que TODOS os códigos-fonte sejam disponibilizados, não apenas a parte do banco de dados.
precisa saber é o seguinte
4

Você sinalizou sua pergunta como amazon S3.

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

Isso não é um plugue para isso, mas vale a pena examinar, especialmente se você planeja usar os serviços em nuvem da Amazon.

O modelo de dados SDB se assemelha a uma planilha.

Consulte aqui para obter mais informações: http://aws.amazon.com/simpledb/ E o modelo de dados: http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/

Matt
fonte
O SimpleDB é caro. Dolorosamente, em muitos casos.
Tom O'Connor
1

Embora 180mb de dados possam ser facilmente manipulados por qualquer banco de dados relacional, eu recomendo o MongoDB ( http://www.mongodb.org/) acima do MySQL, Redis, MemcacheDB e outros armazenamentos de valores-chave mais simples ou bancos de dados relacionais. O motivo é que, para esse tipo de problema, o MongoDB é o sistema mais rápido e mais 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ê preferir. 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 de forma exclusiva para divulgar suas notícias. Você pode ter uma idéia de quão rápido é o site deles e que está online desde 1995 (o jornal online mais antigo do Reino Unido). Eles também passaram por todo tipo de gargalo no passado por causa dos bancos de dados relacionais. Por 180mb, o MongoDB servirá tudo na memória, portanto é provável que o tempo de carregamento de sub-ms seja o caso.

snez
fonte
0

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

Você disse que suas consultas são apenas simples pesquisas de chave; com a pesquisa binária, você precisa de 21 iterações na pior das hipóteses; com chaves em hash, suas consultas são ainda mais rápidas. Três milhões de registros são pequenos , desde que você evite junções (ou outras operações cartesianas do tipo de produto) e pesquisas lineares.

Ousaria dizer que praticamente tudo daria certo. Sua carga é de 30000 consultas / dia significa que (supondo que sua carga seja constante ao longo do dia), você terá 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 depois avaliar se esse é realmente o gargalo do sistema.

Lie Ryan
fonte
0

A melhor maneira de fazer isso realmente depende da qualidade e natureza dos seus dados e consultas. Para iniciantes, 180 MB de dados em uma única tabela de produtos não são um problema, seja qual for a forma como você os analisa. E 30 mil consultas por dia são ainda menos problemáticas. Com um banco de dados configurado corretamente, qualquer área de trabalho antiga pode lidar com essa carga.

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

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

Se os atributos variarem amplamente na presença e no tipo de dados, é melhor usar um banco de dados noSQL, que lida com esse cenário com mais eficiência do que os bancos de dados SQL tradicionais.

Quanto ao desempenho: trabalhei anteriormente para uma empresa de comércio eletrônico, onde por muito tempo o site foi fornecido com dados de um servidor MySQL. Este servidor tinha 2 GB de RAM, o banco de dados no total foi de aprox. Com 5 GB de tamanho e sob carga máxima, o servidor processou vários milhares de consultas por segundo. Sim, fizemos muitas otimizações de consulta, mas isso é definitivamente possível.

wolfgangsz
fonte