Optimisation et finition de la base de données: séparation des requêtes

Introduction

Caractéristiques du système

Le système de service client dispose d'une fonction d'interrogation des bons de travail. Les caractéristiques de la table des bons de travail et les besoins des utilisateurs sont les suivants:
1) Des dizaines de millions de données sont stockées dans la table des bons de travail.
2) Lors de l'interrogation des données de la table des bons de travail, plus d'une douzaine de sous-tables doivent être associées et les données de chaque sous-table dépassent 100 millions.
3) Certaines données du tableau des bons de travail datent de quelques années et les clients ont besoin de ces données pour continuer à être mises à jour.


Description du problème

Chaque fois qu'un client interroge des données, cela peut prendre des dizaines de secondes, voire plus, pour renvoyer les résultats.


Sélection de solution

Méthode 1: Utilisez des techniques d'optimisation de base de données telles que les index et SQL pour résoudre le problème. Cependant, en raison de l'énorme quantité de données et des nombreux sous-tableaux associés, l'effet d'optimisation n'est pas évident.
Méthode 2: Utilisez la séparation du froid et de la chaleur, mais les restrictions de la demande du client à l'article 3), passez directement le programme.


Existe-t-il une solution pour résoudre le problème de la lenteur des requêtes du système de caractéristiques mentionné ci-dessus?
La réponse est oui, c'est la séparation des requêtes que nous allons introduire dans cet article .


2. Qu'est-ce que la séparation des requêtes?

La séparation des requêtes signifie: à chaque fois que des données sont écrites, en plus de l'écriture des données dans la base de données principale, une autre copie des données est enregistrée dans un autre système de stockage et l'utilisateur obtient directement les données de l'autre système de stockage lors de l'interrogation des données.
Insérez la description de l'image ici


3. Dans quels scénarios la séparation des requêtes est-elle utilisée?

Je crois que dans le premier chapitre, nous avons une compréhension préliminaire des scénarios d'utilisation de la séparation des requêtes.
Ci-dessous, nous résumons les situations dans lesquelles la séparation des requêtes doit être utilisée dans les affaires réelles:

  • Grande quantité de données;
  • L'efficacité de toutes les demandes d'écriture de données est acceptable;
  • L'efficacité de la demande de données de requête est très faible;
  • Toutes les données peuvent être modifiées à tout moment;
  • L'entreprise souhaite que nous optimisions la fonction d'interrogation des données.


Quatre, idées de réalisation de séparation de requêtes

Insérez la description de l'image ici


4.1 Comment déclencher la séparation des requêtes?

Comment déclencher la séparation des requêtes peut être simplement compris comme suit: quand une copie des données doit-elle être enregistrée dans les données de la requête.
D'une manière générale, il existe deux façons de séparer et de déclencher la requête: l'implémentation du code de la couche métier et l'implémentation du binlog . L'implémentation du code de la couche métier peut être subdivisée en deux méthodes d'implémentation (synchrone, asynchrone).

(1) Implémentation du code de couche métier: après l'écriture de données régulières, les données de requête sont créées de manière synchrone.

Scénarios applicables: le code métier est relativement simple et ne nécessite pas une vitesse de réponse élevée pour les opérations d'écriture.
Insérez la description de l'image ici


(2) Implémentation du code de couche métier: après l'écriture de données régulières, les données de requête sont créées de manière asynchrone.

Scénario d'utilisation: le code métier est relativement simple et nécessite la vitesse de réponse des opérations d'écriture. (Dans les scénarios commerciaux réels, cette méthode est utilisée plus souvent)
Insérez la description de l'image ici


(3) Le binlog du journal de la base de données de surveillance est implémenté: s'il y a un changement de données, les données de la requête sont mises à jour.

Scénario d'utilisation: le code métier est plus compliqué ou le changement est trop coûteux.
Insérez la description de l'image ici

Comparaison des avantages et des inconvénients des trois méthodes de déclenchement
Insérez la description de l'image ici
Plusieurs concepts du tableau expliquent:
Qu'est-ce qu'une logique métier flexible et contrôlable? De manière générale, la personne qui écrit le code métier peut rapidement juger à partir de la logique métier dans quelles circonstances mettre à jour les données de la requête, tandis que la personne qui surveille le journal de la base de données ne peut pas épuiser toutes les branches de modification de la base de données, puis associer toutes les possibilités à Dans le logique de données de requête de mise à jour correspondante, toute modification des données qui entraîne finalement la nécessité de rétablir les données de requête.

Qu'est-ce qui ralentit la vitesse de l'opération d'écriture? Quelle vitesse d'opération d'écriture peut être ralentie par une action d'établissement de données de requête? Réponse: beaucoup.
Prenez un châtaigne: lorsque vous mettez simplement à jour le logo d'une commande, il ne faut que 2 ms pour interroger les données, et cela peut impliquer une reconstruction lors de l'interrogation des données (comme l'indexation, le partage, la sauvegarde maître-esclave lors de l'utilisation d'ES pour interroger des données, chaque action est subdivisé en plusieurs sous-actions, dont nous parlerons plus tard.) À ce stade, le processus d'établissement des données de requête peut prendre 1s, de 2ms à 1. Pensez-vous que le ralentissement est important?

Avant que les données de requête ne soient mises à jour, les utilisateurs peuvent interroger des données obsolètes. Ici, nous combinons la deuxième logique de déclenchement, par exemple, une opération est dans l'état de mise à jour de l'ordre et les données seront interrogées de manière asynchrone lorsque l'état est mis à jour. Après la mise à jour, l'ordre passera de l'état "en attente d'examen" à l'état État "révisé". En supposant qu'il faut 1 seconde pour mettre à jour les données de la requête, si l'utilisateur interroge le statut de la commande pendant cette 1 seconde, bien que les données de base soient passées au statut "révisé", le résultat final de la requête affiche toujours le statut "révision en attente" .


4.2 Comment réaliser la séparation des requêtes?

Cela concerne uniquement l' implémentation du code de la couche de gestion: après avoir écrit des données régulières, établissez de manière asynchrone la méthode de séparation des requêtes de données de requête à expliquer. Il existe deux façons de résumer brièvement:

(1) Méthode 1 : démarrer un thread distinct pour établir les données de requête

Cette implémentation est relativement simple, mais les problèmes suivants peuvent survenir dans les applications réelles:

  • Il y a trop d'opérations d'écriture et trop de threads, qui finiront par éclater la JVM;
  • Comment réessayer automatiquement le thread qui a créé les données de requête;
  • En cas de concurrence multithread, de nombreux scénarios de concurrence doivent être résolus.

D'après la liste de questions ci-dessus, nous savons que bien que cette méthode soit simple, il existe de nombreux problèmes. Par conséquent, cette méthode n'est pas recommandée.


(B) Mode de réalisation 2 : la gestion MQ emprunte
une opération spécifique en pensant à l'opération d'écriture du maître MQ pour chaque demande de traitement de données, enverra un avis à MQ, MQ notifiée après qu'un thread de réveil met à jour la requête de données, le diagramme schématique suivant:
Insérez la description de l'image ici
comprendre Après le idées de fonctionnement spécifiques de MQ, nous devrions également considérer les 5 problèmes majeurs suivants:

(1) Question 1: Comment sélectionner MQ?
Il n'y a pas de condition de référence absolue pour sélectionner MQ. Vous pouvez sélectionner en fonction de votre situation réelle.
Par exemple, si l'entreprise a déjà utilisé MQ et a été bien appliquée dans le projet, vous pouvez alors choisir le MQ que vous connaissez et qui a été testé en combat réel. Après tout, la technologie perfectionnée peut éviter les fossés et les détours.

Si l'entreprise n'a pas encore utilisé MQ et n'est pas familiarisée avec les avantages et les inconvénients de divers types de MQ et de scénarios d'utilisation, la sélection de MQ est nécessaire.
En général, il existe les principes suivants pour la sélection à titre de référence:
1) Selon les besoins et les caractéristiques de l'entreprise, choisissez plusieurs MQ plus appropriées.
2) Invitez tous ceux qui peuvent prendre des décisions techniques au centre technologique à voter pour la sélection.
3) Considérer du point de vue de la facilité d'utilisation et de la charge de travail du code.


(2) Question 2: Que dois-je faire si MQ est en panne?
S'il y a un temps d'arrêt MQ, nous devons nous assurer que le processus principal se déroule normalement et que le flux de travail ne peut pas être bloqué en raison du temps d'arrêt MQ; en même temps, assurez-vous que les données peuvent être traitées normalement après la restauration du MQ .
plan spécifique:

  • À chaque opération d'écriture, ajoutez une marque aux données principales: NeedUpdateQueryData = true, de sorte que le message envoyé à MQ soit très simple, juste un simple signal pour mettre à jour les données et ne contienne pas l'ID de données mis à jour.
  • Après avoir reçu le signal, les consommateurs MQ interrogent d'abord par lots les données de base à mettre à jour, puis mettent à jour par lots les données de la requête. Après la mise à jour, l'identificateur de données de base NeedUpdateQueryData des données de la requête est mis à jour sur false.
  • Bien sûr, il existe des cas où plusieurs consommateurs effectuent des actions en même temps, ce qui implique le problème de la concurrence, qui est similaire à la logique de traitement de la concurrence dans la séparation du froid et du chaud.


(3) Question 3: Que dois-je faire si le thread de mise à jour des données de requête échoue?
Si le thread de mise à jour échoue, l'ID de NeedUpdateQueryData ne sera pas mis à jour et les consommateurs suivants retireront à nouveau les données identifiées par NeedUpdateQueryData pour traitement. Mais s'il continue à échouer, nous pouvons ajouter un nombre supplémentaire de tentatives de traitement aux données principales, comme +1 pour chaque tentative de déplacement, et l'effacer après le succès, afin de surveiller les données qui ont trop de tentatives de déplacement.


(4) Question 4: Consommation idempotente de messages
En programmation, une opération idempotente est caractérisée par le même effet d'exécuter une opération plusieurs fois.

Par exemple, après la mise à jour de l'ordre A des données de base, nous insérons A dans les données de la requête, mais pour le moment, le système rencontre un problème. Le système croit à tort que les données de la requête n'ont pas été mises à jour, puis insère et met à jour l'ordre A encore.

La soi-disant idempotence signifie que quel que soit le nombre de fois que la logique de mise à jour des données de requête est exécutée, le résultat est le résultat que nous voulons. Par conséquent, lorsque nous examinons le problème de la concurrence du côté des consommateurs, nous devons nous assurer que les données de la requête de mise à jour sont idempotentes.


(5) Question 5: Problème de synchronisation du message. Par
exemple, un ordre A met à jour les données une fois pour devenir A1, et le thread A déplace les données de A1 vers les données de requête. Après un certain temps, l'ordre principal A a de nouveau mis à jour ses données pour devenir A2, et le thread B a également commencé à travailler, déplaçant les données d'A2 vers les données de requête.

Le soi-disant minutage est que si le thread A démarre plus tôt que le thread B, mais que le mouvement des données en mouvement est terminé plus tard que le thread B, il est possible que les données de la requête finissent par devenir A1 expiré. Comme le montre la figure ci-dessous (le numéro de séquence devant l'action représente la séquence de l'action réelle):
Insérez la description de l'image ici
Solution:
mettez à jour l'heure de la dernière mise à jour last_update_time pour chaque mise à jour, puis après que chaque thread met à jour les données de la requête, vérifiez si last_update_time de l'ordre actuel A est le même que le thread qui vient de démarrer L'heure est la même, et si NeedUpdateQueryData est égal à false, s'ils sont tous satisfaits, nous changerons NeedUpdateQueryData en true, puis effectuerons un autre déplacement.


4.3 Comment stocker les données de requête?
Le choix de la technologie de stockage de données nécessite une prise en compte globale en combinaison avec les besoins réels de l'entreprise et sa propre structure organisationnelle.

À l'heure actuelle, Elasticsearch est largement utilisé pour les requêtes de recherche avec de grandes quantités de données.


4.4 Comment utiliser les données de requête?
Si dans la section précédente, nous avons choisi Elasticsearch pour implémenter des requêtes de recherche avec une grande quantité de données, alors lors de l'interrogation de données, nous pouvons directement appeler des fonctions de l'API ES dans le code.

Cette méthode peut avoir le problème de "données de requête incohérentes avant la mise à jour de la requête de données". Pour le moment, nous pouvons nous référer aux deux solutions suivantes à résoudre:
1) Idée 1: avant que les données de la requête ne soient mises à jour au plus tard, les utilisateurs ne sont pas autorisés à interroger.

2) Idée 2: Pour rappeler aux utilisateurs que les données actuellement interrogées peuvent être les données d'il y a 1 seconde. Si les données s'avèrent inexactes, vous pouvez essayer de les actualiser.


5. Plan général et lacunes de la séparation des requêtes


5.1 La solution globale de la séparation des requêtes
Insérez la description de l'image ici


5.2 Les faiblesses de la
solution de séparation des requêtes Bien que la solution de séparation des requêtes puisse résoudre certains problèmes, il faut aussi bien comprendre ses faiblesses.
1) Lorsque vous utilisez Elasticsearch pour stocker et interroger des données, certaines choses à prendre en compte doivent être claires.
2) Une fois que le volume de données principal devient de plus en plus grand, l'opération d'écriture est encore lente et des problèmes se produiront toujours à ce moment-là.
3) Lorsque les données de base et les données de requête sont incohérentes, en supposant que la logique métier doit maintenir la cohérence des données de requête, c'est également un problème que nous devons prendre en compte.

Je suppose que tu aimes

Origine blog.csdn.net/locahuang/article/details/112562237
conseillé
Classement