Sharding é um processo de dividir a grande escala de conjuntos de dados em um bloco de conjuntos de dados menores em várias instâncias do MongoDB em um ambiente distribuído.
últimas postagens
O que é Fragmentação?
O sharding do MongoDB nos fornece uma solução escalável para armazenar uma grande quantidade de dados entre o número de servidores, em vez de armazenar em um único servidor.
Em termos práticos, não é viável armazenar dados em crescimento exponencial em uma única máquina. Consultar uma grande quantidade de dados armazenados em um único servidor pode levar a uma alta utilização de recursos e pode não fornecer um rendimento satisfatório de leitura e gravação.
Basicamente, existem dois tipos de métodos de dimensionamento que existem para realizar o crescimento de dados com o sistema:
O Vertical Scaling trabalha com o aprimoramento do desempenho de servidor único, adicionando processadores mais potentes, atualizando a RAM ou adicionando mais espaço em disco ao sistema. Mas existem as possíveis implicações da aplicação do dimensionamento vertical em casos de uso práticos com tecnologia existente e configurações de hardware.
O dimensionamento horizontal funciona adicionando mais servidores e distribuindo a carga em vários servidores. Como cada máquina estará lidando com o subconjunto de todo o conjunto de dados, ela oferece melhor eficiência e solução econômica em vez de implantar o hardware de ponta. Mas requer manutenção adicional de infraestrutura complexa com um grande número de servidores.
A fragmentação do Mongo DB funciona na técnica de dimensionamento horizontal.
Componentes de fragmentação
Para obter fragmentação no MongoDB, os seguintes componentes são necessários:
Shard é uma instância do Mongo para lidar com um subconjunto de dados originais. Os fragmentos precisam ser implantados no conjunto de réplicas.
Mongos é uma instância do Mongo e atua como uma interface entre um aplicativo cliente e um cluster fragmentado. Ele funciona como um roteador de consulta para shards.
O Config Server é uma instância do Mongo que armazena informações de metadados e detalhes de configuração do cluster. O MongoDB requer que o servidor de configuração seja implantado como um conjunto de réplicas.
Arquitetura de fragmentação
O cluster MongoDB consiste em vários conjuntos de réplicas.
Cada conjunto de réplicas consiste em no mínimo 3 ou mais instâncias do mongo. Um cluster fragmentado pode consistir em várias instâncias de fragmentos do mongo, e cada instância de fragmento funciona em um conjunto de réplicas de fragmentos. O aplicativo interage com o Mongos, que por sua vez se comunica com os shards. Portanto, no Sharding, os aplicativos nunca interagem diretamente com nós de shard. O roteador de consulta distribui os subconjuntos de dados entre os nós de estilhaços com base na chave de estilhaço.
Implementação de fragmentação
Siga as etapas abaixo para fragmentação
Passo 1
- Inicie o servidor de configuração no conjunto de réplicas e habilite a replicação entre eles.
mongod –configsvr –port 27019 –replSet rs0 –dbpath C:datadata1 –bind_ip localhost
mongod –configsvr –port 27018 –replSet rs0 –dbpath C:datadata2 –bind_ip localhost
mongod –configsvr –port 27017 –replSet rs0 –dbpath C:datadata3 –bind_ip localhost
Passo 2
- Inicialize o conjunto de réplicas em um dos servidores de configuração.
rs.initiate( { _id : “rs0”, configsvr: true, membros: [ { _id: 0, host: “IP:27017” }, { _id: 1, host: “IP:27018” }, { _id: 2, host: “IP:27019” } ] })
rs.initiate( { _id : "rs0", configsvr: true, members: [ { _id: 0, host: "IP:27017" }, { _id: 1, host: "IP:27018" }, { _id: 2, host: "IP:27019" } ] }) { "ok" : 1, "$gleStats" : { "lastOpTime" : Timestamp(1593569257, 1), "electionId" : ObjectId("000000000000000000000000") }, "lastCommittedOpTime" : Timestamp(0, 0), "$clusterTime" : { "clusterTime" : Timestamp(1593569257, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1593569257, 1) }
etapa 3
- Inicie a fragmentação de servidores no conjunto de réplicas e habilite a replicação entre eles.
mongod –shardsvr –port 27020 –replSet rs1 –dbpath C:datadata4 –bind_ip localhost
mongod –shardsvr –port 27021 –replSet rs1 –dbpath C:datadata5 –bind_ip localhost
mongod –shardsvr –port 27022 –replSet rs1 –dbpath C:datadata6 –bind_ip localhost
O MongoDB inicializa o primeiro servidor de fragmentação como Primário, para mover o uso do servidor de fragmentação primário movePrimary método.
Passo 4
- Inicialize o conjunto de réplicas em um dos servidores fragmentados.
rs.initiate( { _id : “rs0”, membros: [ { _id: 0, host: “IP:27020” }, { _id: 1, host: “IP:27021” }, { _id: 2, host: “IP:27022” } ] })
rs.initiate( { _id : "rs0", members: [ { _id: 0, host: "IP:27020" }, { _id: 1, host: "IP:27021" }, { _id: 2, host: "IP:27022" } ] }) { "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1593569748, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1593569748, 1) }
Etapa 5
- Inicie as mangas para o cluster fragmentado
mongos –porta 40000 –configdb rs0/localhost:27019,localhost:27018, localhost:27017
Etapa 6
- Conecte o servidor de rotas do mongo
mongo –porta 40000
- Agora, adicione servidores de fragmentação.
sh.addShard( “rs1/localhost:27020,localhost:27021,localhost:27022”)
sh.addShard( "rs1/localhost:27020,localhost:27021,localhost:27022") { "shardAdded" : "rs1", "ok" : 1, "operationTime" : Timestamp(1593570212, 2), "$clusterTime" : { "clusterTime" : Timestamp(1593570212, 2), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
Etapa 7
- No shell do mongo, habilite o sharding no banco de dados e nas coleções.
- Ativar fragmentação no banco de dados
sh.enableSharding(“geekFlareDB”)
sh.enableSharding("geekFlareDB") { "ok" : 1, "operationTime" : Timestamp(1591630612, 1), "$clusterTime" : { "clusterTime" : Timestamp(1591630612, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
Etapa 8
- Para fragmentar a chave de fragmentação da coleção (descrita posteriormente neste artigo) é necessário.
Sintaxe: sh.shardCollection(“dbName.collectionName”, { “key” : 1 } )
sh.shardCollection("geekFlareDB.geekFlareCollection", { "key" : 1 } ) { "collectionsharded" : "geekFlareDB.geekFlareCollection", "collectionUUID" : UUID("0d024925-e46c-472a-bf1a-13a8967e97c1"), "ok" : 1, "operationTime" : Timestamp(1593570389, 3), "$clusterTime" : { "clusterTime" : Timestamp(1593570389, 3), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
Observe se a coleção não existir, crie da seguinte maneira.
db.createCollection("geekFlareCollection") { "ok" : 1, "operationTime" : Timestamp(1593570344, 4), "$clusterTime" : { "clusterTime" : Timestamp(1593570344, 5), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
Etapa 9
Insira dados na coleção. Os logs do Mongo começarão a crescer, indicando que um balanceador está em ação e tentando balancear os dados entre os fragmentos.
Etapa 10
A última etapa é verificar o status da fragmentação. O status pode ser verificado executando o comando abaixo no nó de rota do Mongos.
Status de fragmentação
Verifique o status do sharding executando o comando abaixo no nó de rota do mongo.
sh.status()
mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("5ede66c22c3262378c706d21") } shards: { "_id" : "rs1", "host" : "rs1/localhost:27020,localhost:27021,localhost:27022", "state" : 1 } active mongoses: "4.2.7" : 1 autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: no Failed balancer rounds in last 5 attempts: 5 Last reported error: Could not find host matching read preference { mode: "primary" } for set rs1 Time of Reported error: Tue Jun 09 2020 15:25:03 GMT+0530 (India Standard Time) Migration Results for the last 24 hours: No recent migrations databases: { "_id" : "config", "primary" : "config", "partitioned" : true } config.system.sessions shard key: { "_id" : 1 } unique: false balancing: true chunks: rs1 1024 too many chunks to print, use verbose if you want to force print { "_id" : "geekFlareDB", "primary" : "rs1", "partitioned" : true, "version" : { "uuid" : UUID("a770da01-1900-401e-9f34-35ce595a5d54"), "lastMod" : 1 } } geekFlareDB.geekFlareCol shard key: { "key" : 1 } unique: false balancing: true chunks: rs1 1 { "key" : { "$minKey" : 1 } } -->> { "key" : { "$maxKey" : 1 } } on : rs1 Timestamp(1, 0) geekFlareDB.geekFlareCollection shard key: { "product" : 1 } unique: false balancing: true chunks: rs1 1 { "product" : { "$minKey" : 1 } } -->> { "product" : { "$maxKey" : 1 } } on : rs1 Timestamp(1, 0) { "_id" : "test", "primary" : "rs1", "partitioned" : false, "version" : { "uuid" : UUID("fbc00f03-b5b5-4d13-9d09-259d7fdb7289"), "lastMod" : 1 } } mongos>
Distribuição de dados
O roteador Mongos distribui a carga entre os shards com base na chave do shard e para distribuir os dados uniformemente; balanceador entra em ação.
O componente chave para distribuir dados entre os shards são
- Um balanceador desempenha um papel no balanceamento do subconjunto de dados entre os nós fragmentados. O balanceador é executado quando o servidor Mongos começa a distribuir cargas entre os shards. Uma vez iniciado, o Balancer distribuiu os dados de forma mais uniforme. Para verificar o estado do balanceador, execute sh.status() ou sh.getBalancerState() ou
sh.isBalancerRunning().
mongos> sh.isBalancerRunning() true mongos>
OU
mongos> sh.getBalancerState() true mongos>
Após inserir os dados, notamos alguma atividade no daemon do Mongos informando que ele está movendo alguns chunks para os shards específicos e assim por diante, ou seja, o balanceador estará em ação tentando balancear os dados entre os shards. A execução do balanceador pode levar a problemas de desempenho; portanto, sugere-se executar o balanceador dentro de um determinado janela do balanceador.
mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("5efbeff98a8bbb2d27231674") } shards: { "_id" : "rs1", "host" : "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022", "state" : 1 } { "_id" : "rs2", "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025", "state" : 1 } active mongoses: "4.2.7" : 1 autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: yes Failed balancer rounds in last 5 attempts: 5 Last reported error: Could not find host matching read preference { mode: "primary" } for set rs2 Time of Reported error: Wed Jul 01 2020 14:39:59 GMT+0530 (India Standard Time) Migration Results for the last 24 hours: 1024 : Success databases: { "_id" : "config", "primary" : "config", "partitioned" : true } config.system.sessions shard key: { "_id" : 1 } unique: false balancing: true chunks: rs2 1024 too many chunks to print, use verbose if you want to force print { "_id" : "geekFlareDB", "primary" : "rs2", "partitioned" : true, "version" : { "uuid" : UUID("a8b8dc5c-85b0-4481-bda1-00e53f6f35cd"), "lastMod" : 1 } } geekFlareDB.geekFlareCollection shard key: { "key" : 1 } unique: false balancing: true chunks: rs2 1 { "key" : { "$minKey" : 1 } } -->> { "key" : { "$maxKey" : 1 } } on : rs2 Timestamp(1, 0) { "_id" : "test", "primary" : "rs2", "partitioned" : false, "version" : { "uuid" : UUID("a28d7504-1596-460e-9e09-0bdc6450028f"), "lastMod" : 1 } } mongos>
- A chave de fragmentação determina a lógica para distribuir documentos de coleção de fragmentos entre os fragmentos. A chave de fragmentação pode ser um campo indexado ou um campo composto indexado que deve estar presente em todos os documentos da coleção a ser inserida. Os dados serão particionados em partes e cada parte será associada à chave de fragmentação baseada em intervalo. Com base no intervalo de consulta, o roteador decidirá qual fragmento armazenará o fragmento.
A Shard Key pode ser selecionada considerando cinco propriedades:
- Cardinalidade
- Distribuição de gravação
- Ler distribuição
- Ler segmentação
- Ler localidade
Uma chave de fragmentação ideal faz com que o MongoDB distribua uniformemente a carga entre todos os fragmentos. Escolher uma boa chave de fragmentação é extremamente importante.
Imagem: MongoDB
Removendo o nó do estilhaço
Antes de remover os estilhaços do cluster, o usuário deve garantir a migração segura dos dados para os estilhaços restantes. O MongoDB cuida da drenagem segura de dados para outros nós de estilhaços antes da remoção do nó de estilhaço necessário.
Execute o comando abaixo para remover o fragmento necessário.
Passo 1
Primeiro, precisamos determinar o nome do host do shard a ser removido. O comando abaixo listará todos os shards presentes no cluster junto com o estado do shard.
db.adminCommand( { listShards: 1 } )
mongos> db.adminCommand( { listShards: 1 } ) { "shards" : [ { "_id" : "rs1", "host" : "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022", "state" : 1 }, { "_id" : "rs2", "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025", "state" : 1 } ], "ok" : 1, "operationTime" : Timestamp(1593572866, 15), "$clusterTime" : { "clusterTime" : Timestamp(1593572866, 15), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
Passo 2
Emita o comando abaixo para remover o estilhaço necessário do cluster. Uma vez emitido, o balanceador cuida da remoção de pedaços do nó de estilhaços de drenagem e, em seguida, equilibra a distribuição dos pedaços restantes entre os nós de fragmentos restantes.
db.adminCommand( { removeShard: “shardedReplicaNodes” } )
mongos> db.adminCommand( { removeShard: "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022" } ) { "msg" : "draining started successfully", "state" : "started", "shard" : "rs1", "note" : "you need to drop or movePrimary these databases", "dbsToMove" : [ ], "ok" : 1, "operationTime" : Timestamp(1593572385, 2), "$clusterTime" : { "clusterTime" : Timestamp(1593572385, 2), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
etapa 3
Para verificar o status do fragmento de drenagem, emita o mesmo comando novamente.
db.adminCommand( { removeShard: “rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022” } )
Precisamos esperar até que a drenagem dos dados seja concluída. Os campos msg e state mostrarão se a drenagem de dados foi concluída ou não, como segue
"msg" : "draining ongoing", "state" : "ongoing",
Também podemos verificar o status com o comando sh.status(). Uma vez removido, o nó fragmentado não será refletido na saída. Mas se a drenagem estiver em andamento, o nó fragmentado virá com o status de drenagem como verdadeiro.
Passo 4
Continue verificando o status de drenagem com o mesmo comando acima, até que o fragmento necessário seja removido completamente.
Uma vez concluído, a saída do comando refletirá a mensagem e o estado como concluído.
"msg" : "removeshard completed successfully", "state" : "completed", "shard" : "rs1", "ok" : 1,
Etapa 5
Por fim, precisamos verificar os fragmentos restantes no cluster. Para verificar o status digite sh.status() ou db.adminCommand( { listShards: 1 } )
mongos> db.adminCommand( { listShards: 1 } ) { "shards" : [ { "_id" : "rs2", "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025", "state" : 1 } ], "ok" : 1, "operationTime" : Timestamp(1593575215, 3), "$clusterTime" : { "clusterTime" : Timestamp(1593575215, 3), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
Aqui, podemos ver que o fragmento removido não está mais presente na lista de fragmentos.
Benefícios da fragmentação sobre a replicação
- Na replicação, o nó primário trata de todas as operações de gravação, enquanto os servidores secundários são necessários para manter cópias de backup ou atender a operações somente leitura. Mas ao fragmentar junto com conjuntos de réplicas, a carga é distribuída entre vários servidores.
- Um único conjunto de réplicas é limitado a 12 nós, mas não há restrição quanto ao número de estilhaços.
- A replicação requer hardware de ponta ou dimensionamento vertical para lidar com grandes conjuntos de dados, o que é muito caro em comparação com a adição de servidores adicionais na fragmentação.
- Na replicação, o desempenho de leitura pode ser aprimorado com a adição de mais servidores escravos/secundários, enquanto, na fragmentação, o desempenho de leitura e gravação será aprimorado com a adição de mais nós de fragmentos.
Limitação de fragmentação
- O cluster Sharded não oferece suporte à indexação exclusiva nos estilhaços até que o índice exclusivo seja prefixado com a chave de estilhaço completa.
- Todas as operações de atualização para coleção fragmentada em um ou vários documentos devem conter a chave fragmentada ou o campo _id na consulta.
- As coleções podem ser fragmentadas se seu tamanho não exceder o limite especificado. Esse limite pode ser estimado com base no tamanho médio de todas as chaves de fragmentação e no tamanho configurado dos blocos.
- A fragmentação compreende limites operacionais no tamanho máximo da coleção ou no número de divisões.
- Escolher as chaves de fragmentação erradas pode levar a implicações de desempenho.
Conclusão
O MongoDB oferece sharding integrado para implementar um grande banco de dados sem comprometer o desempenho. Espero que o acima ajude você a configurar o sharding do MongoDB. Em seguida, você pode querer se familiarizar com alguns dos comandos mais usados do MongoDB.