MongoDB Sharding

No MongoDB Sharding é uma forma de distribuir dados através de múltiplos servidores com o objetivo de ter um grande cluster de dados.

O Recurso de Sharding é utilizando quando se trabalha com grandes datasets, essa semana por exemplo vou precisar configurar um cluster de mongodb de com 3 máquinas que vão guardar 3 terabytes de dados, sendo assim neste caso é um Pré-Requisito criar um cluster com sharding e replicação. Mas por que usar os dois recursos? por que a replicação vai garantir a redundancia dos seus dados e o sharding vai permitir que você aumente o tamanho do seu dataset, pois pode ser que no futuro 3 terabytes não sejam mais suficientes para armazenar todos os dados, sendo assim é só adicionar mais um servidor no sharding e o tamanho total de armazenamento irá aumentar.

Abaixo uma imagem da arquitetura do cluster:

Explicando essa arquitetura.

No desenho é mostrado 1 servidor rodando um serviço chamado MongoService, esse serviço é o responsável por balancear essa carga entre os 2 servidores atrás dele que estarão replicados. Em uma arquitetura ideal é interessante ter pelo menos 2 servidores com o MongoService para garantir uma alta disponibilidade e um proxy-loadbalancer na frente, nessa arquitetura só foi colocado um pois o cliente disponibilizou somente 3 máquinas.

Atrás desse servidor com o MongoService temos 2 servidores e em cada um deles será executado 2 serviços do MongoDB de forma diferente, sendo um deles para armazenar os dados, que chamados de DataServer e o outro será o ConfigServer que irá armazenar os metadados do cluster.

Uma arquitetura minima viável para criar um cluster de sharding são pelo menos 6 máquinas, abaixo segue uma imagem da documentação oficial do mongodb.

Na imagem acima são:
– 2 servidores MongoService
– 2 ConfigServer em Replica
– 2 Servidores em Shard em replica

Bom, agora chega de imagens e arquitetura e vamos mão na massa,

vim /etc/hosts
 
192.168.0.108 mongoservice
192.168.0.106 mongodb1
192.168.0.107 mongodb2

Acima são os apontamentos do meu arquivo /etc/hosts, fiz esse apontamento pois toda a configuração vou fazer através de nomes. Lembrando que esse arquivo deve ser copiado para todas as máquinas para que elas se conversem através de nomes.

Para fazer a instalação do mongodb é necessário configurar o repositório e fazer a instalação dos pacotes nas 3 máquinas conforme as instruções abaixo:

Configurando os repositórios.

vim  /etc/yum.repos.d/mongodb-org-3.4.repo
 
# conteudo abaixo foi adicionado no arquivo acima
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc

Agora a instalação.

yum -y install mongodb-org

Criando o Sharding e o ConfigServer.

Primeiro acesse o servidor mongodb1 e rode os seguintes comandos:

mkdir -p /data/{db,configdb}
 
mongod --replSet "rs0" --shardsvr --port 27017 &
 
mongod --configsvr --replSet configReplSet &

Sendo executados os comandos acima, devem existir 2 serviços rodando na máquina, um na porta 27017 e outro na porta 27019.

Para validar execute o comando abaixo:

[root@localhost system]# ss -ntpl
State      Recv-Q Send-Q                                       Local Address:Port                                                      Peer Address:Port
LISTEN     0      128                                                      *:27019                                                                *:*                   users:(("mongod",pid=11751,fd=6))
LISTEN     0      128                                                      *:22                                                                   *:*                   users:(("sshd",pid=1147,fd=3))
LISTEN     0      100                                              127.0.0.1:25                                                                   *:*                   users:(("master",pid=1947,fd=13))
LISTEN     0      128                                                      *:27017                                                                *:*                   users:(("mongod",pid=11685,fd=6))
LISTEN     0      128                                                     :::22                                                                  :::*                   users:(("sshd",pid=1147,fd=4))
LISTEN     0      100                                                    ::1:25                                                                  :::*                   users:(("master",pid=1947,fd=14))

Veja que os serviços que eu citei acima estão sendo mostrados na saida do comando ss -ntpl.

Agora faça a mesma coisa no mongodb2.

Criando a replica dos dados.

Para criar a replica dos dados em qualquer um dos servidores você pode digitar as instruções abaixo:

[root@localhost ~]# mongo
MongoDB shell version v3.4.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.3
Server has startup warnings:
2017-04-16T23:19:10.154-0400 I CONTROL  [initandlisten]
2017-04-16T23:19:10.154-0400 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-04-16T23:19:10.154-0400 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2017-04-16T23:19:10.154-0400 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-04-16T23:19:10.154-0400 I CONTROL  [initandlisten]
> rs.initiate( {
   _id : "rs0",
   members: [ { _id : 0, host : "mongodb1:27017" } ]
})

Com os comandos acima o próprio servidor foi adicionado ao replicaset rs0 criado anteriormente, agora para adicionar o segundo servidor execute as linhas abaixo:

[root@localhost ~]# mongo
MongoDB shell version v3.4.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.3
> rs0:PRIMARY> rs.add("mongodb2")
{ "ok" : 1 }

Para validar que eles estão em replica, você pode acessar o console do segundo servidor e validar se ele está aparecendo como SECONDARY:

[root@localhost ~]# mongo
MongoDB shell version v3.4.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.3
 
rs0:SECONDARY>

Na saida do comando acima é possível ver que logo no console já aparece que o servidor faz parte do rs0 e está como SECONDARY.

Agora para fazer a replica do configserver, em qualquer um dos dois servidores você pode executar as seguinte instrução dentro do console do mongodb.

[root@localhost ~]# mongo localhost:27019
MongoDB shell version v3.4.3
connecting to: localhost:27019
MongoDB server version: 3.4.3
Server has startup warnings:
2017-04-16T23:15:10.890-0400 I CONTROL  [initandlisten]
2017-04-16T23:15:10.890-0400 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-04-16T23:15:10.890-0400 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2017-04-16T23:15:10.890-0400 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-04-16T23:15:10.890-0400 I CONTROL  [initandlisten]
>
> rs.initiate( {
...    _id: "configReplSet",
...    configsvr: true,
...    members: [
...       { _id: 0, host: "mongodb1:27019" },
...       { _id: 1, host: "mongodb2:27019" }
...    ]
... } )
{ "ok" : 1 }
configReplSet:OTHER>

No exemplo acima o cliente do mongodb foi executando para acessar a parta 27019 que é a responsável por fazer a replicação do configserver e a replica foi criada nela.

Com todas as replicas configuradas é hora de configurar o service.

Acesse agora o servidor mongoservice e execute o seguinte comando:

mongos --configdb configReplSet/mongodb1:27019,mongodb2:27019 &

Esse comando irá iniciar um processo na porta 27017.

[root@localhost ~]# ss -ntpl
State      Recv-Q Send-Q                                       Local Address:Port                                                      Peer Address:Port
LISTEN     0      128                                                      *:22                                                                   *:*                   users:(("sshd",pid=1078,fd=3))
LISTEN     0      100                                              127.0.0.1:25                                                                   *:*                   users:(("master",pid=1546,fd=13))
LISTEN     0      128                                                      *:27017                                                                *:*                   users:(("mongos",pid=11497,fd=4))
LISTEN     0      128                                                     :::22                                                                  :::*                   users:(("sshd",pid=1078,fd=4))
LISTEN     0      100                                                    ::1:25                                                                  :::*                   users:(("master",pid=1546,fd=14))

A saida do comando acima mostra isso.

O mongoservice será o ponto de acesso para as replicas configuradas no começo do artigo, agora para acessa-lo será da seguinte maneira:

[root@localhost ~]# mongo mongoservice/admin
Welcome to the MongoDB shell.
mongos>

Note que agora o console está diferente e ao invés de ficar somente o sinal de maior ( > ), fica aparecendo mongos>, pois estamos acessando o service e não a base diretamente.

Agora para adicionar o nosso cluster de shard execute a linha abaixo:

> sh.addShard( "rs0/mongodb1:27017,mongodb2:27017" )
2017-04-16T23:45:03.496-0400 I NETWORK  [conn2] Starting new replica set monitor for rs0/mongodb1:27017,mongodb2:27017
{ "shardAdded" : "rs0", "ok" : 1 }

A saida do comando acima mostra que o shard foi adicionado com sucesso.

No MongoService você pode adicionar quantos clusters de shard você precisar.

Agora para criar um banco de dados dentro do seu cluster é necessário executar a instrução abaixo:

mongos> sh.enableSharding("alisson")
2017-04-16T23:46:51.918-0400 I SHARDING [conn2] distributed lock 'alisson' acquired for 'enableSharding', ts : 58f43aab9202a5538a1cb23c
2017-04-16T23:46:51.919-0400 I ASIO     [NetworkInterfaceASIO-ShardRegistry-0] Connecting to mongodb1:27017
2017-04-16T23:46:51.920-0400 I ASIO     [NetworkInterfaceASIO-ShardRegistry-0] Successfully connected to mongodb1:27017
2017-04-16T23:46:51.921-0400 I SHARDING [conn2] Placing [alisson] on: rs0
2017-04-16T23:46:51.921-0400 I SHARDING [conn2] Enabling sharding for database [alisson] in config db
2017-04-16T23:46:51.979-0400 I SHARDING [conn2] distributed lock with ts: 58f43aab9202a5538a1cb23c' unlocked.
{ "ok" : 1 }

Agora você pode acessar o banco de de dados e criar um documento e fazer uma busca para ver se já funciona:

mongos> use alisson;
switched to db alisson
mongos> db.documentos.insert({"nome":"teste"})
WriteResult({ "nInserted" : 1 })
mongos> db.documentos.find()
2017-04-16T23:48:19.957-0400 I ASIO     [NetworkInterfaceASIO-TaskExecutorPool-0-0] Connecting to mongodb1:27017
2017-04-16T23:48:19.958-0400 I ASIO     [NetworkInterfaceASIO-TaskExecutorPool-0-0] Successfully connected to mongodb1:27017
{ "_id" : ObjectId("58f43afd058b0dbab981298e"), "nome" : "teste" }
mongos> show dbs;
admin    0.000GB
alisson  0.000GB
config   0.000GB
mongos> show collections;
documentos

Note que ao fazer o find do documento é mostrado no log que o dado é buscado dentro do servidor mongodb1.

Agora eu reiniciei o servidor primary e fiz a mesma busca, note que agora ele busca no segundo servidor:

mongos> db.documentos.find()
2017-04-17T00:02:22.177-0400 I ASIO     [NetworkInterfaceASIO-TaskExecutorPool-0-0] Connecting to mongodb2:27017
2017-04-17T00:02:22.179-0400 I ASIO     [NetworkInterfaceASIO-TaskExecutorPool-0-0] Successfully connected to mongodb2:27017
{ "_id" : ObjectId("58f43afd058b0dbab981298e"), "nome" : "teste" }

Agora para finalizar é importante adicionar autenticação ao mongodb, pois por padrão o usuário é o anonimo.

Para fazer isso é só executar os comandos abaixo:

use admin
db.createUser(
  {
    user: "alisson",
    pwd: "alisson123",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

4
Deixe um comentário

avatar
1 Comment threads
3 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Alisson MachadoJorge Antonio Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Jorge Antonio
Visitante
Jorge Antonio

Otimo post, esta de parabens mas tenho uma duvida, se já possuir um replica set eu consigo colocar essa base em sharding ? Ou somente bases criadas do zero ?

Desde já agradeço