Pergunta

Temos um banco de dados InnoDB com cerca de 70 GB e esperamos que ele cresça para várias centenas de GB nos próximos 2 a 3 anos.Cerca de 60% dos dados pertencem a uma única tabela.Atualmente o banco de dados está funcionando muito bem pois temos um servidor com 64 GB de RAM, então quase todo o banco de dados cabe na memória, mas estamos preocupados com o futuro quando a quantidade de dados será consideravelmente maior.No momento, estamos considerando uma forma de dividir as tabelas (especialmente aquela que representa a maior parte dos dados) e agora estou me perguntando qual seria a melhor maneira de fazer isso.

As opções que conheço atualmente são

  • Usando o particionamento MySQL que vem com a versão 5.1
  • Usando algum tipo de biblioteca de terceiros que encapsula o particionamento dos dados (como fragmentos de hibernação)
  • Implementando nós mesmos dentro de nosso aplicativo

Nosso aplicativo é construído em J2EE e EJB 2.1 (espero que algum dia mudemos para EJB 3).

O que você sugeriria?

EDITAR (11/02/2011):
Apenas uma atualização:Atualmente o tamanho do banco de dados é de 380 GB, o tamanho dos dados da nossa "grande" tabela é de 220 GB e o tamanho do seu índice é de 36 GB.Portanto, embora a tabela inteira não caiba mais na memória, o índice cabe.
O sistema ainda está funcionando bem (ainda no mesmo hardware) e ainda estamos pensando em particionar os dados.

EDITAR (04/06/2014):Mais uma atualização:O tamanho de todo o banco de dados é 1,5 TB, o tamanho da nossa tabela "grande" é 1,1 TB.Atualizamos nosso servidor para uma máquina de 4 processadores (Intel Xeon E7450) com 128 GB de RAM.O sistema ainda está funcionando bem.O que estamos planejando fazer a seguir é colocar nossa grande mesa em um servidor de banco de dados separado (já fizemos as alterações necessárias em nosso software) e, ao mesmo tempo, atualizar para um novo hardware com 256 GB de RAM.

Essa configuração deve durar dois anos.Então teremos que finalmente começar a implementar uma solução de sharding ou apenas comprar servidores com 1 TB de RAM, o que deve nos sustentar por algum tempo.

EDITAR (18/01/2016):

Desde então, colocamos nossa grande tabela em seu próprio banco de dados em um servidor separado.Atualmente o tamanho deste banco de dados é de cerca de 1,9 TB, o tamanho do outro banco de dados (com todas as tabelas exceto a "grande") é de 1,1 TB.

Configuração atual de hardware:

  • HP ProLiant DL 580
  • 4 x CPU Intel(R) Xeon(R) E7-4830
  • 256 GB de RAM

O desempenho é bom com esta configuração.

Foi útil?

Solução

Se você acha que ficará vinculado à E/S/memória, não acho que o particionamento será útil.Como sempre, o benchmarking primeiro o ajudará a descobrir a melhor direção.Se você não tiver servidores sobressalentes com 64 GB de memória disponíveis, você pode sempre pedir ao seu fornecedor uma 'unidade de demonstração'.

Eu me inclinaria para a fragmentação se você não espera um relatório agregado de consulta.Presumo que você fragmentaria todo o banco de dados e não apenas sua grande tabela:é melhor manter entidades inteiras juntas.Bem, se o seu modelo se dividir bem, de qualquer maneira.

Outras dicas

Você definitivamente começará a ter problemas nessa tabela de 42 GB quando ela não caber mais na memória.Na verdade, assim que ele não couber mais na memória, o desempenho será degradado extremamente rapidamente.Uma maneira de testar é colocar essa tabela em outra máquina com menos RAM e ver o desempenho dela.

Primeiro de tudo, não importa tanto dividir as tabelas, a menos que você também mova algumas das tabelas para um volume físico separado.

Isso está incorreto.O particionamento (seja por meio do recurso do MySQL 5.1 ou pela mesma coisa usando tabelas MERGE) pode fornecer benefícios significativos de desempenho mesmo se as tabelas estiverem na mesma unidade.

Por exemplo, digamos que você esteja executando consultas SELECT em sua grande tabela usando um intervalo de datas.Se a tabela estiver inteira, a consulta será forçada a percorrer toda a tabela (e nesse tamanho, mesmo o uso de índices pode ser lento).A vantagem do particionamento é que suas consultas só serão executadas nas partições onde for absolutamente necessário.Se cada partição tiver 1 GB de tamanho e sua consulta precisar acessar apenas 5 partições para ser atendida, a tabela combinada de 5 GB será muito mais fácil para o MySQL lidar do que uma versão monstruosa de 42 GB.

Uma coisa que você precisa se perguntar é como está consultando os dados.Se houver uma chance de que suas consultas precisem acessar apenas determinados blocos de dados (ou seja,um intervalo de datas ou intervalo de ID), algum tipo de particionamento será benéfico.

Ouvi dizer que ainda há alguns erros no particionamento do MySQL 5.1, principalmente relacionados à escolha da chave correta pelo MySQL.As tabelas MERGE podem fornecer a mesma funcionalidade, embora exijam um pouco mais de sobrecarga.

Espero que ajude, boa sorte!

Este é um ótimo exemplo do que o particionamento MySql pode fazer em um exemplo real de enormes fluxos de dados:

http://web.archive.org/web/20101125025320/http://www.tritux.com/blog/2010/11/19/partitioning-mysql-database-with-high-load-solutions/11/1

Esperando que seja útil para o seu caso.

Há algum tempo, em um evento do Microsoft ArcReady, vi uma apresentação sobre padrões de escala que podem ser úteis para você.Você pode veja os slides para isso on-line.

Eu escolheria MariaDB InnoDB + Partições (por chave ou por data, dependendo de suas dúvidas).

Fiz isso e agora não tenho mais problemas de banco de dados.

O MySQL pode ser substituído pelo MariaDB em segundos... todos os arquivos do banco de dados permanecem os mesmos.

Primeiro de tudo, não importa tanto dividir as tabelas, a menos que você também mova algumas das tabelas para um volume físico separado.

Em segundo lugar, não é necessariamente a mesa com maior tamanho físico que você deseja mover.Você pode ter uma tabela muito menor que recebe mais atividade, enquanto sua tabela grande permanece razoavelmente constante ou apenas anexa dados.

Faça o que fizer, não implemente você mesmo.Deixe o sistema de banco de dados cuidar disso.

O que a grande mesa faz.

Se for dividir, você tem algumas opções:
- Divida usando o sistema de banco de dados (não sei muito sobre isso)
- Divida por linha.
- divida por coluna.

Dividir por linha só seria possível se seus dados pudessem ser facilmente separados em pedaços.por exemplo.Algo como Campo de base tem várias contas completamente separadas.Você poderia manter 50% das contas em uma tabela e 50% em uma tabela diferente em uma máquina diferente.

A divisão por coluna é boa para situações em que o tamanho da linha contém campos de texto grandes ou BLOBS.Se você tiver uma tabela com (por exemplo) uma imagem de usuário e um enorme bloco de texto, poderá agrupar a imagem em uma tabela completamente diferente.(em uma máquina diferente)

Você quebra a normalização aqui, mas não acho que isso causaria muitos problemas.

Como sempre, o benchmarking primeiro o ajudará a descobrir a melhor direção.

Isso é o que a maioria das pessoas me diz, então acho que finalmente terei que tomar aquela pílula...

Você provavelmente iria querer dividir aquela mesa grande eventualmente.Você provavelmente desejará colocá-lo em um disco rígido separado antes de pensar em um segundo servidor.Fazer isso com MySQL é a opção mais conveniente.Se for capaz, então vá em frente.

MAS

Tudo depende de como seu banco de dados está sendo usado, na verdade.Estatisticas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top