MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Comment empêcher les restaurations dans MongoDB

La réplication dans MongoDB implique des ensembles de répliques par membres avec une architecture de membres principaux et secondaires, mais parfois avec un membre non porteur de données appelé arbitre. Le processus de réplication est que, chaque fois que les données ont été écrites sur le nœud principal, les modifications sont enregistrées dans un fichier oplog à partir duquel les membres secondaires appliquent les mêmes modifications. Les opérations de lecture peuvent être effectuées à partir de n'importe quel membre porteur de données, créant ainsi un scénario communément appelé haute disponibilité.

Cependant, dans certains cas, les membres secondaires peuvent ne pas rattraper le principal en apportant des modifications et en cas de défaillance du nœud principal avant que ces modifications aient été appliquées, on sera obligé de resynchroniser l'ensemble du cluster afin qu'ils puissent être dans le même état de données.

Qu'est-ce qu'une restauration ?

Il s'agit d'une fonctionnalité de basculement automatique dans MongoDB dans laquelle le nœud principal d'un jeu de réplicas peut échouer lors de modifications qui, malheureusement, finissent par ne pas être répercutées sur les membres secondaires à temps à partir de l'oplog. état du primaire à un avant que les modifications ne soient apportées.

Les retours en arrière ne sont donc nécessaires que lorsque le primaire a accepté d'écrire les opérations qui n'ont pas été répliquées sur les membres secondaires avant que le primaire ne descende pour une raison telle qu'une partition réseau. Si dans le cas où les opérations d'écriture parviennent à être répliquées dans l'un des membres qui est disponible et accessible à la majorité du jeu de répliques, une restauration ne se produira pas.

La raison principale derrière les restaurations dans MongoDB est de maintenir la cohérence des données pour tous les membres et donc, lorsque le primaire rejoint le jeu de répliques, si ses modifications n'ont pas été appliquées aux membres secondaires, elles seront annulées à l'état avant la panne.

Cependant, les retours en arrière doivent être rares ou plutôt évités dans MongoDB car ils peuvent entraîner de nombreuses pertes de données et par conséquent affecter le fonctionnement des applications connectées à la base de données.

Processus de restauration MongoDB

Considérons un ensemble d'instances dupliquées à trois membres avec A comme membre principal, B et C comme membres secondaires. Nous allons remplir les données vers A et déclencher en même temps un partitionnement du réseau vers B et C. Nous utiliserons MongoDB version 4.2 et Atlas dans ce test.

Nous allons d'abord obtenir l'état du jeu de réplicas en exécutant la commande rs.status() sur le shell mongo  

MongoDB Enterprise Cluster0-shard-0:PRIMARY> rs.status()

En regardant l'attribut membres, vous pouvez voir quelque chose comme

"members" : [

{

"_id" : 0,

"name" : "cluster0-shard-00-00-sc27x.mongodb.net:27017",

"health" : 1,

"state" : 2,

"stateStr" : "SECONDARY",

"uptime" : 1891079,

"optime" : {

"ts" : Timestamp(1594826711, 1),

"t" : NumberLong(27)

},

"optimeDurable" : {

"ts" : Timestamp(1594826711, 1),

"t" : NumberLong(27)

},

"optimeDate" : ISODate("2020-07-15T15:25:11Z"),

"optimeDurableDate" : ISODate("2020-07-15T15:25:11Z"),

"lastHeartbeat" : ISODate("2020-07-15T15:25:19.509Z"),

"lastHeartbeatRecv" : ISODate("2020-07-15T15:25:18.532Z"),

"pingMs" : NumberLong(0),

"lastHeartbeatMessage" : "",

"syncingTo" : "cluster0-shard-00-02-sc27x.mongodb.net:27017",

"syncSourceHost" : "cluster0-shard-00-02-sc27x.mongodb.net:27017",

"syncSourceId" : 2,

"infoMessage" : "",

"configVersion" : 4

},

{

"_id" : 1,

"name" : "cluster0-shard-00-01-sc27x.mongodb.net:27017",

"health" : 1,

"state" : 2,

"stateStr" : "SECONDARY",

"uptime" : 1891055,

"optime" : {

"ts" : Timestamp(1594826711, 1),

"t" : NumberLong(27)

},

"optimeDurable" : {

"ts" : Timestamp(1594826711, 1),

"t" : NumberLong(27)

},

"optimeDate" : ISODate("2020-07-15T15:25:11Z"),

"optimeDurableDate" : ISODate("2020-07-15T15:25:11Z"),

"lastHeartbeat" : ISODate("2020-07-15T15:25:17.914Z"),

"lastHeartbeatRecv" : ISODate("2020-07-15T15:25:19.403Z"),

"pingMs" : NumberLong(0),

"lastHeartbeatMessage" : "",

"syncingTo" : "cluster0-shard-00-02-sc27x.mongodb.net:27017",

"syncSourceHost" : "cluster0-shard-00-02-sc27x.mongodb.net:27017",

"syncSourceId" : 2,

"infoMessage" : "",

"configVersion" : 4

},

{

"_id" : 2,

"name" : "cluster0-shard-00-02-sc27x.mongodb.net:27017",

"health" : 1,

"state" : 1,

"stateStr" : "PRIMARY",

"uptime" : 1891089,

"optime" : {

"ts" : Timestamp(1594826711, 1),

"t" : NumberLong(27)

},

"optimeDate" : ISODate("2020-07-15T15:25:11Z"),

"syncingTo" : "",

"syncSourceHost" : "",

"syncSourceId" : -1,

"infoMessage" : "",

"electionTime" : Timestamp(1592935644, 1),

"electionDate" : ISODate("2020-06-23T18:07:24Z"),

"configVersion" : 4,

"self" : true,

"lastHeartbeatMessage" : ""

}

],

Cela vous montrera le statut de chaque membre de votre jeu de répliques. Nous avons maintenant ouvert un nouveau terminal pour le nœud A et l'avons rempli avec 20 000 enregistrements :

MongoDB Enterprise Cluster0-shard-0:PRIMARY> for (var y = 20000; y >= 0; y--) {

    db.mytest.insert( { record : y } )

 }

WriteResult({ "nInserted" : 1 })

MongoDB Enterprise Cluster0-shard-0:PRIMARY> db.mytest 2020-07-15T21:28:40.436+2128 I NETWORK  [thread1] trying reconnect to 127.0.0.1:3001 (127.0.0.1) failed

2020-07-15T21:28:41.436+2128 I 

NETWORK  [thread1] reconnect 127.0.0.1:3001 (127.0.0.1) ok

MongoDB Enterprise Cluster0-shard-0:SECONDARY> rs.slaveOk()

MongoDB Enterprise Cluster0-shard-0:SECONDARY> db.mytest.count()

20000

Pendant le partitionnement du réseau, A sera indisponible, ce qui le rendra indisponible pour B et C et donc B élu comme principal dans notre cas. Lorsque A rejoint, il sera ajouté en tant que secondaire et vous pouvez le vérifier à l'aide de la commande rs.status(). Cependant, certains enregistrements ont réussi à être répliqués sur le membre B avant le partitionnement du réseau, comme indiqué ci-dessous :(Rappelez-vous que dans ce cas, B est le principal maintenant)

MongoDB Enterprise Cluster0-shard-0:PRIMARY> db.mytest.find({}).count()

12480    

Le nombre est le nombre de documents qui ont pu être répliqués sur B avant que A ne tombe en panne.

Si nous écrivons des données sur B et permettons à A de rejoindre le réseau, nous pouvons remarquer quelques changements sur A

connecting to: 127.0.0.1:3001/admin

MongoDB Enterprise Cluster0-shard-0:ROLLBACK> 

MongoDB Enterprise Cluster0-shard-0:RECOVERING> 

MongoDB Enterprise Cluster0-shard-0:SECONDARY> 

MongoDB Enterprise Cluster0-shard-0:SECONDARY> 

MongoDB Enterprise Cluster0-shard-0:PRIMARY>

À l'aide d'un oplogFetcher, les membres secondaires synchronisent les entrées d'oplog à partir de leur syncSource. L'oplogFetcher déclenche une méthode de recherche sur l'oplog source suivie d'une série de séries de curseurs getMores. Lorsque A rejoint en tant que secondaire, la même approche est appliquée et un document supérieur à l'horodatage du prédicat est renvoyé. Si le premier document de B ne correspond pas à la dernière entrée de l'oplog de A, A sera contraint à une annulation.

Récupération des données de restauration dans MongoDB

Le rollback n'est pas une mauvaise chose dans MongDB mais il faut essayer autant que possible de s'assurer qu'ils ne se produisent pas assez souvent. Il s'agit d'une mesure automatique de sécurité garantissant la cohérence des données entre les membres d'un jeu de répliques. En cas de restauration, voici quelques étapes pour remédier à la situation :

Collection de données de restauration

Vous devez collecter les données des membres concernant la restauration. Pour ce faire, assurez-vous que les fichiers de restauration sont créés (uniquement disponible avec la version 4.0 de MongoDB) en activant createRollbackDataFiles. Par défaut, cette option est définie sur true, par conséquent, les fichiers de restauration seront toujours créés.

Les fichiers de restauration sont placés dans le chemin /rollback/. et ils contiennent des données qui peuvent être converties à partir du format BSON à l'aide de l'outil bsondump dans un format lisible par l'homme.

Charger les données des fichiers de restauration dans une base de données ou un serveur distinct

Mongorestore est un aspect vital de MongoDB qui peut aider à permettre la récupération des fichiers de données de restauration. La première chose à faire est de copier les fichiers de restauration sur un nouveau serveur, puis d'utiliser mongorestore pour charger les fichiers sur votre serveur. La commande mongorestore est illustrée ci-dessous.

mongorestore -u <> -p <> -h 127.0.0.1 -d <rollbackrestoretestdb> -c <rollbackrestoretestc> <path to the .bson file> --authenticationDatabase=<database of user>

Nettoyage des données inutiles et filtrage des données

Cette étape nécessite de faire preuve de discrétion pour choisir entre les données à conserver à partir des fichiers de restauration et les données à jeter. Il est conseillé d'importer toutes les données des fichiers de restauration, ce point de décision fait de cette étape l'étape la plus difficile de la récupération de données.

Utiliser l'élément principal en tant que cluster pour importer des données 

Commencez la dernière étape en téléchargeant les données nettoyées à l'aide de mongorestore et mongodump, puis en réimportant les données dans le cluster de production d'origine.

Prévenir les restaurations MongoDB

Afin d'empêcher les restaurations de données lors de l'utilisation de MongoDB, vous pouvez procéder comme suit.

Exécuter tous les membres votants ‘MAJORITÉ’

Cela peut être fait en utilisant w :la préoccupation d'écriture majoritaire qui a le pouvoir d'option demander un accusé de réception qui permettra l'opération d'écriture sur des balises spécifiques données d'instances Mongod. Ceci peut être réalisé en utilisant l'option w suivie de la balise . Pour empêcher le retour en arrière, tous les membres votants de MongoDB auront un journal activé et l'utilisation de w :préoccupation d'écriture majoritaire, cela garantit que la majorité est en mesure d'écrire et de définir des nœuds de réplique avant qu'un retour en arrière ne se produise. Il garantit également que le client reçoit un accusé de réception après avoir propagé l'opération d'écriture sur le jeu de réplicas.

Opérations utilisateur  

La version mise à jour de MongoDB, c'est-à-dire la version 4.2, a la capacité d'arrêter toutes les opérations en cours en cas de restauration.

Constructions d'index 

La version 4.2 de la version de compatibilité des fonctionnalités de MongoDB (fcv) "4.2" est capable d'attendre tous les index en cours qui sont en cours de construction et terminés avant qu'une restauration ne prenne lieu. Cependant, la version 4.0 attend la poursuite de l'avancement et crée un index d'arrière-plan, donc la possibilité d'une restauration est élevée.

Taille et limites

La version 4.0 de MongoDB n'a pas de limites répertoriées de données données qui peuvent être annulées lors de la construction d'un index d'arrière-plan en cours.

Conclusion 

La restauration de MongoDB est un phénomène courant pour ceux qui utilisent MongoDB sans savoir comment l'empêcher. Les retours en arrière sont évitables si l'on suit attentivement et adhère à certaines des pratiques sûres et des moyens d'éviter les retours en arrière dans MongoDB. Dans l'ensemble, il est toujours conseillé de mettre à niveau vers la dernière version de MongoDB afin d'éviter certains contretemps évitables.