Problèmes de gestion et de maintenance des grands clusters ElasticSearch et d'une solution GProxy


Préface


Le composant de recherche d'utilisateurs et la plate-forme de gestion des journaux sont une partie importante du service push. ElasticSearch (ES pour faire court), en tant que moteur de recherche distribué open source, peut mieux répondre aux exigences ci-dessus. Après de nombreuses années d'itération dans l'utilisation d'ES, je pousse a accumulé une riche expérience, notamment lorsque la quantité de données continue d'augmenter, comment gérer le cluster, maintenir la stabilité du cluster, et optimiser les performances du cluster, nous avons effectué de nombreuses pratiques.


Cet article décrit l'évolution de l'architecture ElasticSearch à partir de trois parties: les défis des grands clusters, la manière dont GProxy prend en charge plusieurs clusters et les conditions de fonctionnement actuelles.



f829fd81ce85452585001f13fe7992b6 ~ tplv-k3u1fbpfcp-zoom-1.image

Auteur | Xiaoyao, directeur R&D de la plateforme Itweet et ingénieur Java senior Nanyang



01

Présentation du service Push ES


Le scénario métier d'un push utilisant ES consiste principalement à ajouter, supprimer, modifier et stocker les informations utilisateur et le stockage des journaux. Il s'agit de l'un des principaux services qui prennent en charge le push, et ses caractéristiques sont les suivantes:

● Mise à jour rapide des données: nécessité de mettre à jour le portrait de l'utilisateur et d'autres informations en temps réel

● Conditions de requête compliquées: prenez en charge plusieurs dimensions pour compléter et compléter, et recherchez des conditions combinées

● Grande quantité de données de requête: une tâche push peut avoir besoin d'interroger des dizaines de millions de données


Il y a trois raisons principales pour lesquelles nous choisissons ES:

● Fournir un index en temps quasi réel, le plus court peut rechercher le document écrit en 1 s

● Il peut prendre en charge les requêtes avec des conditions complexes et répondre à nos différentes conditions de recherche

● Les fonctionnalités distribuées peuvent mieux répondre aux exigences d'expansion horizontale et de haute disponibilité

De plus, le responsable de l'ES et la communauté sont très actifs, et il y a beaucoup de produits écologiques autour, et les problèmes rencontrés peuvent en principe être bien résolus.




02

Les défis des grands clusters

Évolution du cluster push individuel

b8e481a468e943f9b15e5bb57cdfdcbd ~ tplv-k3u1fbpfcp-zoom-1.image


La figure ci-dessus montre le processus de poussée de l'évolution du cluster ES. Un push utilisait ES plus tôt. Au début, il a commencé à utiliser la version 0.20.x. À ce moment-là, le cluster était petit. Plus tard, afin de faire défiler les résultats de la requête sans source, l'index-source a été séparé et mis à niveau vers la version 0.90.x. Ensuite, la version officielle de la version 1.2.0 qui ne prend en charge aucune fonction de requête source, nous avons effectué la fusion de cluster. Par la suite, afin d'utiliser certaines des nouvelles fonctionnalités officielles, nous sommes passés aux versions 1.4.x et 1.5.x.


À ce stade, la taille du cluster est déjà très grande, il n'est pas pratique de mettre à niveau la version une fois, et les nouvelles fonctionnalités suivantes ne sont pas très attrayantes pour nous, nous n'avons donc pas mis à niveau depuis longtemps, ignorant la version officielle 2.x. Cependant, en raison de la grande échelle du cluster, de nombreux problèmes difficiles à résoudre ont commencé à apparaître. Il a dû être divisé et mis à niveau, et la version officielle a également été mise à jour vers la version 5.x. Elle ne prend pas en charge la mise à niveau de 1.x vers 5.x, nous avons donc envisagé d'utiliser la passerelle de données. Pour résoudre les difficultés de mise à niveau et de redémarrage, le cluster a également évolué vers la dernière version de l'architecture ci-dessus.


Problèmes avec les grands clusters

Les gros clusters posent également de nombreux problèmes, dont certains des problèmes relativement difficiles que nous avons rencontrés lors de l'utilisation.


● Le premier problème est que la mémoire JVM a tendance à rester élevée.

La mémoire ES occupe plusieurs parties: mémoire de segment, cache de filtre, cache de données de champ, file d'attente en bloc, tampon d'indexation et tampon d'état de cluster. La mémoire de segment augmentera avec la croissance des fichiers de segment, et l'utilisation de la mémoire d'un grand cluster ne peut être évitée.


Le cache de filtre et le cache de données de champ ne sont pas utilisés dans de nombreux scénarios, nous les désactivons donc via la configuration des paramètres. Bulk Queue et Indexing Buffer sont relativement fixes, la mémoire ne continuera pas à augmenter et il n'est pas nécessaire d'ajuster les paramètres. La mémoire tampon d'état du cluster était un problème délicat à l'époque. La façon dont nous avons configuré le mappage consistait à configurer le fichier default_mapping.json dans le répertoire config. Ce fichier correspondrait à tous les documents écrits et effectuerait une analyse de format. Après le traitement ES, il sera en mémoire. Une copie de ParserContext est mise en cache dans. À mesure que le nombre de types continue d'augmenter, cette partie de l'utilisation de la mémoire augmentera jusqu'à ce qu'elle soit épuisée. Si le nouveau type n'est pas indexé, il n'augmentera pas.


Lorsqu'il y avait un problème de mémoire élevée, nous avons analysé son fichier de vidage, comme le montre la figure ci-dessous, et avons constaté qu'il était causé par l'occupation de ParserContext. À ce moment-là, il n'y avait pas de bon moyen de le résoudre complètement, et le seul moyen d'effacer le ParserContext en redémarrant était de le soulager temporairement pendant un certain temps. Cependant, avec l'écriture continue des documents, cette partie de l'utilisation de la mémoire augmentera à nouveau.


14f4e7b2b6b24acabefc363f97de24e1 ~ tplv-k3u1fbpfcp-zoom-1.image

● Le deuxième problème concerne les fragments surdimensionnés et les segments surdimensionnés.

Par défaut, nous utilisons docid comme base de routage, et les documents de hachage vers différentes partitions via l'algorithme de hachage. De cette manière, la taille des fragments est relativement uniforme lorsque le nombre de documents est petit, mais lorsque le nombre de documents augmente dans une certaine mesure, l'écart de taille des fragments devient plus grand. Lorsque la taille moyenne de chaque tranche est de 100 g, l'écart peut atteindre jusqu'à 20 g. À ce stade, le nombre de segments atteignant la limite de seuil de segment maximum est également très important, ce qui conduit à une fusion de segments qui prend du temps.


● Le troisième problème concerne les E / S disque élevées.

Nous utilisons souvent le défilement pour interroger les documents. Les fichiers à segments volumineux réduiront l'efficacité de la recherche de fichiers sur disque. De plus, la majeure partie de la mémoire de la machine est occupée par la JVM du nœud ES, ce qui rend difficile pour le système de fichiers d'utiliser la mémoire pour mettre en cache les pages de fichiers de segment. Cela provoque la requête de défilement pour lire directement le fichier de disque et l'IO est plein. Du point de vue de la surveillance, l'IO du cluster est pratiquement plein à tout moment.

15299ce07b204dd8b985f97c4e352079 ~ tplv-k3u1fbpfcp-zoom-1.image


De plus, il existe de nombreux dangers cachés.


Le premier est le goulot d'étranglement de l'expansion. Le nombre prédéfini de partitions dans le cluster était initialement suffisant. Cependant, après plusieurs expansions, le nombre d'instances est égal au nombre de partitions. Une fois les instances développées, le cluster n'allouera pas de partitions aux nouvelles Exemple. Deuxièmement, l'espace disque de la machine d'origine est progressivement insuffisant. La limite d'eau par défaut ES est de 85%, et les fragments commenceront à sauter au hasard après l'avoir atteint et il est difficile de récupérer.


Ensuite, il est difficile de régler. Le redémarrage et la récupération sont très lents. Si vous mettez à niveau et reconstruisez, l'index est également très lent.


Enfin, la robustesse du cluster sera également affectée. Au fur et à mesure que le nombre de documents augmente, la pression augmente et les échecs sont plus susceptibles de se produire. Après l'échec d'une instance, la pression sera répartie sur d'autres nœuds et l'entreprise aura une perception.

cab353c898e84d17bae270da97fa752f ~ tplv-k3u1fbpfcp-zoom-1.image




03

La solution GProxy


Pour les problèmes décrits ci-dessus, nous espérons trouver une solution pouvant fournir les fonctions suivantes:

1. Il peut mettre à niveau en douceur la version du cluster sans affecter l'utilisation de l'entreprise pendant la mise à niveau

2. En divisant les grands clusters en petits clusters, les activités sont divisées et la pression sur les clusters est réduite

3. Fournir plusieurs sauvegardes à chaud IDC des données du cluster et fournir une prise en charge de la couche de données pour plusieurs activités à différents endroits


Cependant, dans l'architecture précédente, les services métier accèdent directement au cluster ES, et le couplage est sévère, ce qui rend plus difficile la satisfaction de ces exigences. Par conséquent, nous avons choisi une architecture basée sur un proxy pour isoler les clusters de stockage et les clusters de services métier en ajoutant un proxy de couche intermédiaire afin de prendre en charge un fonctionnement et une maintenance plus flexibles des clusters de stockage.

4d823b932df24e2aac8ead67236f2a46 ~ tplv-k3u1fbpfcp-zoom-1.image


L'image ci-dessus est l'architecture globale de GProxy, qui est une architecture à trois niveaux:

● La couche supérieure est la couche métier, qui n'a besoin que d'interagir avec le proxy et de réaliser la découverte de service du proxy via etcd

● Au milieu se trouve la couche GProxy, qui assure le transfert des demandes et la gestion des clusters

● En bas se trouvent plusieurs clusters ES


GProxy contient plusieurs composants:

● etcd: une base de données de stockage de méta-informations hautement disponible, comprenant des règles de routage, des informations de cluster, des adresses de service proxy, des tâches de migration, etc.

● SDK: étend le SDK natif d'ES et encapsule des fonctions telles que la découverte et la fusion des services proxy via son mécanisme de détection.

● Proxy est un service proxy léger, il est très pratique de se développer, vous pouvez enregistrer votre adresse dans etcd après le démarrage

● Le tableau de bord est le service de gestion de l'ensemble du cluster et fournit une interface Web pour faciliter la gestion et le suivi du cluster par le personnel d'exploitation et de maintenance

● Le service de migration fournit des fonctions de migration entre différents clusters


Découverte de services et règles de routage


Avec l'architecture globale ci-dessus, il y a deux autres problèmes à résoudre:

1. Comment le service métier découvre-t-il le proxy, c'est-à-dire le problème de découverte de service

2. À quel cluster le proxy transmet la demande, c'est-à-dire le problème de routage



Découverte de service

etcd est une base de données clé-valeur distribuée hautement disponible, et elle interagit via http api, qui est facile à utiliser, nous avons donc choisi etcd pour réaliser la découverte de services et le stockage des métadonnées.

3671019835ed44cb9318b3732614b2ca ~ tplv-k3u1fbpfcp-zoom-1.image



Proxy est un service sans état. Une fois le démarrage et l'initialisation terminés, il enregistre son adresse dans etcd. Grâce au mécanisme de location d'etcd, le système peut surveiller l'état de survie du proxy. Lorsque le service proxy est anormal et que le bail ne peut pas être renouvelé régulièrement, etcd le supprimera pour éviter qu'il n'affecte les demandes commerciales normales.


Le sdk fourni par ElasticSearch réserve l'interface sniffer, et le sdk peut obtenir l'adresse back-end via l'interface sniffer. Nous avons implémenté l'interface sniffer, qui obtient régulièrement la liste de proxy d'etcd, surveille les services en ligne et hors ligne via le mécanisme de surveillance d'etcd, et met à jour la liste des connexions internes à temps. Le côté commercial peut toujours utiliser le SDK natif de la manière originale, sans trop de modifications, il suffit d'injecter les renifleurs dans le SDK.


Règles de routage

Dans un scénario d'entreprise push push, les données requises pour chaque push d'application peuvent être considérées comme un tout, nous choisissons donc d'acheminer la demande en fonction des dimensions de l'application, et les données requises pour chaque push d'application sont stockées dans un cluster.


Les informations de routage sont stockées dans etcd, et le format est appid-> clusterName une telle correspondance. S'il n'y a pas une telle correspondance, le proxy attribuera l'appid à un cluster par défaut.

Lorsque le proxy démarre, il extrait la dernière table de routage et surveille les modifications de la table de routage via le mécanisme de surveillance d'etcd.

72b0a33b32f4468d8d5f561e34cbc8fc ~ tplv-k3u1fbpfcp-zoom-1.image


La modification de la relation de routage est réalisée via l'opération de migration. Ce qui suit est une introduction au processus de migration.


Processus de migration

Chaque application appartient à un cluster. Lorsque la charge du cluster n'est pas équilibrée, l'administrateur peut utiliser le service de migration pour migrer les données entre les clusters en fonction de la dimension de l'application.


301c826985fb409091bcf537b72390d6 ~ tplv-k3u1fbpfcp-zoom-1.image

Le processus de migration se compose de deux étapes: la synchronisation des données et la modification des règles de routage. La synchronisation des données doit synchroniser deux éléments de données: les données complètes et les données incrémentielles.

1. Les données complètes sont exportées via l'API de défilement d'ElasticSearch

2. Étant donné qu'ElasticSearch ne fournit pas de moyen d'obtenir des données incrémentielles (similaire au protocole binlog de mysql pour obtenir une acquisition incrémentielle de données), nous utilisons une double écriture proxy pour obtenir une acquisition incrémentielle de données.


Le service de migration est responsable de la synchronisation des données et notifie le tableau de bord une fois la synchronisation des données terminée, et le tableau de bord met à jour la relation de routage de etcd. Le proxy obtient la nouvelle relation de routage via le mécanisme de surveillance et met à jour la table de routage interne. À ce stade, la nouvelle demande de l'application sera acheminée vers le nouveau cluster.



Sauvegarde à chaud de plusieurs données IDC


Dans le scénario commercial réel d'un push, push est un service au niveau de l'entreprise, qui nécessite une haute disponibilité des services. Dans un push, il existe plusieurs salles informatiques pour fournir des services externes, et chaque application appartient à une salle informatique. Afin de faire face aux pannes au niveau de la salle informatique, nous devons effectuer une sauvegarde à chaud multi-IDC des données afin qu'après l'échec de la salle informatique, la demande du client puisse être acheminée vers la salle informatique non défectueuse, afin de ne pas affecter l'utilisation normale des clients.


ac813ac8c8914f06a4ba923bc8930b3b ~ tplv-k3u1fbpfcp-zoom-1.image

Nous utilisons des dimensions de cluster pour la sauvegarde à chaud des données, et les données de chaque cluster seront sauvegardées dans une autre salle informatique. Après avoir reçu la demande, le proxy écrit les données incrémentielles sur le MQ en temps réel en fonction des informations de secours du cluster, et le service client dans une autre salle informatique consomme en permanence les données incrémentielles du MQ et les écrit dans le cluster correspondant. Le service de tableau de bord est chargé de contrôler l'état de toutes les tâches de sauvegarde à chaud IDC.


performance

Après introduction d'une couche intermédiaire, une certaine perte de performance se produira inévitablement. La raison pour laquelle nous choisissons le développement GO est de minimiser les pertes autant que possible. Les résultats finaux des performances sont les suivants:

bb6bb193554d4f88a4a57d195fbcddcb ~ tplv-k3u1fbpfcp-zoom-1.image

Comme on peut le voir sur la figure ci-dessus, QPS est réduit d'environ 10%, et le retard moyen est approximativement égal à la somme du retard moyen de l'appel ES et du proxy lui-même. Bien qu'il y ait une dégradation des performances de 10%, il apporte des capacités d'exploitation et de maintenance plus flexibles.


L'opération en cours

Une fois le service GProxy mis en ligne, la mise à niveau de la version ES (de la version 1.5 à la version 6.4) s'est terminée avec succès et le grand cluster d'origine a été divisé en plusieurs petits clusters. L'ensemble du processus de mise à niveau et de fractionnement est insensible au côté métier, et la fonction de restauration sans perte fournie par GProxy peut rendre l'opération plus sûre (la migration des données doit être très prudente).


Avec la prise en charge de GProxy, les opérations quotidiennes d'exploitation et de maintenance des ES de DBA, telles que l'optimisation des paramètres et l'équilibre de la pression entre les clusters, deviennent plus pratiques.





Conclusion

Grâce à l'utilisation du langage Go, la société a développé indépendamment Gproxy, a résolu avec succès les problèmes existant dans le grand cluster ElasticSearch et a fourni des services de stockage de données stables et fiables pour l'entreprise de niveau supérieur. En outre, GeTui continuera à peaufiner sa propre technologie, continuera d'explorer dans le domaine de la recherche et du stockage de données, continuera à étendre les scénarios d'application d'ElasticSearch et partagera les dernières pratiques sur la façon d'assurer la haute disponibilité du stockage de données avec les développeurs.


5bc8ecc0e30b406eb762b3285c640286 ~ tplv-k3u1fbpfcp-zoom-1.image



Je suppose que tu aimes

Origine blog.51cto.com/13031991/2540743
conseillé
Classement