Meilleures pratiques pour optimiser les performances de lecture dans les jeux de réplicas
Améliorez les lectures des jeux de réplicas MongoDB grâce à la préférence de lecture, la préoccupation de lecture, la surveillance du décalage, l'indexation et les contrôles de délai d'attente.
Meilleures pratiques pour optimiser les performances de lecture dans les jeux de réplicas
Les jeux de réplicas MongoDB offrent une haute disponibilité, mais ils n'accélèrent pas automatiquement les lectures. Si votre application envoie chaque requête au primaire, utilise des index faibles ou lit à partir de secondaires en retard, les utilisateurs ressentiront des pages lentes et des données obsolètes.
De bonnes performances de lecture proviennent du choix de la bonne préférence de lecture, de l'adaptation de la préoccupation de lecture à la cohérence dont vous avez besoin, de la surveillance du décalage de réplication et de la correction des requêtes lentes en premier.
Comprendre le chemin de lecture dans les jeux de réplicas
Dans un déploiement standard de jeu de réplicas, un membre est désigné comme le primaire, gérant toutes les écritures. Les membres restants sont des secondaires, qui répliquent de manière asynchrone les données du primaire. Les lectures de l'application peuvent être dirigées vers le primaire ou distribuées sur les secondaires, selon la configuration.
Optimiser les lectures signifie équilibrer le besoin de cohérence immédiate des données (qui nécessite souvent de lire depuis le primaire) avec le désir de décharger le trafic du primaire (en lisant depuis les secondaires).
1. Utilisation stratégique des préoccupations de lecture
La préoccupation de lecture définit le degré de cohérence des données requis pour les opérations de lecture. Définir une préoccupation de lecture trop stricte alors qu'une préoccupation plus relâchée suffit est une cause courante de latence de lecture, car cela peut forcer l'opération à attendre des confirmations de plusieurs nœuds.
Préoccupations de lecture disponibles
MongoDB propose plusieurs préoccupations de lecture, chacune faisant un compromis entre latence et durabilité/cohérence :
| Préoccupation de lecture | Description | Cas d'utilisation |
|---|---|---|
majority |
Renvoie les données reconnues comme validées par une majorité de nœuds votants. Par défaut standard. | Lectures à usage général nécessitant une haute durabilité. |
local |
Renvoie les données les plus récentes disponibles sur le membre interrogé, indépendamment de la confirmation d'écriture. | Lectures pouvant tolérer des données légèrement obsolètes (par exemple, compteurs de tableau de bord). |
linearizable |
Lit depuis le primaire et reflète toutes les écritures reconnues avant le début de la lecture. Nécessite readConcern: "linearizable" et une préoccupation d'écriture majoritaire pour les écritures concernées. |
Lectures rares qui doivent observer l'état reconnu le plus récent, comme les vérifications de propriété de verrou. |
Astuce d'optimisation : Par défaut sur local ou majority
Pour les lectures non critiques (comme le chargement de données de configuration rarement mises à jour ou de résultats en cache), utilisez la préoccupation de lecture local sur les secondaires. Cela évite tout délai de synchronisation.
Exemple : Définir la préoccupation de lecture au niveau de la session
// Définir la préoccupation de lecture sur 'local' pour cette session spécifique
const session = mongoClient.startSession({ readConcern: { level: "local" } });
// Opération de recherche utilisant la session
db.collection('mydata').find().session(session).toArray();
Avertissement : Lire avec la préoccupation
localsur un secondaire peut renvoyer des données obsolètes par rapport au primaire.
2. Distribuer les lectures sur les secondaires
Par défaut, MongoDB dirige les lectures vers le primaire. Pour augmenter la capacité de lecture, vous devez explicitement diriger les lectures vers les secondaires en utilisant les paramètres de Préférence de lecture.
Comprendre la préférence de lecture
La préférence de lecture dicte quels membres du jeu de réplicas sont éligibles pour satisfaire les demandes de lecture et dans quel ordre ils doivent être choisis.
Les préférences de lecture courantes incluent :
primary: (Par défaut) Seul le primaire est éligible.primaryPreferred: Essaie d'abord le primaire ; se rabat sur un secondaire si le primaire est indisponible.secondary: Seuls les secondaires sont éligibles. Si aucun secondaire n'est disponible, l'opération échoue.secondaryPreferred: Préfère les secondaires ; se rabat sur le primaire si aucun secondaire n'est disponible.nearest: Choisit le membre (primaire ou secondaire) avec la latence réseau la plus faible par rapport au client.
Astuce d'optimisation : Utiliser secondaryPreferred ou nearest
Pour la plupart des applications à forte charge de lecture, utiliser secondaryPreferred permet de distribuer la charge des requêtes sur tous les secondaires disponibles, réduisant considérablement la charge sur le primaire.
Si vous avez des serveurs d'application géographiquement distribués, nearest est souvent le meilleur choix, car il minimise la latence réseau pour le client, même s'il touche occasionnellement le primaire.
Exemple : Connexion avec secondaryPreferred
Lors de la connexion de votre pilote d'application, spécifiez la préférence de lecture :
const uri = "mongodb://host1,host2,host3/?replicaSet=rs0&readPreference=secondaryPreferred";
// Ou en utilisant les options de connexion dans une configuration de pilote
const options = {
readPreference: "secondaryPreferred"
};
3. Gérer la synchronisation et le décalage des secondaires
Si vous acheminez les lectures vers les secondaires, la performance de ces lectures dépend entièrement de la rapidité avec laquelle les secondaires suivent le primaire. Un décalage de réplication élevé signifie que les secondaires servent des données obsolètes, ou si le décalage est trop important, les lectures peuvent échouer ou expirer.
Surveiller le décalage de réplication
Surveillez toujours la différence d'optime entre le primaire et les secondaires. rs.status() montre l'état de réplication par membre, et les outils gérés comme MongoDB Atlas, Cloud Manager ou Ops Manager peuvent alerter en cas de décalage.
rs.status().members.map(m => ({
name: m.name,
stateStr: m.stateStr,
optimeDate: m.optimeDate
}))
Impact de la préoccupation d'écriture sur les performances des secondaires
Bien que cet article se concentre sur les lectures, des paramètres de préoccupation d'écriture élevés peuvent indirectement impacter les performances de lecture en ralentissant le primaire, ce qui à son tour fait que les secondaires prennent encore plus de retard.
Par exemple, exiger w: "majority" signifie que le client ne reçoit pas d'accusé de réception tant que l'écriture n'a pas atteint une majorité de membres votants porteurs de données. Si les secondaires sont lents en raison de la pression du disque ou du réseau, la latence d'écriture de l'application peut augmenter, et ces mêmes secondaires surchargés peuvent également servir des lectures lentes.
Meilleure pratique pour la préoccupation d'écriture (Optimisation indirecte des lectures) : Ne réduisez pas la préoccupation d'écriture juste pour rendre les lectures plus rapides. Choisissez la préoccupation d'écriture en fonction des exigences de durabilité, puis corrigez la cause du décalage : disques lents, secondaires surchargés, oplog sous-dimensionné, problèmes réseau ou requêtes en compétition avec la réplication.
4. Indexation et optimisation des requêtes
Aucun paramètre de configuration ne peut surmonter une requête mal écrite. Le principe fondamental des lectures rapides reste une indexation robuste.
Considérations clés sur l'indexation
- Requêtes couvertes : Concevez des requêtes qui peuvent être entièrement satisfaites par un index sans récupérer de documents du disque. Ce sont les lectures les plus rapides possibles.
- Alignement des index : Assurez-vous que les index correspondent aux champs utilisés dans vos clauses
find(),sort()etprojection(). - Évitez les scans de collection : Vérifiez toujours dans le profileur de requêtes que les opérations de lecture utilisent des index (
IXSCAN) plutôt que d'effectuer des scans complets de collection (COLLSCAN).
Réglage des délais d'attente des requêtes
Si une application atteint un secondaire fortement en retard, la requête peut expirer. Configurez des délais d'attente raisonnables dans votre application pour gérer gracieusement le décalage temporaire, peut-être en revenant au primaire ou en réessayant plus tard, plutôt que de rester bloqué indéfiniment.
Résumé des étapes d'optimisation des lectures
Pour obtenir des performances de lecture optimales dans votre jeu de réplicas MongoDB, suivez ces étapes concrètes :
- Identifiez les types de lectures : Classez les lectures entre celles nécessitant des données fraîches du primaire et celles pouvant tolérer une cohérence éventuelle des secondaires.
- Configurez la préférence de lecture : Définissez la chaîne de connexion ou les options de session pour utiliser
secondaryPreferredounearestpour la majorité du trafic de l'application. - Surveillez le décalage : Surveillez en continu le décalage de réplication à partir de
rs.status(), des métriques du pilote ou de votre plateforme de surveillance. Si le décalage est constamment élevé, enquêtez sur le matériel des secondaires ou les problèmes réseau. - Révisez les préoccupations d'écriture : Assurez-vous que les préoccupations d'écriture ne ralentissent pas indûment le primaire, ce qui prive les secondaires de données fraîches.
- Indexez minutieusement : Vérifiez que tous les chemins de lecture fréquemment exécutés utilisent des index efficaces.
La mise à l'échelle des lectures des jeux de réplicas fonctionne mieux lorsque vous êtes honnête sur l'obsolescence. Envoyez les lectures critiques pour l'utilisateur au primaire lorsqu'elles doivent être à jour, utilisez les secondaires pour les analyses ou les tableaux de bord qui peuvent tolérer un décalage, et continuez à mesurer les plans de requête et la santé de la réplication à mesure que le trafic change.