Servidores de replicação no MongoDB

27 de dezembro de 2016

Uma das grandes vantagens dos bancos de dados não relacionais, os NoSQLs, é a facilidade em preparar toda sua infraestrutura. Configurar um servidor com replicação no MongoDB é um processo simples, que exige apenas alguns comandos. Neste exemplo, será exibido uma configuração utilizando três máquinas.

MongoDB Replica Set

Sharding e Replica Set

Antes de mais nada, é interessante entender alguns termos utilizados no MongoDB.

Sharding é um método de distribuição de dados através de várias máquinas, utilizando instâncias do MongoDB chamadas Shards. Estes Shards podem armazenar partes diferentes dos dados, o que facilita a escalabilidade da nossa aplicação. Replica Set É um grupo de instâncias Shards do MongoDB que provém a redundância e disponibilidade dos dados. Os membros de um Replica Set podem ser:

  • Primary: Recebe as operações de escrita
  • Secondary: Replica os dados do membro primário para manter uma base de dados idêntica.

Para criar um membro de um Shard de um Replica Set, execute o comando, em cada um dos servidores:

mongod --shardsvr --replSet "rs0" --port 27017 --logpath "rs0.log" --fork

Onde rs0 é o nome do nosso Replica Sets e rs0.log é onde será gravado o log de saída. Por padrão, o comando mongod cria uma instância do banco na porta 27017, porém, alguns parâmetros, como o --shardsvr e o --configsrv alteram a porta para 27018 e 27019, respectivamente. Para evitar confusão, informamos a porta que desejamos utilizar através do parâmetro --port.

Arbiter

Os Arbiters não mantém cópias dos dado, mas são responsáveis por eleger um novo membro como Primary caso o membro atual fique indisponível. Por não armazenar dados, um Arbiter não é instanciado como um Shard. Para criá-lo, execute o comando:

mongod --replSet "rs0" --dbpath /data/arb --logpath "rs0.log" --fork

Onde rs0 é o nome do grupo de Replica Sets, que deve ser o mesmo utilizando na configuração anterior, e rs0.log é onde será gravado o log de saída. O parâmetro --dbpath tem a finalidade de informar um diretório alternativo para gravar os registros e configurações do banco de dados. É útil quando desejamos evitar possíveis conflitos com dados de outras instâncias na mesma máquina.

Inicializando o Replica Set

Agora que temos nossos Shards e nosso Arbiter inicializados, é necessário configurar o Replica Set para que a replicação funcione de fato. Em um dos servidores, entre no console do MongoDB com o comando mongo localhost:27017 e execute:

var config = {
  _id: 'rs0',
  members: [
    { _id: 0, host: 'server1:27017' },
    { _id: 1, host: 'server2:27017' },
    { _id: 2, host: 'server3:27017', arbiterOnly: true }
  ]
};
rs.initiate(config)

Saia do terminal, aguarde cerca de 30 segundos, entre no terminal novamente e execute rs.status() para verificar se está tudo funcionando.

Populando o banco para testes

Pode ser útil possuir alguns registros em nosso banco de dados para que possamos realizar alguns testes. O MongoDB possui ferramentas que auxiliam neste processo. O comando abaixo irá gerar mil registros de testes no database test, na coleção test_collection. Entre no terminal do Mongo em alguma das instâncias, utilizando o comando mongo localhost:27017 e execute:

use test
var bulk = db.test_collection.initializeUnorderedBulkOp();
var people = [ 'Steve Jobs', 'Bill Gates', 'Larry Page', 'Mark Zuckerberg', 'Jeff Bezos', 'Elon Musk' ];

for (var i = 0; i < 1000; i++) {
  user_id = i;
  name = people[Math.floor(Math.random() * people.length)];
  number = Math.floor(Math.random() * 10001);
  bulk.insert({
    'user_id': user_id,
    'name': name,
    'number': number
  });
}

bulk.execute();

Config Server

Os Config Servers contém os metadados dos nossos Shards. Estes metadados são responsáveis para que as várias instâncias do MongoDB funcione como um só banco de dados. Em cada um dos servidores, execute o comando:

mongod --configsrv --replSet "configReplSet" --logpath "configReplSet.log" --fork

Onde configReplSet é o nome do grupo de Config Servers e configReplSet.log é onde será gravado o log de saída. Como dito anteriormente, os Config Servers são iniciados na porta 27019 por padrão. Também é possível alterá-la adicionando o parâmetro --port.

Inicializando

Uma vez que os Config Servers já estejam inicializados, devemos configurá-los. Em um dos servidores, abra o terminal do MongoDB na porta 27019 com o comando mongo localhost:27019 e execute:

var config = {
  _id: 'configReplSet',
  configsrv: true,
  members: [
    { _id: 0, host: 'server1:27019' },
    { _id: 1, host: 'server2:27019' },
    { _id: 2, host: 'server3:27019' }
  ]
};
rs.initiate(config)

Roteamento

Um roteador do MongoDB é o serviço responsável por receber todas as requisições de banco de dados e redirecionar ao servidor responsável por aquele serviço. É recomendável que o roteador esteja configurado em uma máquina que não armazenará os registros do banco de dados, ou seja, em uma máquina que não esteja rodando um Shard. Neste exemplo, ele foi instanciado no server3, onde funciona nosso Arbiter.

mongos --configdb configReplSet/server1:27019,server2:27019,server3:27019 --port 27020 --logpath "router.log" --fork

Por fim, é necessário informar ao nosso roteador quais serão os seus Shards. Para isso, acesse o terminal do MongoDB na máquina roteador (server3 neste exemplo), com o comando mongo localhost:27020/admin e execute:

sh.addShard('rs0/server1:27017,server2:27017,server3:27017')
sh.enableSharding('test')

O comando sh.enableSharding() habilita o Sharding no banco de dados. É necessário executar este comando para todos os bancos que farão parte das clusterização. Podemos verificar se está tudo funcionando com o comando sh.status() e realizar uma consulta de teste:

use test
db.test_collection.find().limit(30).pretty()

Com estes passos, nosso banco de dados está pronto para operar. Sempre que o Shard primário ficar indisponível, o nosso Arbiter irá eleger uma nova instância para ser o novo master. Caso seja optado por não utilizar de um Arbiter, quem será responsável por esta tarefa serão os próprios slaves. É um processo rápido e quase transparente, tanto para o desenvolvedor quanto para o usuário final. Para este Shard ficar novamente disponível, basta executar os comandos mongod de Shard e Config Server novamente.


Escrito por Alan Cesar, Software Engineer na Pismo.
Trabalhando com desenvolvimento desde 2014, mas fazendo código desde moleque.

© alancesar.dev, 2021 | Built with Gatsby.