Mysql: Trabalhando com 192 trilhões de registros ... (Sim, 192 trilhões)

39

Aqui está a pergunta ...

Considerando 192 trilhões de registros, quais devem ser minhas considerações?

Minha principal preocupação é a velocidade.

Aqui está a mesa ...

    CREATE TABLE `ref` (
  `id` INTEGER(13) AUTO_INCREMENT DEFAULT NOT NULL,
  `rel_id` INTEGER(13) NOT NULL,
  `p1` INTEGER(13) NOT NULL,
  `p2` INTEGER(13) DEFAULT NULL,
  `p3` INTEGER(13) DEFAULT NULL,
  `s` INTEGER(13) NOT NULL,
  `p4` INTEGER(13) DEFAULT NULL,
  `p5` INTEGER(13) DEFAULT NULL,
  `p6` INTEGER(13) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY (`s`),
  KEY (`rel_id`),
  KEY (`p3`),
  KEY (`p4`)
    );

Aqui estão as consultas ...

SELECT id, s FROM ref WHERE red_id="$rel_id" AND p3="$p3" AND p4="$p4"

SELECT rel_id, p1, p2, p3, p4, p5, p6 FROM ref WHERE id="$id"

INSERT INTO rel (rel_id, p1, p2, p3, s, p4, p5, p6)
VALUES ("$rel_id", "$p1", "$p2", "$p3", "$s", "$p4", "$p5", "$p6")

Aqui estão algumas notas ...

  • Os SELECTs serão feitos com muito mais frequência que o INSERT. No entanto, ocasionalmente, quero adicionar algumas centenas de registros por vez.
  • Em termos de carga, não haverá nada por horas e talvez alguns milhares de consultas ao mesmo tempo.
  • Não pense que posso normalizar mais (preciso dos valores de p em uma combinação)
  • O banco de dados como um todo é muito relacional.
  • Esta será a maior tabela de longe (a próxima maior é de cerca de 900k)

ATUALIZAÇÃO (11/11/2010)

Curiosamente, me foi dada uma segunda opção ...

Em vez de 192 trilhões, eu poderia armazenar 2,6 * 10 ^ 16 (15 zeros, o que significa 26 quadrilhões) ...

Mas nesta segunda opção, eu precisaria armazenar apenas um bigint (18) como o índice em uma tabela. É isso - apenas a coluna. Então, eu apenas verificaria a existência de um valor. Ocasionalmente adicionando registros, nunca os excluindo.

Então isso me faz pensar que deve haver uma solução melhor do que o mysql para simplesmente armazenar números ...

Dada esta segunda opção, devo pegar ou ficar com a primeira ...

[edit] Acabei de receber notícias de alguns testes realizados - 100 milhões de linhas com essa configuração retornam a consulta em 0,0004 segundos [/ edit]

Sarah
fonte
7
Como você está pronto para usar o MySQL para isso? Você poderia se convencer a mudar para um dbms diferente se alguém fornecer argumentos sólidos para fazer isso?
WheresAlice
3
Trilhões como em 10 ^ 12 ou como em 10 ^ 18?
Andol
15
Com 192 trilhões de registros, você deve ter um orçamento que permita fazer perguntas aos usuários do MySQL, não a alguns fóruns de discussão.
Remus Rusanu
5
Com um banco de dados tão grande (e, obviamente, um orçamento decente), por que não usar uma solução Oracle e Oracle ou SQL que comprovadamente lida facilmente com bancos de dados grandes?
Jim B
5
Certifique-se de nos manter atualizados quando implementar isso. Eu certamente estaria interessado. Você também pode querer escrever para o site highscalability.com
Tom O'Connor

Respostas:

30

A estimativa de 7PB do pQd parece razoável, e há muitos dados para um RDBMS. Não tenho certeza se já ouvi falar de alguém fazendo 7PB com qualquer sistema de disco compartilhado, muito menos MySQL. A consulta desse volume de dados com qualquer sistema de disco compartilhado será inutilmente lenta. O hardware SAN mais rápido atinge o máximo de 20 GB / s, mesmo quando ajustado para grandes consultas de streaming. Se você puder adquirir o hardware SAN dessa especificação, poderá solicitar algo mais adequado ao trabalho que o MySQL.

Na verdade, estou lutando para conceber um cenário em que você possa ter um orçamento para um subsistema de disco dessa especificação, mas não para uma plataforma DBMS melhor. Mesmo usando discos de 600 GB (a maior unidade 'corporativa' de 15K atualmente no mercado), você terá 12.000 unidades de disco físico para armazenar 7PB. Os discos SATA seriam mais baratos (e com discos de 2 TB, você precisaria de cerca de 1/3 do número), mas um pouco mais lento.

Uma SAN dessa especificação de um grande fornecedor como EMC ou Hitachi custaria muitos milhões de dólares. Na última vez em que trabalhei com um equipamento de SAN de um grande fornecedor, o custo de transferência de espaço em um IBM DS8000 foi superior a £ 10k / TB, sem incluir nenhum subsídio de capital para os controladores.

Você realmente precisa de um sistema de nada compartilhado como o Teradata ou o Netezza para esses dados. Compartilhar um banco de dados MySQL pode funcionar, mas eu recomendo uma plataforma VLDB criada para esse fim. Um sistema de nada compartilhado também permite que você use discos de conexão direta muito mais baratos nos nós - dê uma olhada na plataforma X4550 (thumper) da Sun para uma possibilidade.

Você também precisa pensar nos seus requisitos de desempenho.

  • O que é um tempo de execução aceitável para uma consulta?
  • Com que frequência você consultará seu conjunto de dados?
  • A maioria das consultas pode ser resolvida usando um índice (ou seja, eles analisarão uma pequena fração - digamos: menos de 1% - dos dados) ou precisam fazer uma verificação completa da tabela?
  • Com que rapidez os dados serão carregados no banco de dados?
  • Suas consultas precisam de dados atualizados ou você pode viver com uma tabela de relatórios atualizada periodicamente?

Em resumo, o argumento mais forte contra o MySQL é que você faria backflips para obter um desempenho decente de consultas com mais de 7PB de dados, se for possível. Esse volume de dados realmente o coloca no território de nada compartilhado para criar algo que o consultará razoavelmente rapidamente, e você provavelmente precisará de uma plataforma que foi projetada para a operação de nada compartilhado desde o início. Somente os discos vão diminuir o custo de qualquer plataforma DBMS razoável.

Nota: Se você dividir seus bancos de dados operacionais e de relatórios, não precisará necessariamente usar a mesma plataforma DBMS para ambos. Obter inserções rápidas e relatórios de segundos após a mesma tabela de 7PB será, no mínimo, um desafio técnico.

Considerando seus comentários de que você pode viver com alguma latência nos relatórios, considere sistemas separados de captura e relatório, e talvez não seja necessário manter todos os 7PB de dados em seu sistema operacional de captura. Considere uma plataforma operacional como a Oracle (o MySQL pode fazer isso com o InnoDB) para captura de dados (novamente, o custo dos discos por si só diminuirá o custo do DBMS, a menos que você tenha muitos usuários) e uma plataforma VLDB como Teradata, Sybase IQ, RedBrick, Netezza (nota: hardware proprietário) ou Greenplum para geração de relatórios

ConcernedOfTunbridgeWells
fonte
11
@ConcernedOfTunbridgeW - eles sempre podem seguir este caminho: blog.backblaze.com/2009/09/01/… - muito mais divertido do que SAN, são necessárias apenas ~ 120-130 caixas de 4U ... mas não tenho certeza se ' negócio 'seria feliz ....
pQd 08/08/10
Essencialmente, um Sun Thumper com orçamento limitado e realmente um exemplo de opção para um nó em um sistema de nada compartilhado. Tenho certeza de que já vi outras opções para isso também, mas não consigo pensar em onde. A questão não é tanto qual hardware, mas qual plataforma de banco de dados.
ConcernedOfTunbridgeWells
No entanto, observadores interessados ​​observarão que qualquer tipo de caixa baseada em conexão direta como essa é muito, muito mais barata por TB do que qualquer coisa baseada em uma SAN, que é pelo menos um argumento significativo a favor de algo projetado para funcionar em uma plataforma de compartilhamento de nada. .
ConcernedOfTunbridgeWells
@ConcernedOfTunbridgeWells e você pode executar todas essas consultas / manutenção e qualquer outra coisa em paralelo em várias caixas [caso contrário, com muita energia].
PQD
11
@ConcernedOfTunbridgeWells - para responder a suas perguntas ... Preciso de cerca de 500 consultas para retornar em menos de um segundo, se possível. Farei isso apenas algumas centenas de vezes por dia. Quando uma consulta é executada, a tabela completa precisa ser verificada. Além disso, os INSERT são uma prioridade mais baixa que os SELECT, portanto, não precisam estar nem perto do instante. Eu posso esperar algumas horas para que "novos" dados entrem no banco de dados.
21410 Sarah
16

caco. nesse tamanho, ter uma instância grande é um suicídio - pense em possíveis restaurações de backup, corrupções no espaço de tabelas, adicionando novas colunas ou qualquer outro processo de "manutenção da casa" - tudo isso é impossível de ser feito em tempo razoável nessa escala.

cálculos simples do verso do envelope - assumindo números inteiros de 32 bits para todas as colunas, exceto o ID de 64 bits; sem índices incluídos:

8 * 4B + 8B = 40B por linha [e isso é muito otimista]

192 trilhões de linhas 40B cada uma nos dá quase 7 PB

talvez você possa repensar a coisa toda, resumir informações para obter relatórios rápidos e armazenar registros compactados por intervalos de tempo determinados quando alguém precisar pesquisar detalhes mais profundos.

perguntas a serem respondidas:

  • qual é o tempo de inatividade aceitável no caso de o sistema travar / reiniciar?
  • o que é tempo de inatividade acessível quando você precisa recuperar o backup ou retirar o servidor da produção para manutenção planejada.
  • com que frequência e onde você deseja fazer backup?

links aleatórios - velocidade das inserções:

pQd
fonte
Eu concordo 7PB é bastante pesado. Adoraria repensá-lo e encontrar uma solução mais leve, mas preciso encontrar a existência (ou não) de uma combinação específica dos campos p. Dividir as tabelas passou pela minha cabeça - é mais sensato, mas isso significa que eu tenho a consulta de cada tabela por vez. Por interesse, em quantas tabelas você recomendaria dividir aqui?
Sarah
5
@ Sarah - eu não recomendaria apenas dividir em tabelas, mas também máquinas. você pode executar suas consultas em paralelo para obter desempenho [eu faço isso em menor escala]. e quanto a corrupções no sistema de arquivos ou mesmo verificação de rotina após a reinicialização do servidor? não sei o que você quer dizer com encontrar uma combinação específica ... talvez um simples armazenamento de valores-chave ajudasse? tamanho da tabela - não mais do que algumas dezenas de GB; dados em servidor único - não mais que poucos TB. veja stackoverflow.com/questions/654594 para saber qual dor de cabeça esperar em uma escala muito menor; use innodb_file_per_table
08/08
8

Ligue para a Percona . Não passe "Go". Não colete US $ 200.

JustinShoffstall
fonte
2

Pode haver outra maneira, em vez de armazenar quatrilhões de números, se tudo que você quer fazer é ver se eles estão no conjunto. Os filtros Bloom são um método probabilístico, usando hash de várias maneiras. Além disso, falsos positivos são possíveis, mas falsos negativos não são. (Então, pode-se dizer que o número está no conjunto - e estar errado, mas não diz que não está lá, se realmente estava). Ainda há a questão do grande número de itens a serem armazenados, mas pelo menos isso pode reduzir um pouco o tamanho do conjunto de dados em funcionamento.

Alister Bulman
fonte
Parece interessante, embora eu poderia viver com falsos negativos - mas não os falsos positivos :)
Sarah
2

Edit: Na verdade, se é apenas a existência ou não de um "registro" no local X em um intervalo de números inteiros, você pode eliminar o armazenamento de dados e usar o bitmap ... Então, 10 ou mais máquinas com 100 TB de espaço em disco (para que você tenha 10 cópias do seu bitmap para desempenho e backup) e, se tiver 128 GB de RAM por servidor, poderá ajustar um índice de grupo de blocos de nível superior de alta resolução na memória para fazer uma primeira verificação antes de atingir o disco pelo bit X de 26 Quadrilhões .

Eu iria para a opção 2, se você tomar:

375 máquinas com 64 TB (32 unidades de 2 TB) cada (realisticamente 400 máquinas para falhas) apenas mapeiam os registros em ZVOLs com 2 TB cada. Em um ou mais servidores de indexação, armazene em uma matriz Judy ou matriz de bits críticos, ou apenas em bitmap simples, um mapeamento de se você adicionou um registro aos 1 dos 26 locais de Quadrilhões. O índice estaria entre 50 e 100 TB e você poderia até ter um índice de segundo nível indicando se houvesse registros gravados em um determinado bloco de endereços de 64k que caberiam em menos de 64 GB de RAM e forneceriam um nível rápido de verificação inicial se um certo "bairro" estava vazio ou não.

Depois, para ler esse registro, verifique primeiro se há um registro a ser encontrado consultando o índice. Se houver, vá para a máquina # (X) / ZOL # (Y) nessa máquina / local de registro # (Z) dentro desse blob de 2 TB com base no cálculo simples do índice. As pesquisas de registro único seriam extremamente rápidas e você poderia testar o carregamento de algumas partes do armazenamento de dados em dbs diferentes (enquanto usa o armazenamento de dados para um trabalho real) e fazer testes de desempenho para verificar se eles eram capazes de suportar todo o banco de dados - ou não, basta usar o armazenamento de dados dessa maneira.

Um ZOL é uma coisa do ZFS que pode ser pensada em um arquivo esparso em outros sistemas de arquivos, portanto coisas semelhantes se aplicam. Ou você pode simplesmente indexar para um determinado número de bytes em um disco, mas isso fica complicado se os discos tiverem tamanhos diferentes, se você não limitar o número de bytes usados ​​por disco em um nível que funcione para todos os discos - ou seja, 1,75 TB por disco de 2 TB . Ou crie metadispositivos com tamanho fixo etc.


fonte
Olá Sarah - não tenho certeza se você ainda está trabalhando nisso, mas se precisar de ajuda, eu poderia criar um protótipo da minha ideia para você em uma máquina de 100 TB e também estaria disposto a hospedar (em um grande datacenter dos EUA) e gerenciar o cluster de produção completo de 400-500 máquinas, conforme necessário. BTW, você já trabalhou na CNET em SF?
1

Além de ajustar seus parâmetros de banco de dados como loucos (use o mysqltuner para ajudar) para tentar manter seus SELECTs armazenados em cache o mais humanamente possível, uma coisa que você pode investigar é START TRANSACTION / CoMMIT (assumindo o InnoDB) ao inserir algumas centenas de registros para evitar o linha por linha, bloqueando a sobrecarga e reduza o tempo de inserção por um fator enorme. Eu também criaria a tabela como MyISAM e InnoDB e executaria testes nela para ver o que é realmente mais rápido depois que o cache for reforçado - nem sempre o MyISAM será mais rápido para leituras - verifique isso:

http://www.mysqlperformanceblog.com/2007/01/08/innodb-vs-myisam-vs-falcon-benchmarks-part-1/

Durante o teste, o número de encadeamentos simultâneos também deve variar para cima e para baixo até que você encontre o ponto ideal para quanta RAM você pode pagar no servidor para dedicar ao ajuste dos caches; você pode achar que, embora possa suportar mais threads pela matemática, o próprio banco de dados pode realmente ter um desempenho pior se a contagem de threads for muito alta.

Além disso, se você usar o MyISAM e / ou o InnoDB arquivo por tabela, poderá investigar a criação de um ponto de montagem do sistema de arquivos diferente para / var / lib / mysql que foi ajustado para um tamanho de bloco menor e ajustado para os parâmetros do tipo fs - ou seja, ext3 / ext4 / resiserfs, você pode usar data = writeback para o diário e desativar a atualização dos tempos de acesso no sistema de arquivos para a velocidade de E / S.

troyengel
fonte
11
myisam parece estar fora de questão devido a requisitos de transação.
PQD
0

Para a segunda opção, quantos números provavelmente serão realmente colocados?

Se houver apenas um em mil, ou 10.000, 100.000, etc, o armazenamento de intervalos de números usados ​​(ou não usados) poderá economizar trilhões de entradas. por exemplo: storing ('free', 0,100000), ('taken', 100000,100003), ('free', 100004,584234) - dividindo linhas em duas ou três linhas, conforme necessário, e indexando o primeiro número, procure por x <= {agulha} para ver se o intervalo que contém o número pesquisado é atendido ou está livre.

Você pode nem precisar dos dois status. Apenas armazene o status menos provável.

Alister Bulman
fonte