MongoDB Sharding

0 Flares Twitter 0 Facebook 0 Filament.io 0 Flares ×

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" } ]
  }
)
0 Flares Twitter 0 Facebook 0 Filament.io 0 Flares ×
8 meses ago

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *