Alta disponibilidade é essencial quando você executa serviços críticos em seu ambiente de produção. Isso pode ser alcançado eliminando todos os pontos únicos de falhas, incluindo a camada do banco de dados. Então você pode imaginar nossa surpresa toda vez que nos deparamos com configurações com vários servidores/aplicativos da web, todos atingindo uma única instância de banco de dados.
O serviço de alta disponibilidade no MongoDB pode ser obtido por meio de replicação. O termo conjunto de réplicas descreve uma configuração em que vários processos do MongoDB executam e mantêm os mesmos dados. Neste blog, discutiremos como implantar o Percona Server para MongoDB para obter alta disponibilidade.
Implantação do Percona Server para MongoDB
Precisamos de pelo menos 3 nós para alta disponibilidade, um conjunto de réplicas consistirá em 1 nó primário e 2 nós secundários. Você pode usar 2 nós, 1 Primário e 1 Secundário, mas ainda precisa de um árbitro como terceiro nó. Um árbitro é um nó do MongoDB que não copia e armazena os dados, mas está envolvido no processo de eleição do novo primário quando ocorre o failover.
Neste exemplo, estamos executando 3 ambientes virtuais com CentOS Linux versão 7.3 como sistema operacional e usaremos o Percona Server for MongoDB versão 4.2 para a instalação. O endereço IP como abaixo:
- mongo-node8:10.10.10.17
- mongo-node9:10.10.10.18
- mongo-node10:10.10.10.19
Antes de entrarmos na instalação, certifique-se de que todos os nós já estejam configurados no arquivo /etc/hosts em cada nó.
[[email protected] ~]# cat /etc/hosts
127.0.0.1 mongo-node9 mongo-node9
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.10.17 mongo-node8
10.10.10.18 mongo-node9
10.10.10.19 mongo-node10
Depois, precisamos configurar o Repositório Percona em cada um dos nós. Depois disso, habilite o repositório para psmdb42 conforme mostrado abaixo:
[[email protected] ~]# percona-release setup psmdb42
* Disabling all Percona Repositories
* Enabling the Percona Server for MongoDB 4.2 repository
* Enabling the Percona Tools repository
<*> All done!
E então continue instalando o pacote Percona Server for MongoDB:
[[email protected] ~]# yum install percona-server-mongodb*
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: centos.mirror.angkasa.id
* extras: centos.mirror.angkasa.id
* updates: centos.mirror.angkasa.id
Resolving Dependencies
--> Running transaction check
---> Package percona-server-mongodb.x86_64 0:4.2.9-10.el7 will be installed
--> Processing Dependency: cyrus-sasl-gssapi for package: percona-server-mongodb-4.2.9-10.el7.x86_64
--> Processing Dependency: numactl for package: percona-server-mongodb-4.2.9-10.el7.x86_64
---> Package percona-server-mongodb-debuginfo.x86_64 0:4.2.9-10.el7 will be installed
---> Package percona-server-mongodb-mongos.x86_64 0:4.2.9-10.el7 will be installed
--> Processing Dependency: libcrypto.so.10(OPENSSL_1.0.2)(64bit) for package: percona-server-mongodb-mongos-4.2.9-10.el7.x86_64
---> Package percona-server-mongodb-server.x86_64 0:4.2.9-10.el7 will be installed
---> Package percona-server-mongodb-shell.x86_64 0:4.2.9-10.el7 will be installed
---> Package percona-server-mongodb-tools.x86_64 0:4.2.9-10.el7 will be installed
--> Running transaction check
---> Package cyrus-sasl-gssapi.x86_64 0:2.1.26-23.el7 will be installed
--> Processing Dependency: cyrus-sasl-lib(x86-64) = 2.1.26-23.el7 for package: cyrus-sasl-gssapi-2.1.26-23.el7.x86_64
---> Package numactl.x86_64 0:2.0.12-5.el7 will be installed
---> Package openssl-libs.x86_64 1:1.0.1e-60.el7_3.1 will be updated
--> Processing Dependency: openssl-libs(x86-64) = 1:1.0.1e-60.el7_3.1 for package: 1:openssl-1.0.1e-60.el7_3.1.x86_64
---> Package openssl-libs.x86_64 1:1.0.2k-19.el7 will be an update
--> Running transaction check
---> Package cyrus-sasl-lib.x86_64 0:2.1.26-20.el7_2 will be updated
---> Package cyrus-sasl-lib.x86_64 0:2.1.26-23.el7 will be an update
---> Package openssl.x86_64 1:1.0.1e-60.el7_3.1 will be updated
---> Package openssl.x86_64 1:1.0.2k-19.el7 will be an update
--> Finished Dependency Resolution
Dependencies Resolved
================================================================
Package Arch Version Repository
Size
================================================================
Installing:
percona-server-mongodb x86_64 4.2.9-10.el7 psmdb-42-release-x86_64
4.9 k
percona-server-mongodb-debuginfo
x86_64 4.2.9-10.el7 psmdb-42-release-x86_64
885 M
percona-server-mongodb-mongos
x86_64 4.2.9-10.el7 psmdb-42-release-x86_64
10 M
percona-server-mongodb-server
x86_64 4.2.9-10.el7 psmdb-42-release-x86_64
22 M
percona-server-mongodb-shell x86_64 4.2.9-10.el7 psmdb-42-release-x86_64
12 M
percona-server-mongodb-tools x86_64 4.2.9-10.el7 psmdb-42-release-x86_64
30 M
Installing for dependencies:
cyrus-sasl-gssapi x86_64 2.1.26-23.el7 base 41 k
numactl x86_64 2.0.12-5.el7 base 66 k
Updating for dependencies:
cyrus-sasl-lib x86_64 2.1.26-23.el7 base 155 k
openssl x86_64 1:1.0.2k-19.el7 base 493 k
openssl-libs x86_64 1:1.0.2k-19.el7 base 1.2 M
Transaction Summary
================================================================
Install 6 Packages (+2 Dependent packages)
Upgrade ( 3 Dependent packages)
Total download size: 960 M
Is this ok [y/d/N]:
. . . .
Installed:
percona-server-mongodb.x86_64 0:4.2.9-10.el7
percona-server-mongodb-debuginfo.x86_64 0:4.2.9-10.el7
percona-server-mongodb-mongos.x86_64 0:4.2.9-10.el7
percona-server-mongodb-server.x86_64 0:4.2.9-10.el7
percona-server-mongodb-shell.x86_64 0:4.2.9-10.el7
percona-server-mongodb-tools.x86_64 0:4.2.9-10.el7
Dependency Installed:
cyrus-sasl-gssapi.x86_64 0:2.1.26-23.el7
numactl.x86_64 0:2.0.12-5.el7
Dependency Updated:
cyrus-sasl-lib.x86_64 0:2.1.26-23.el7
openssl.x86_64 1:1.0.2k-19.el7
openssl-libs.x86_64 1:1.0.2k-19.el7
Repita a instalação nos outros nós. Após a conclusão da instalação, altere a configuração do bindIP em /etc/mongod.conf do endereço IP do host local para todos os endereços IP privados, conforme mostrado abaixo:
# network interfaces
net:
port: 27017
bindIp: 0.0.0.0
Você também pode restringir o endereço IP no parâmetro bindIP por motivos de segurança, basta adicionar o endereço IP com ponto e vírgula como separador.
Certifique-se de que podemos nos conectar à instância do MongoDB entre os três nós, conforme mostrado no exemplo abaixo:
[[email protected] ~]# mongo --host 10.10.10.19 --port 27017
Percona Server for MongoDB shell version v4.2.9-10
connecting to: mongodb://10.10.10.19:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("99afee8f-a194-4d0a-963a-6dfdc17f5bee") }
Percona Server for MongoDB server version: v4.2.9-10
Server has startup warnings:
2020-10-30T04:38:46.244+0000 I CONTROL [initandlisten]
2020-10-30T04:38:46.244+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2020-10-30T04:38:46.244+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2020-10-30T04:38:46.244+0000 I CONTROL [initandlisten] ** You can use percona-server-mongodb-enable-auth.sh to fix it.
2020-10-30T04:38:46.244+0000 I CONTROL [initandlisten]
A próxima etapa é configurar o conjunto de réplicas no MongoDB. Precisamos editar o arquivo /etc/mongod.conf e descomentar a seção de replicação e adicionar o parâmetro replSetName conforme mostrado abaixo:
replication:
replSetName: "my-mongodb-rs"
Usamos o nome do conjunto de réplicas my-mongodb-rs nesta instalação. Depois que a configuração de replicação for adicionada, reinicie o serviço mongodb.
$ service mongod restart
Repita a configuração nos outros nós.
Uma vez feito, precisamos inicializar a replicação em um dos nós. Conecte-se ao mongodb e execute o comando rs.initiate() conforme mostrado abaixo:
> rs.initiate()
{
"info2" : "no configuration specified. Using a default configuration for the set",
"me" : "mongo-node8:27017",
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1604036305, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1604036305, 1)
}
my-mongodb-rs:OTHER>
my-mongodb-rs:PRIMARY>
Como podemos ver nos nós, o primeiro nó onde iniciamos a replicação se tornará um nó PRIMARY. Precisamos adicionar o restante dos nós para ingressar na replicação.
Adicione os outros nós usando o comando rs.add() nos nós PRIMARY como abaixo:
my-mongodb-rs:PRIMARY> rs.add("mongo-node9:27017");
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1604037158, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1604037158, 1)
}
my-mongodb-rs:PRIMARY> rs.add("mongo-node10:27017");
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1604037170, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1604037170, 1)
}
Outra opção para iniciar o conjunto de réplicas usando o comando start() é passar as informações de endereço IP do nó para todos os nós, conforme mostrado abaixo:
rs.initiate( {
_id: "my-mongodb-rs",
members: [
{ _id: 0, host: "mongo-node8:27017" },
{ _id: 1, host: "mongo-node9:27017" },
{ _id: 2, host: "mongo-node10:27017" }
] })
Podemos verificar o cluster de conjunto de réplicas atual usando o comando rs.status() em qualquer nó do cluster:
my-mongodb-rs:PRIMARY> rs.status()
{
"set" : "my-mongodb-rs",
"date" : ISODate("2020-10-30T06:27:41.693Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1604039248, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2020-10-30T06:27:28.305Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1604039248, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2020-10-30T06:27:28.305Z"),
"appliedOpTime" : {
"ts" : Timestamp(1604039248, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1604039248, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2020-10-30T06:27:28.305Z"),
"lastDurableWallTime" : ISODate("2020-10-30T06:27:28.305Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1604039245, 1),
"lastStableCheckpointTimestamp" : Timestamp(1604039245, 1),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2020-10-30T05:38:25.155Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1604036305, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 1,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"newTermStartDate" : ISODate("2020-10-30T05:38:25.171Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2020-10-30T05:38:25.180Z")
},
"members" : [
{
"_id" : 0,
"name" : "mongo-node8:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 3014,
"optime" : {
"ts" : Timestamp(1604039248, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-10-30T06:27:28Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1604036305, 2),
"electionDate" : ISODate("2020-10-30T05:38:25Z"),
"configVersion" : 7,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "mongo-node9:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 226,
"optime" : {
"ts" : Timestamp(1604039248, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1604039248, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-10-30T06:27:28Z"),
"optimeDurableDate" : ISODate("2020-10-30T06:27:28Z"),
"lastHeartbeat" : ISODate("2020-10-30T06:27:40.520Z"),
"lastHeartbeatRecv" : ISODate("2020-10-30T06:27:40.519Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "mongo-node8:27017",
"syncSourceHost" : "mongo-node8:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 7
},
{
"_id" : 2,
"name" : "mongo-node10:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 201,
"optime" : {
"ts" : Timestamp(1604039248, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1604039248, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-10-30T06:27:28Z"),
"optimeDurableDate" : ISODate("2020-10-30T06:27:28Z"),
"lastHeartbeat" : ISODate("2020-10-30T06:27:40.520Z"),
"lastHeartbeatRecv" : ISODate("2020-10-30T06:27:40.688Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "mongo-node8:27017",
"syncSourceHost" : "mongo-node8:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 7
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1604039248, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1604039248, 1)
}
Implante o Percona Server para MongoDB usando ClusterControl
O ClusterControl oferece suporte à implantação do Percona Server para MongoDB. As versões suportadas incluem 3.4, 3.6, 4.0 e 4.2. A implantação é simples, você só precisa ir para Deploy e escolher a guia MongoDB Replicaset conforme mostrado abaixo:
Preencha o usuário SSH, a senha, a porta e o nome do cluster. O ClusterControl requer que você configure o SSH sem senha entre o nó do controlador e o nó do banco de dados de destino antes da instalação. Após o preenchimento de todas as informações, clique em Continuar. Haverá outra página como mostrado abaixo:
Escolha Percona como um fornecedor, selecione a versão que deseja instalar. Se você tiver um diretório de dados personalizado do MongoDB, precisará especificá-lo. Defina o usuário e a senha do administrador para o seu MongoDB. Se você quiser usar outra porta em vez de usar o padrão (re. 27017), poderá alterá-la para outro número de porta. A última etapa é preencher o endereço IP do nó do banco de dados de destino na caixa de combinação Adicionar nó.
Depois que tudo estiver concluído, basta clicar no botão Deploy. Ele acionará um trabalho para implantar um cluster MongoDB, conforme mostrado abaixo:
Após a implementação, você pode ver a página Visão geral que já possui 3 instâncias do Percona Server para MongoDB em funcionamento.
A visualização de topologia abaixo mostra que você tem 1 nó primário e 2 nós secundários: