Um grande banco de dados x vários menores

14

Temos uma situação em que podemos (A) implantar instâncias de aplicativos em um banco de dados MySQL usando prefixo de tabela ou (B) usar bancos de dados MySQL diferentes para cada instância do aplicativo, por exemplo,

Configurar um":

central_database
  app1_table1
  app1_table2
  app1_tablen
...
  appn_table1
  appn_table2
  appn_tablen

O resultado final é um banco de dados grande com muitas tabelas.

Instalação "B":

app1_db
  table1
  table2
  tablen

...

appn_db
  table1
  table2
  tablen

O resultado final são muitos bancos de dados com algumas tabelas.

Todas as coisas são iguais (por exemplo, quantidade de dados, número de instâncias de aplicativos etc.), quais são os prós e os contras de uma das abordagens? O que seria prejudicial ao desempenho e manutenção do banco de dados? O aplicativo é baseado no PHP 5, executado no Apache 2.xe estamos executando o MySQL 5.x.

Muito obrigado pelo seu tempo e pensamentos!

KM.
fonte
1
Veja também: dba.stackexchange.com/questions/4547/…
Derek Downey
Veja também: dba.stackexchange.com/questions/1043/…
RolandoMySQLDBA
Dado que os "bancos de dados" do MySQL são realmente esquemas (ou seja, espaços para nome), não haverá diferença no desempenho, apenas na manutenção.
mustaccio

Respostas:

14

Eu dirigi um sistema com a melhor parte de mil bancos de dados, espalhados por vários servidores. Todos eles tinham uma estrutura idêntica e foram sincronizados com um banco de dados de modelos que estava em cada uma das máquinas.

Isso me permitiu migrar bancos de dados de um banco de dados para outro, se um estava ficando sobrecarregado demais e, à medida que o mix de clientes mudava, eu podia criar novos bancos de dados em diferentes servidores para equilibrar a carga entre os servidores. Essa foi a maior vantagem que obtive do sistema, pois eu tinha vários pedaços grandes de estanho realizando várias consultas complicadas simultaneamente em servidores separados.

O melhor disso é que você pode adicionar servidores à configuração na sua própria velocidade, à medida que cada servidor começa a ficar sobrecarregado, adiciona outro ao mix, migra alguns dbs para o novo servidor e termina com um bom carregar um conjunto equilibrado de servidores. Uma maneira realmente agradável e simples de adicionar escala ao sistema como e quando necessário!

O motivo pelo qual eu segui essa abordagem, e não a única abordagem de banco de dados enorme, foi o tamanho do banco de dados em potencial que seria criado ... cada um dos 1000 bancos de dados tinha 200 tabelas e muitas das tabelas individuais em cada um dos bancos de dados. bancos de dados compreendem muitas centenas de milhões de linhas de dados!

Uma única configuração de banco de dados exigiria que determinadas tabelas (aproximadamente 8 delas) tivessem vários bilhões de linhas de dados, e o tamanho total do banco de dados teria sido superior a 10 TB. Conseguimos ter vários servidores com 5 TB de armazenamento RAID 10, com muitos bancos de dados em cada um.

Isso é o que eu faria! Espero que ajude a sua tomada de decisão ... :)

Dave Rix
fonte
Resposta legal !!! +1 !!!
RolandoMySQLDBA
@DaveRix - Como você migraria o dbs para o novo servidor sem tempo de inatividade?
Pratik Bothra 4/17/17
1
@ pratik-bothra - felizmente isso não foi um problema, pois nossa carga de trabalho do cliente era muito horário comercial e conseguimos fazer todas essas migrações fora do horário comercial. Não há 'tempo de inatividade' como tal, mas não há acesso para esse cliente durante a migração #
Dave Rix
E se você tivesse que alterar a estrutura de dados para cada um desses milhares de bancos de dados? Isso não era realmente um pé no saco?
25419 Vincent Vincent
@Incent não, pois eles foram sincronizados com um modelo usando um script personalizado. Faça uma alteração no modelo e deixe o script de sincronização funcionar nos próximos dias, à medida que os dados forem carregados nos outros bancos de dados.
Dave Rix
11

O aplicativo que você está construindo é um aplicativo SaaS? Nesse caso, sugiro que você considere uma terceira abordagem - tenha um banco de dados, com uma estrutura comum para todas as instâncias de aplicativos com uma diferença - adicione uma coluna userid / applicationid em todas as tabelas. Isso reduzirá bastante os custos de desenvolvimento / manutenção de aplicativos. Na minha experiência, essa é uma das melhores abordagens para armazenar dados de vários inquilinos.

Veja também este excelente artigo da Microsoft sobre arquitetura de dados com vários inquilinos

Também destaca as vantagens / desvantagens das abordagens que você mencionou.

Dharmendar Kumar 'DK'
fonte
1
Este é um ponto muito interessante. Embora eu concorde com isso em princípio, vale a pena considerar os riscos associados a grandes plataformas SaaS geograficamente dispersas. Por exemplo, se sua plataforma SaaS única tiver usuários nos EUA e na Europa, faria sentido ter instâncias de servidor nos dois continentes para minimizar a latência. Isso é bastante simples de obter com várias instâncias de banco de dados (e resultaria apenas em uma pequena quantidade de sobrecarga de administração de banco de dados), mas certamente é algo a ser lembrado desde o início ao projetar a camada de aplicativo da plataforma multilocatário.
Kosta Kontos
9

A configuração B é muito mais fácil de gerenciar

Cada um tablenfica em uma pasta diferente. Isso pode ser muito benéfico se você não quiser testar os limites do SO .

Por exemplo, meu empregador hospeda o MySQL para um sistema de CRM de concessionárias de carros. O cliente possui 800 concessionárias. Cada banco de dados de concessionárias possui 160 tabelas. São 128.000 mesas.

  • Na Instalação A, todas as 128.000 tabelas ficam em um banco de dados.
  • Na Instalação B, cada conjunto de 160 tabelas fica em uma subpasta em / var / lib / mysql.

Da perspectiva do sistema operacional e de sua capacidade de lidar com nós-i (ou tabelas FAT para Windows), que inclui ter um número máximo de arquivos por pasta:

  • Na instalação A, você se preocuparia com 128.000 arquivos em uma pasta. O seu sistema operacional pode suportar tantos arquivos em uma única pasta?
  • Na instalação B, não há essa preocupação.

Se você tivesse que modificar estruturas de tabela usando ALTER TABLEou algum outro DDL:

  • Na Instalação A, você teria que criar um script do DDL necessário usando PHP (ou scripts especializados do MySQL) no nome da tabela específica e nas consultas correspondentes antes de acessá-lo e fazer alterações
  • Em Configuração B, conecte-se ao banco de dados correto e acesse sempre a mesma tabela nomeada. O paradigma de acesso sempre seria limpo:
    • Banco de Dados Específico
    • Pasta específica em /var/lib/mysql
    • Nome da tabela específico.

Se você deseja colocar bancos de dados diferentes em discos diferentes:

  • Em Instalação A, links simbólicos para todas as tabelas movidas para um disco separado só exacerbam o problema "número de inodes em uma pasta". A E / S de disco e o acesso geral à tabela complica mais e aumenta a carga geral do servidor, pois os .frmarquivos são acessados ​​repetidamente.
  • Na Instalação B, basta mover uma pasta de banco de dados inteira para um conjunto de dados separado. A E / S de disco pode ser distribuída sob demanda.
  • CAVEAT: Altamente desencorajado pelo InnoDB

Falando metaforicamente, qual você prefere?

  • um apartamento gigantesco com um quarto, um banheiro e uma cozinha (SetupA)
  • vários apartamentos, cada um com seu próprio quarto, banheiro e cozinha (SetupB)

Quando se trata de consertar um radiador em um apartamento:

  • Com a Instalação A, todo inquilino pode ser incomodado e deve estar envolvido porque você precisa conversar com os inquilinos afetados na frente de todos, como se fosse um negócio de todos.
  • Com a Instalação B, além de ouvir algumas pancadas na parede ou nos canos, os inquilinos podem continuar com suas vidas particulares
  • Esta lista e suas metáforas podem continuar indefinidamente

IHMO Embora os orçamentos possam ser uma força motriz para decisões de design / infraestrutura, eu seria facilmente a favor de separar bancos de dados por cliente.

RolandoMySQLDBA
fonte
3

Também tenho um produto SaaS e uso a mesma configuração mencionada por Dave Rix.

Cada cliente tem seu próprio banco de dados

Gostaria de fazer mais algumas sugestões:

  • Você deve ter um "controlador" de banco de dados com balanceamento de carga (mestre-mestre), que armazene o local (ip) do banco de dados, o nome do banco de dados e o nome do cliente. Este controlador é onde o seu aplicativo sabe onde está o banco de dados de cada cliente.

  • Seu aplicativo pode estar onde você quiser - você pode ter bancos de dados para muitos datacenters ao redor do mundo.

  • Seu aplicativo pode crescer o quanto você quiser. Se for um Web SaaS, você pode criar um farm de servidores da Web com balanceamento de carga apontando para cada banco de dados, assim como o login do cliente.

  • Você pode criar VIEW / Database personalizado para alguns clientes - sem impactar outros. Isso é importante se você tentar oferecer personalização como parte do seu negócio.

  • Você pode configurar dois farms da Web + farms de bancos de dados: um para versões "EDGE" e outro para versões "STABLE". Então, você precisará de um pequeno grupo de clientes disposto a testar as coisas e confirmar se tudo está funcionando conforme o esperado (em outras palavras, garantia de qualidade) antes de aplicar a todos os seus clientes.

  • Você deve ter um trabalho de backup automatizado por banco de dados pelo menos uma vez por dia.

  • Você deve ter outro servidor para fazer a replicação. Um mesmo host pode replicar muitos bancos de dados (use portas diferentes para cada servidor no mesmo host) se você não puder pagar a mesma quantidade de servidores host "principais" e "escravos".

    Por exemplo, 5 servidores mestre + 1 servidor escravo com 5 bancos de dados em execução em portas diferentes - apenas têm RAM suficiente para fazê-lo.

  • Você deve fazer uma ferramenta de "migração" para mover um banco de dados para outro servidor sempre que desejar.

  • Você deve migrar clientes VIP para um servidor de banco de dados mais seguro / disponível para manter sua receita protegida. Lembre-se de que muitas vezes 20% dos clientes representam 80% de sua receita. Cuide de clientes especiais.

  • Você deve ter um coletor de "lixo" para excluir backup, para fazer um "último backup" e excluir o banco de dados quando um cliente deixar sua empresa.

  • Você deve ter uma imagem de banco de dados onde exporte e use para novas contas.

  • Você deve ter uma ferramenta de correção de banco de dados para aplicar novos patches às contas existentes.

  • Mantenha versões de todos os seus patches SQL, usando uma ferramenta de controle de versão como subversion ou git e crie sua própria numeração também. xxx-4.3.0.sql - algumas vezes o patch dá errado e você deve saber como recuperar / concluir a tarefa de patch.

Bem, isso é tudo o que faço na minha empresa com um produto que possui cerca de 5k bancos de dados com cerca de 600 tabelas cada.

b0x
fonte