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]
Respostas:
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.
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
fonte
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:
links aleatórios - velocidade das inserções:
fonte
Ligue para a Percona . Não passe "Go". Não colete US $ 200.
fonte
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.
fonte
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
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.
fonte
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.
fonte