Admins/Sharding

De Wiki Expresso V3
Ir para: navegação, pesquisa

Conteúdo

Sharding de Banco de Dados

Objetivo

Para ambientes com grande número de usuários, a carga sobre um único banco de dados (BD) pode exigir um servidor SGBD com hardware muito robusto.

O Sharding tem como objetivo particionar as informações e distribuir a carga entre dois ou mais servidores de BDs.

Para mais informações, veja a seção Referências.

Conceitos básicos sobre Sharding

No Sharding, as linhas das tabelas são particionadas em vários BDs.

As linhas das tabelas são agrupadas por uma chave única, denominada Chave de Shard (Shard Key).

Todas as linhas associadas a uma determinada Shard Key são armazenadas em um mesmo BD.

Cada Shard Key é associada a um Virtual Shard, que é associado a um BD.

Exemplo:

  • Sendo a Shard Key o campo de e-mail do usuário;
  • O usuario_1@empresa.gov.br esta associado ao Virtual Shard 1;
  • O usuario_2@empresa.gov.br esta associado ao Virtual Shard 2;
  • O usuario_3@empresa.gov.br esta associado ao Virtual Shard 2;
  • O usuario_4@expresa.gov.br esta associado ao Virtual Shard 3;
  • O Virtual Shard 1 e o Virtual Shard 3 estão associados ao banco de dados 1;
  • O Virtual Shard 2 esta associado ao banco de dados 2:

Nesse exemplo, podemos concluir que as informações dos usuários 1 e 4 estão armazenadas no banco de dados 1, enquanto que as informações dos usuários 2 e 3 estão armazenadas no banco de dados 2.

Resharding é o processo feito quando desejamos redistribuir os dados entre os BDs. Podemos, por exemplo, mover parte dos dados que estão nos BDs existentes para um novo BD.

Exemplo de Resharding:

  • Fazendo Resharding para reassociar o Virtual Shard 2 ao novo banco de dados 3;
  • Os dados do usuario_2@empresa.gov.br e do usuario_3@empresa.gov.br são movidos do banco de dados 2 para o banco de dados 3;
  • O Virtual Shard 2 passa a a ser associado ao banco de dados 3;

Configuração Inicial

Antes de iniciar a configuração, certifique-se que sua instalação do ExpressoV3 multi domínios esta funcionando.

Em seguinda precisamos adicionar a seguinte linha de código no arquivo init_plugins.php

Tinebase_Core::setShardPlugin('Custom_Plugins_Shard');

Vamos configurar Shard para o backend separado de ActiveSync. Esse backend separado gerência as tabelas:

- tine20_acsync_device

- tine20_acsync_folder

- tine20_acsync_content

- tine20_acsync_synckey

- tine20_acsync_policy

Vamos criar dois BDs contendo estas tabelas: asdb1 e asdb2

E também vamos realizar as configurações necessárias para que o shard distribua os registros dos usuários nesses dois BDs.

Preparando novas instalações do Expresso

Para instalações do Expressov3 que ainda não estão em produção vamos fazer o seguinte.

Criar dois BDs com os nomes asdb1 e asdb2.

No setup gráfico, configurar o backend separado para Activesync, apontando para o asdb1 e instalar o módulo ActiveSync.

Com a instalação do módulo, as tabelas, índices e chaves estrangeiras serão criadas no BD.

Replique as estruturas do asdb1 para o asdb2. Com isso o BD asdb2 ficará igual ao asdb1.

Nesse exemplo o domínio serpro.gov.br esta sendo configurado.

Edite o arquivo domains/serpro.gov.br/config.inc.php e adicione as seguintes linhas para indicar que o backend "asdatabase" usará arquivo de nfiguração shard1.inc.php

'shard' =>
array (
  'asdatabase' => 'shard1',
),

Crie (ou faça cópia do template domais/default/shard.inc.php.dist) o arquivo domais/serpro.gov.br/shard1.inc.php com o seguinte conteúdo:


<?php
return array (
   'numberOfVirtualShards' => 1000,
   // Class that defines the strategy to obtain ShardKey
   'shardKeyStrategy' => 'LoginName', // Class Tinebase_Shard_Shardkey_Strategy_XXXXXX
   // Class that defines the strategy of Association Shardkeys => Virtualshards
   'associationVirtualshardShardkeyStrategy' => 'ModOfDivision', // Class Tinebase_Shard_Association_Virtualshard_Shardkey_Strategy_XXXXXX
   // Backend Association Virtualshards => Connectionconfigkeys
   'associationVirtualshardConnectionconfigkeyClass' => array(
       'class' => 'Filesystem',
       'options' => array(
           'filePath' => '/shardfiles'
           )
       ),
   // Backend Connectionconfigs
   'connectionConfigClass' => array(
       'class' => 'Filesystem',
       'options' => array(
           'filePath' => '/shardfiles'
           )
       ),
   // Backend Flag to control resharding state
   'reshardingFlagClass' => array(
       'class' => 'Filesystem',
       'options' => array(
           'filePath' => '/shardfiles')
       ),
   // Backend associations Shardkeys => Connectionconfigkeys, during reshard processing
   'reshardingAssociationShardkeyConnectionconfigkeyClass' => array(
       'class' => 'Filesystem',
       'options' => array(
           'filePath' => '/shardfiles'
           )
       ),
);

Crie uma pasta para armazenar os arquivos de controle do shard. Se a sua infraestrutura possui mais de um frontend, crie esta pasta em um sistema de arquivos compartilhados, como por exemplo NFS (Network Filesystem), para que esses arquivos sejam compartilhados por todos frontends.

Vamos criar em nosso exemplo a pasta /shardfiles para armazenar os arquivos de controle. Atribua direitos para que o usuário do Apache (www-data) possa criar arquivos nessa pasta.

Agora vamos começar a criar os arquivos de controle.

Primeiro precisamos criar o arquivo /shardfiles/connectionConfig.asdatabase.serpro.gov.br com as seguintes configurações de conexão de BD. Isso deve ser feito através da execução de comandos CLI:

  'db1' =>
  array (
    'active' => true,
    'adapter' => 'pdo_pgsql',
    'port' => 5432,
    'host' => 'localhost',
    'dbname' => 'asdb1',
    'username' => 'tine20user',
    'password' => 'serpro',
    'tableprefix' => 'tine20_',
  ),

e

'db2' =>
  array (
    'active' => true,
    'adapter' => 'pdo_pgsql',
    'port' => 5432,
    'host' => 'localhost',
    'dbname' => 'asdb2',
    'username' => 'tine20user',
    'password' => 'serpro',
    'tableprefix' => 'tine20_',
  ),

Isso será feito executando os seguintes comandos CLI, onde o parâmetro username deve ser um usuário com perfil de administrador:

sudo -u www-data php tine20.php --domain serpro.gov.br --username dogbert@serpro.gov.br --method Tinebase_Shard.connectionConfig 
-- database='asdatabase' operation='set' values="{'db1':{'host':'localhost';'dbname':'asdb1';'username':'tine20user';'password':'serpro';
'adapter':'pdo_pgsql';'tableprefix':'tine20_';'port':5432}}" outputlogfile='/tmp/connectionconfig.log'

sudo -u www-data php tine20.php --domain serpro.gov.br --username dogbert@serpro.gov.br --method Tinebase_Shard.connectionConfig 
-- database='asdatabase' operation='set' values="{'db2':{'host':'localhost';'dbname':'asdb2';'username':'tine20user';'password':'serpro';
'adapter':'pdo_pgsql';'tableprefix':'tine20_';'port':5432}}" outputlogfile='/tmp/connectionconfig.log'

Se por engano criamos por exemplo a configuração db2 de conexão com DB com algo errado, podemos excluir através do seguinte comando:

sudo -u www-data php tine20.php --domain serpro.gov.br --username dogbert@serpro.gov.br --method Tinebase_Shard.connectionConfig 
-- database='asdatabase' -- operation='remove' values='db2' outputlogfile='/tmp/connectionconfig.log'

Continuando, vamos configurar o arquivo associationVirtualshardConnectionconfigkey.asdatabase.serpro.gov.br, que mantém a associação entre VirtualShards x Conexões com BDs. No nosso exemplo vamos apontar todos os 1000 VirtualShards para o db1. Com isso todos os usuários, em princípio, só usarão o BD asdb1.

sudo -u www-data php tine20.php --domain serpro.gov.br --username dogbert@serpro.gov.br 
--method Tinebase_Shard.associationVirtualshardConnectionconfigkey -- database='asdatabase' key='db1' 
fromvirtualshard=0 tovirtualshard=999 outputlogfile='/tmp/associationVirtualshardConnectionconfigkey.log'

Mais adiante vamos ver como apontar determinado usuário para o BD asdb2 usando a funcionalidade 'resharding'.

A qualquer momento podemos gerar uma consulta para saber quais usuários estão associados a quais BDs. Vamos executar o seguinte comando e posteriormente visualizar o resultado gerado em /tmp/associations.txt

 sudo -u www-data php tine20.php --domain serpro.gov.br --username dogbert@serpro.gov.br 
--method Tinebase_Shard.getAssociationOfShardKey -- database='asdatabase' shardkey='all' outputlogfile='/tmp/associations.txt'

No arquivo /tmp/associations.txt veremos algo semelhante a isso:

06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): VirtualShard | ShardKey | ConnectionConfigKey
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 60; emerson-faria.nobre@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 60; joao.maria@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 106; pedro.maria@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 106; maria.pedro@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 167; ana.pedro@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 229; ana.ana@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 235; fabiano.ana@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 303; teste@serpro.gov.br; db1

Analisando esse resultado, veremos por exemplo que a Shard Key emerson-faria.nobre@serpro.gov.br esta associada ao VirtualShard 60, o qual esta associado ao db1. Em outras palavras o usuário emerson-faria.nobre@serpro.gov.br usará o BD asdb1.

Para testar o funcionamento do Sharding, crie uma conta ActiveSync no dispositivo móvel para sincronizar. Veja se registros serão criados nas tabelas do BD asdb1. Também é possível acompanhar o funcionamento verificando o log do Expresso. Se, por exemplo, seu arquivo de log é o expressov3.log:

 tail -f /tmp/expressov3.log | grep  -A 1 -i "Shardkey:"

...
0ec57 86928023953 - 2015-08-13T17:25:36+00:00 INFO (6): Tinebase_Shard_Manager::getConnectionConfig::237 Shardkey: emerson-faria.nobre@serpro.gov.br, 
Shard: 648, Backend Connection Config Key: db1
...

Migrando instalações existentes do Expresso para usar Sharding

A primeira etapa da ativação do Shard para ambientes que já estão em produção consiste em configurar o Shard apontando para o BD existente. Dessa forma teremos um Shard em um único BD. Posteriormente, cria-se um segundo BD e faz uso da operação de Resharding para mover parte dos dados para o novo BD.

No exemplo do Shard do backend separado para ActiveSync que introduzimos anteriormente, devemos no setup gráfico habilitar o backend separado para ActiveSync apontando para o BD atualmente em produção, seguir as instruções de forma análoga da secção anterior para configurar o Shard e por fim seguir o raciocínio da secção posterior para realizar a operação de Resharding.

Fazendo Resharding

Antes de realizar uma operação de resharding, o sharding já deve estar funcionando.

Em nosso exemplo, estamos usando atualmente o BD asdb1 para todos usuários.

Primeiro, vamos consultar quais usuários em quais Virtuais Shards.

 sudo -u www-data php tine20.php --domain serpro.gov.br --username dogbert@serpro.gov.br 
--method Tinebase_Shard.getAssociationOfShardKey -- database='asdatabase' shardkey='all' outputlogfile='/tmp/associations.txt'

No arquivo /tmp/associations.txt veremos:

06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): VirtualShard | ShardKey | ConnectionConfigKey
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 60; emerson-faria.nobre@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 60; joao.maria@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 106; pedro.maria@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 106; maria.pedro@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 167; ana.pedro@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 229; ana.ana@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 235; fabiano.ana@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:50+00:00 INFO (6): 303; teste@serpro.gov.br; db1


Vamos realizar uma operação de resharding para mover os dois usuários que estão associados ao Virtual Shard 60 para o BD asdb2.

sudo -u www-data php tine20.php --domain serpro.gov.br --username dogbert@serpro.gov.br --method Tinebase_Shard.reshardVirtualShard 
-- database='asdatabase' virtualshard=60 key='db2' outputlogfile='/tmp/resharding.log'

No arquivo /tmp/resharding.log sera possivel visualizar se o resharding teve sucesso.

9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Obtaining the ShardKey list associated with the Virtual Shard 60

9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): emerson-faria.nobre@serpro.gov.br
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): joao.maria@serpro.gov.br

9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Starting Resharding of emerson-faria.nobre@serpro.gov.br...
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => FETCHING DATA FROM DESTINATION db2
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Fetched 0 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => DELETING DATA FROM DESTINATION db2
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Deleted 0 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => FETCHING DATA FROM ORIGIN
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Fetched 76 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => INSERTING DATA IN DESTINATION db2
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Inserted 76 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => COMPARING COPIED DATA
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Fetched 76 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => DELETING DATA FROM ORIGIN
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Fetched 76 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Deleted 76 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): emerson-faria.nobre@serpro.gov.br Successfully completed.

9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Starting Resharding of joao.maria@serpro.gov.br...
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => FETCHING DATA FROM DESTINATION db2
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Fetched 0 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => DELETING DATA FROM DESTINATION db2
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Deleted 0 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => FETCHING DATA FROM ORIGIN
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Fetched 98 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => INSERTING DATA IN DESTINATION db2
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Inserted 98 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => COMPARING COPIED DATA
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Fetched 98 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): => DELETING DATA FROM ORIGIN
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Fetched 98 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Deleted 98 records
9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): joao.maria@serpro.gov.br Successfully completed.

9b4b3 dogbert - 2015-08-11T20:54:35+00:00 INFO (6): Resharging of Virtual Shard 60 successfully finished!!!

Consultado novamente quais usuários estão em quais Virtuais Shards, veremos que os usuários do VirtualShard 60 agora estão associados ao db2.

 sudo -u www-data php tine20.php --domain serpro.gov.br --username dogbert@serpro.gov.br 
--method Tinebase_Shard.getAssociationOfShardKey -- database='asdatabase' shardkey='all' outputlogfile='/tmp/associations2.txt'

No arquivo /tmp/associations2.txt veremos:

06e37 dogbert - 2015-08-11T20:14:51+00:00 INFO (6): VirtualShard | ShardKey | ConnectionConfigKey
06e37 dogbert - 2015-08-11T20:14:51+00:00 INFO (6): 60; emerson-faria.nobre@serpro.gov.br; db2
06e37 dogbert - 2015-08-11T20:14:51+00:00 INFO (6): 60; joao.maria@serpro.gov.br; db2
06e37 dogbert - 2015-08-11T20:14:51+00:00 INFO (6): 106; pedro.maria@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:51+00:00 INFO (6): 106; maria.pedro@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:51+00:00 INFO (6): 167; ana.pedro@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:51+00:00 INFO (6): 229; ana.ana@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:51+00:00 INFO (6): 235; fabiano.ana@serpro.gov.br; db1
06e37 dogbert - 2015-08-11T20:14:51+00:00 INFO (6): 303; teste@serpro.gov.br; db1

A partir dessa operação de Resharding, o usuário emerson-faria.nobre@serpro.gov.br usará o BD asdb2 quando sincronizar um dispositivo móvel via protocolo ActiveSync.

Ativando Sharding em mais Tabelas do BD

A funcionalidade de Shard é ativada por backend de BD. Atualmente temos dois backend: "database" e "asdatabase". Enquanto que no backend "asdatabase" estão as tabelas de ActiveSync, no backend "database" estão todas as outras tabelas do sistema.

Como visto nos tópicos anteriores, já podemos ativar o Shard para o backend "asdatabase".

Se desejarmos realizar Shard de uma ou mais tabelas que estão atualmente no backend "database", devemos satisfazer as seguintes condições:

  • Criar um backend separado de BD para as tabelas. Todas as tabelas devem ser do tipo Shard Shared Nothing;
  • Se a shard Key for o login do usuário, adicionar os filtros na classe Tinebase_Shard_ShardKey_Strategy_Loginname.php ;
  • Se a shard Key não for o login do usuário, criar uma nova classe Tinebase_Shard_ShardKey_Strategy_XXXXXXXX.php ;
  • Criar um arquivo de configuração de Shard .../domains/xxxx.gov.br/shardX.inc.php . Veja exemplo shard1.inc.php em secção anterior desse documento;
  • Criar a TAG <shard> com suas respectivas subtags nos arquivos setup.xml que descrevem as tabelas de BD que fazem parte do Shard. Veja exemplo: ../ActiveSync/Setup/setup.xml . Veja outros exemplos na pasta ../Tinebase/Shard/examples/...

Configurar o sistema para ativar o Shard no novo backend criado, seguindo os procedimentos descritos nas secções anteriores.

Referências

[1] Nobre, Emerson; 2015; Escalando o Expresso V3 horizontalmente com o uso de Sharding via Aplicação; Artigo Revista Tema; Link [1]

[2] Nobre, Emerson; 2015; Escalando o Expresso V3; Vídeo da Palestra Técnica do CISL; Link [2]

[3] Código fonte; Link [3]

Ferramentas pessoais
Espaços nominais

Variantes
Ações
Navegação
Ferramentas