Cluster Elasticsearch 200 To+

Cluster Elasticsearch 200 To+

De nombreuses personnes rencontrent des difficultés avec Elasticsearch. Mais que se passe-t-il lorsque l’on souhaite l’utiliser pour stocker des logs « dans un volume particulièrement important » ? Et est-il également indolore de subir une panne de l’un des nombreux centres de données ? Quel type d’architecture réaliser et sur quels pièges allez-vous tomber ?

Chez Odnoklassniki, nous avons décidé d'utiliser elasticsearch pour résoudre le problème de la gestion des journaux, et maintenant nous partageons notre expérience avec Habr : à la fois sur l'architecture et sur les pièges.

Je m'appelle Piotr Zaitsev, je travaille comme administrateur système chez Odnoklassniki. Avant cela, j'étais également administrateur, j'ai travaillé avec Manticore Search, Sphinx search, Elasticsearch. Peut-être que si une autre recherche apparaît, je travaillerai probablement avec elle aussi. Je participe également à un certain nombre de projets open source sur une base volontaire.

Quand je suis arrivé à Odnoklassniki, j'ai dit imprudemment lors de l'entretien que je pouvais travailler avec Elasticsearch. Après avoir compris et accompli quelques tâches simples, on m'a confié la grande tâche de réformer le système de gestion des journaux qui existait à cette époque.

Exigences

La configuration système requise a été formulée comme suit :

  • Graylog devait être utilisé comme interface. Comme l'entreprise avait déjà de l'expérience dans l'utilisation de ce produit, les programmeurs et les testeurs le savaient, il leur était familier et pratique.
  • Volume de données : en moyenne 50 à 80 2 messages par seconde, mais si quelque chose tombe en panne, le trafic n'est limité par rien, il peut atteindre 3 à XNUMX millions de lignes par seconde
  • Après avoir discuté avec les clients des exigences relatives à la rapidité de traitement des requêtes de recherche, nous avons réalisé que le modèle typique d'utilisation d'un tel système est le suivant : les utilisateurs recherchent les journaux de leur application des deux derniers jours et ne veulent pas attendre plus d'un deuxièmement pour le résultat d'une requête formulée.
  • Les administrateurs ont insisté pour que le système soit facilement évolutif si nécessaire, sans qu'ils aient besoin d'approfondir son fonctionnement.
  • De sorte que la seule tâche de maintenance dont ces systèmes nécessitent périodiquement est de changer certains matériels.
  • De plus, Odnoklassniki a une excellente tradition technique : tout service que nous lançons doit survivre à une panne du centre de données (soudaine, imprévue et absolument à tout moment).

La dernière exigence de la mise en œuvre de ce projet nous a coûté le plus cher, dont je parlerai plus en détail.

mercredi

Nous travaillons dans quatre centres de données, tandis que les nœuds de données Elasticsearch ne peuvent être localisés que dans trois (pour un certain nombre de raisons non techniques).

Ces quatre centres de données contiennent environ 18 XNUMX sources de journaux différentes : matériel, conteneurs, machines virtuelles.

Caractéristique importante : le cluster démarre dans des conteneurs Podman pas sur des machines physiques, mais sur propre produit cloud one-cloud. Les conteneurs sont garantis 2 cœurs, similaires au 2.0Ghz v4, avec la possibilité de recycler les cœurs restants s'ils sont inactifs.

En d'autres termes:

Cluster Elasticsearch 200 To+

Topologie

J'ai d'abord vu la forme générale de la solution comme suit :

  • 3-4 VIP se trouvent derrière l'enregistrement A du domaine Graylog, c'est l'adresse à laquelle les logs sont envoyés.
  • chaque VIP est un équilibreur LVS.
  • Après cela, les journaux vont à la batterie Graylog, certaines données sont au format GELF, d'autres au format syslog.
  • Ensuite, tout cela est écrit en gros lots sur une batterie de coordinateurs Elasticsearch.
  • Et ils envoient à leur tour des requêtes d’écriture et de lecture aux nœuds de données concernés.

Cluster Elasticsearch 200 To+

Vocabulaire

Peut-être que tout le monde ne comprend pas la terminologie en détail, j'aimerais donc m'y attarder un peu.

Elasticsearch dispose de plusieurs types de nœuds : maître, coordinateur, nœud de données. Il existe deux autres types pour différentes transformations de journaux et communications entre différents clusters, mais nous avons utilisé uniquement ceux répertoriés.

Master
Il envoie une requête ping à tous les nœuds présents dans le cluster, maintient une carte de cluster à jour et la distribue entre les nœuds, traite la logique des événements et effectue divers types de maintenance à l'échelle du cluster.

Coordinatrice
Effectue une seule tâche : accepte les demandes de lecture ou d’écriture des clients et achemine ce trafic. En cas de demande d'écriture, il demandera très probablement au maître dans quel fragment de l'index concerné il doit le placer et redirigera davantage la demande.

Nœud de données
Stocke les données, effectue des requêtes de recherche arrivant de l'extérieur et effectue des opérations sur les fragments qui s'y trouvent.

bûche grise
C'est quelque chose comme une fusion de Kibana avec Logstash dans une pile ELK. Graylog combine à la fois une interface utilisateur et un pipeline de traitement des journaux. Sous le capot, Graylog exécute Kafka et Zookeeper, qui fournissent une connectivité à Graylog en tant que cluster. Graylog peut mettre en cache les journaux (Kafka) au cas où Elasticsearch serait indisponible et répéter les demandes de lecture et d'écriture infructueuses, regrouper et marquer les journaux selon les règles spécifiées. Comme Logstash, Graylog dispose d'une fonctionnalité permettant de modifier les lignes avant de les écrire dans Elasticsearch.

De plus, Graylog dispose d'une découverte de service intégrée qui permet, sur la base d'un nœud Elasticsearch disponible, d'obtenir l'intégralité de la carte du cluster et de la filtrer par une balise spécifique, ce qui permet de diriger les requêtes vers des conteneurs spécifiques.

Visuellement, cela ressemble à ceci :

Cluster Elasticsearch 200 To+

Ceci est une capture d'écran d'une instance spécifique. Ici, nous construisons un histogramme basé sur la requête de recherche et affichons les lignes pertinentes.

Indices

Revenant à l'architecture du système, je voudrais m'attarder plus en détail sur la façon dont nous avons construit le modèle d'index pour que tout fonctionne correctement.

Dans le diagramme ci-dessus, il s'agit du niveau le plus bas : les nœuds de données Elasticsearch.

Un index est une grande entité virtuelle composée de fragments Elasticsearch. En soi, chacun des fragments n'est rien de plus qu'un index Lucene. Et chaque index Lucene, à son tour, se compose d'un ou plusieurs segments.

Cluster Elasticsearch 200 To+

Lors de la conception, nous avons pensé que pour répondre à l'exigence de vitesse de lecture sur une grande quantité de données, nous devions « répartir » ces données uniformément entre les nœuds de données.

Cela a abouti au fait que le nombre de fragments par index (avec réplicas) doit être strictement égal au nombre de nœuds de données. Premièrement, afin d'assurer un facteur de réplication égal à deux (c'est-à-dire que l'on peut perdre la moitié du cluster). Et, d’autre part, afin de traiter les requêtes de lecture et d’écriture sur au moins la moitié du cluster.

Nous avons d'abord déterminé la durée de stockage à 30 jours.

La répartition des fragments peut être représentée graphiquement comme suit :

Cluster Elasticsearch 200 To+

L'ensemble du rectangle gris foncé est un index. Le carré rouge de gauche est le fragment principal, le premier de l'index. Et le carré bleu est une réplique du fragment. Ils sont situés dans différents centres de données.

Lorsque nous ajoutons un autre fragment, il est envoyé au troisième centre de données. Et, au final, on obtient cette structure, qui permet de perdre des DC sans perdre en cohérence des données :

Cluster Elasticsearch 200 To+

Rotation des index, c'est-à-dire en créant un nouvel index et en supprimant le plus ancien, nous l'avons rendu égal à 48 heures (selon le modèle d'utilisation de l'index : les dernières 48 heures sont recherchées le plus souvent).

Cet intervalle de rotation d'index est dû aux raisons suivantes :

Lorsqu'une requête de recherche arrive sur un nœud de données spécifique, du point de vue des performances, il est plus rentable d'interroger un fragment si sa taille est comparable à la taille de la hanche du nœud. Cela vous permet de conserver la partie « chaude » de l'index dans un tas et d'y accéder rapidement. Lorsqu'il y a beaucoup de « parties chaudes », la vitesse de recherche dans l'index se dégrade.

Lorsqu'un nœud commence à exécuter une requête de recherche sur une partition, il alloue un nombre de threads égal au nombre de cœurs hyperthreading de la machine physique. Si une requête de recherche affecte un grand nombre de fragments, le nombre de threads augmente proportionnellement. Cela a un impact négatif sur la vitesse de recherche et affecte négativement l'indexation des nouvelles données.

Pour fournir la latence de recherche nécessaire, nous avons décidé d'utiliser un SSD. Pour traiter rapidement les requêtes, les machines qui hébergeaient ces conteneurs devaient disposer d'au moins 56 cœurs. Le chiffre de 56 a été choisi comme valeur conditionnellement suffisante pour déterminer le nombre de threads qu'Elasticsearch générera pendant le fonctionnement. Dans Elasitcsearch, de nombreux paramètres du pool de threads dépendent directement du nombre de cœurs disponibles, ce qui à son tour affecte directement le nombre requis de nœuds dans le cluster selon le principe « moins de cœurs - plus de nœuds ».

En conséquence, nous avons constaté qu'un fragment pèse en moyenne environ 20 gigaoctets et qu'il y a 1 fragments par index. En conséquence, si nous les alternons toutes les 360 heures, nous en avons 48. Chaque index contient des données sur 15 jours.

Circuits d'écriture et de lecture de données

Voyons comment les données sont enregistrées dans ce système.

Disons qu'une demande arrive de Graylog au coordinateur. Par exemple, nous souhaitons indexer 2 à 3 XNUMX lignes.

Le coordinateur, ayant reçu une demande de Graylog, interroge le maître : « Dans la demande d'indexation, nous avons spécifiquement spécifié un index, mais dans quel fragment l'écrire n'a pas été précisé.

Le maître répond : « Écrivez ces informations sur le fragment numéro 71 », après quoi elles sont envoyées directement au nœud de données concerné, où se trouve le fragment principal numéro 71.

Après quoi, le journal des transactions est répliqué sur une partition de réplique située dans un autre centre de données.

Cluster Elasticsearch 200 To+

Une demande de recherche arrive de Graylog au coordinateur. Le coordinateur le redirige en fonction de l'index, tandis qu'Elasticsearch répartit les requêtes entre la partition principale et la partition réplica selon le principe du round-robin.

Cluster Elasticsearch 200 To+

Les 180 nœuds répondent de manière inégale et, pendant qu'ils répondent, le coordinateur accumule des informations qui ont déjà été « crachées » par des nœuds de données plus rapides. Après cela, lorsque toutes les informations sont arrivées ou que la demande a atteint un délai d'attente, il donne tout directement au client.

L'ensemble de ce système traite en moyenne les requêtes de recherche des dernières 48 heures en 300 à 400 ms, à l'exclusion des requêtes comportant un caractère générique de début.

Fleurs avec Elasticsearch : configuration Java

Cluster Elasticsearch 200 To+

Pour que tout fonctionne comme nous le souhaitions à l'origine, nous avons passé très longtemps à déboguer une grande variété de choses dans le cluster.

La première partie des problèmes découverts était liée à la manière dont Java est préconfiguré par défaut dans Elasticsearch.

Le premier problème
Nous avons observé un très grand nombre de rapports indiquant qu'au niveau Lucene, lorsque des tâches en arrière-plan sont en cours d'exécution, les fusions de segments Lucene échouent avec une erreur. Dans le même temps, il était clair dans les journaux qu’il s’agissait d’une erreur OutOfMemoryError. Nous avons vu par télémétrie que la hanche était libre, et la raison de l'échec de cette opération n'était pas claire.

Il s’est avéré que les fusions d’index Lucene se produisent en dehors de la hanche. Et les conteneurs sont assez strictement limités en termes de ressources consommées. Seul le tas pouvait tenir dans ces ressources (la valeur heap.size était approximativement égale à la RAM), et certaines opérations hors tas se bloquaient avec une erreur d'allocation de mémoire si, pour une raison quelconque, elles ne rentraient pas dans les ~ 500 Mo restants avant la limite.

Le correctif était assez trivial : la quantité de RAM disponible pour le conteneur a été augmentée, après quoi nous avons oublié que nous avions même de tels problèmes.

Problème deux
4 à 5 jours après le lancement du cluster, nous avons remarqué que les nœuds de données commençaient périodiquement à sortir du cluster et à y entrer après 10 à 20 secondes.

Lorsque nous avons commencé à comprendre, il s'est avéré que cette mémoire hors tas dans Elasticsearch n'est en aucun cas contrôlée. Lorsque nous avons donné plus de mémoire au conteneur, nous avons pu remplir les pools de tampons directs avec diverses informations, et celles-ci n'ont été effacées qu'après le lancement du GC explicite depuis Elasticsearch.

Dans certains cas, cette opération a pris beaucoup de temps et pendant ce temps, le cluster a réussi à marquer ce nœud comme déjà quitté. Ce problème est bien décrit ici.

La solution était la suivante : nous avons limité la capacité de Java à utiliser la majeure partie de la mémoire en dehors du tas pour ces opérations. Nous l'avons limité à 16 Go (-XX:MaxDirectMemorySize=16g), garantissant que le GC explicite soit appelé beaucoup plus souvent et traité beaucoup plus rapidement, ne déstabilisant ainsi plus le cluster.

Troisième problème
Si vous pensez que les problèmes liés aux « nœuds quittant le cluster au moment le plus inattendu » sont terminés, vous vous trompez.

Lorsque nous avons configuré le travail avec les index, nous avons choisi mmapfs pour réduire le temps de recherche sur des fragments frais avec une grande segmentation. C'était une véritable erreur, car lors de l'utilisation de mmapfs, le fichier est mappé dans la RAM, puis nous travaillons avec le fichier mappé. Pour cette raison, il s'avère que lorsque le GC essaie d'arrêter les threads dans l'application, nous allons au point de sécurité pendant très longtemps, et sur le chemin, l'application cesse de répondre aux demandes du maître pour savoir si elle est en vie. . En conséquence, le maître estime que le nœud n'est plus présent dans le cluster. Après cela, après 5 à 10 secondes, le garbage collector fonctionne, le nœud prend vie, entre à nouveau dans le cluster et commence à initialiser les fragments. Tout cela ressemblait beaucoup à « la production que nous méritions » et ne convenait pas à quelque chose de sérieux.

Pour nous débarrasser de ce comportement, nous sommes d'abord passés aux niofs standards, puis, lorsque nous avons migré de la cinquième version d'Elastic vers la sixième, nous avons essayé hybridfs, où ce problème ne s'est pas reproduit. Vous pouvez en savoir plus sur les types de stockage ici.

Problème quatre
Ensuite, il y a eu un autre problème très intéressant que nous avons traité en un temps record. Nous l’avons attrapé pendant 2-3 mois car son schéma était absolument incompréhensible.

Parfois, nos coordinateurs se rendaient au Full GC, généralement après le déjeuner, et n'en revenaient jamais. En même temps, lors de l'enregistrement du retard du GC, cela ressemblait à ceci : tout va bien, bien, bien, et puis du coup tout va très mal.

Au début, nous pensions que nous avions un utilisateur malveillant qui lançait une sorte de requête qui faisait sortir le coordinateur du mode de travail. Nous avons enregistré les demandes pendant très longtemps, essayant de comprendre ce qui se passait.

En conséquence, il s'est avéré qu'au moment où un utilisateur lance une demande énorme et qu'elle parvient à un coordinateur Elasticsearch spécifique, certains nœuds répondent plus longtemps que d'autres.

Et pendant que le coordinateur attend une réponse de tous les nœuds, il accumule les résultats envoyés par les nœuds qui ont déjà répondu. Pour GC, cela signifie que nos modèles d'utilisation du tas changent très rapidement. Et le GC que nous avons utilisé n’a pas pu faire face à cette tâche.

La seule solution que nous avons trouvée pour modifier le comportement du cluster dans cette situation est la migration vers JDK13 et l'utilisation du garbage collector Shenandoah. Cela a résolu le problème, nos coordinateurs ont arrêté de tomber.

C'est là que les problèmes avec Java ont pris fin et que les problèmes de bande passante ont commencé.

« Baies » avec Elasticsearch : débit

Cluster Elasticsearch 200 To+

Des problèmes de débit font que notre cluster fonctionne de manière stable, mais aux pics du nombre de documents indexés et lors des manœuvres, les performances sont insuffisantes.

Premier symptôme rencontré : lors de certaines « explosions » en production, lorsqu'un très grand nombre de logs sont soudainement générés, l'erreur d'indexation es_rejected_execution se met à clignoter fréquemment dans Graylog.

Cela était dû au fait que thread_pool.write.queue sur un nœud de données, jusqu'au moment où Elasticsearch est capable de traiter la demande d'indexation et de télécharger les informations sur la partition sur le disque, n'est capable de mettre en cache que 200 demandes par défaut. Et en Documentation ElasticSearch On parle très peu de ce paramètre. Seuls le nombre maximum de threads et la taille par défaut sont indiqués.

Bien sûr, nous sommes allés modifier cette valeur et avons découvert ce qui suit : plus précisément, dans notre configuration, jusqu'à 300 requêtes sont assez bien mises en cache, et une valeur plus élevée est lourde du fait que nous volons à nouveau vers Full GC.

De plus, comme il s'agit de lots de messages qui arrivent dans une seule requête, il a fallu peaufiner Graylog pour qu'il n'écrive pas souvent et par petits lots, mais par gros lots ou une fois toutes les 3 secondes si le lot n'est toujours pas terminé. Dans ce cas, il s'avère que les informations que nous écrivons dans Elasticsearch deviennent disponibles non pas en deux secondes, mais en cinq (ce qui nous convient assez bien), mais le nombre de retraits qu'il faut effectuer pour parcourir un grand la pile d’informations est réduite.

Ceci est particulièrement important dans les moments où quelque chose s'est écrasé quelque part et en a furieusement signalé, afin de ne pas obtenir un Elastic complètement spammé, et après un certain temps - des nœuds Graylog inutilisables en raison de tampons obstrués.

De plus, lorsque nous avons eu ces mêmes explosions en production, nous avons reçu des plaintes de programmeurs et de testeurs : au moment où ils avaient vraiment besoin de ces logs, ils les recevaient très lentement.

Ils ont commencé à comprendre. D'une part, il était clair que les requêtes de recherche et les requêtes d'indexation étaient traitées essentiellement sur les mêmes machines physiques et qu'il y aurait d'une manière ou d'une autre certains retraits.

Mais cela pourrait être partiellement contourné du fait que dans la sixième version d'Elasticsearch, un algorithme est apparu qui vous permet de distribuer les requêtes entre les nœuds de données pertinents non selon le principe du round-robin aléatoire (le conteneur qui effectue l'indexation et contient le principal- le fragment peut être très occupé, il n'y aura aucun moyen de répondre rapidement), mais de transmettre cette demande à un conteneur moins chargé avec un fragment de réplique, qui répondra beaucoup plus rapidement. En d’autres termes, nous sommes arrivés à use_adaptive_replica_selection : true.

L'image de lecture commence à ressembler à ceci :

Cluster Elasticsearch 200 To+

Le passage à cet algorithme a permis d'améliorer considérablement le temps de requête dans les moments où nous avions un flux important de logs à écrire.

Enfin, le principal problème a été la suppression sans douleur du centre de données.

Ce que nous attendions du cluster immédiatement après avoir perdu la connexion avec un contrôleur de domaine :

  • Si nous avons un maître actuel dans le centre de données défaillant, il sera alors resélectionné et déplacé en tant que rôle vers un autre nœud dans un autre contrôleur de domaine.
  • Le maître supprimera rapidement tous les nœuds inaccessibles du cluster.
  • A partir des restants, il comprendra : dans le data center perdu nous avions tels ou tels fragments primaires, il promouvra rapidement des fragments de répliques complémentaires dans les data center restants, et nous continuerons à indexer les données.
  • En conséquence, le débit d'écriture et de lecture du cluster se dégradera progressivement, mais en général, tout fonctionnera, bien que lentement, mais de manière stable.

Il s'est avéré que nous voulions quelque chose comme ceci :

Cluster Elasticsearch 200 To+

Et nous avons obtenu ce qui suit :

Cluster Elasticsearch 200 To+

Comment est-ce arrivé?

Lorsque le centre de données est tombé, notre maître est devenu le goulot d'étranglement.

Pourquoi?

Le fait est que le maître dispose d'un TaskBatcher, chargé de distribuer certaines tâches et événements dans le cluster. Toute sortie de nœud, toute promotion d'un fragment de réplique à principal, toute tâche pour créer un fragment quelque part - tout cela va d'abord à TaskBatcher, où il est traité séquentiellement et dans un seul thread.

Au moment du retrait d'un centre de données, il s'est avéré que tous les nœuds de données des centres de données survivants considéraient qu'il était de leur devoir d'informer le maître "nous avons perdu tels ou tels fragments et tels ou tels nœuds de données".

Dans le même temps, les nœuds de données survivants ont envoyé toutes ces informations au maître actuel et ont essayé d'attendre la confirmation qu'il les avait acceptées. Ils n'ont pas attendu cela, car le maître recevait les tâches plus rapidement qu'il ne pouvait y répondre. Les nœuds ont expiré les demandes répétitives, et le maître à ce moment-là n'a même pas essayé d'y répondre, mais a été complètement absorbé par la tâche de trier les demandes par priorité.

Sous forme de terminal, il s'est avéré que les nœuds de données ont spammé le maître au point qu'il est passé en GC complet. Après cela, notre rôle de maître est passé à un nœud suivant, absolument la même chose lui est arrivée et, par conséquent, le cluster s'est complètement effondré.

Nous avons pris des mesures, et avant la version 6.4.0, où cela était corrigé, il nous suffisait de sortir simultanément seulement 10 nœuds de données sur 360 pour arrêter complètement le cluster.

Cela ressemblait à ceci :

Cluster Elasticsearch 200 To+

Après la version 6.4.0, où ce terrible bug a été corrigé, les nœuds de données ont cessé de tuer le maître. Mais cela ne le rend pas « plus intelligent ». À savoir : lorsque nous produisons 2, 3 ou 10 (n'importe quel nombre autre qu'un) nœuds de données, le maître reçoit un premier message indiquant que le nœud A est parti et essaie d'en informer le nœud B, le nœud C, le nœud D.

Et pour le moment, cela ne peut être résolu qu'en définissant un délai d'attente pour les tentatives d'informer quelqu'un de quelque chose, égal à environ 20 à 30 secondes, et ainsi contrôler la vitesse de sortie du centre de données du cluster.

En principe, cela correspond aux exigences initialement présentées pour le produit final dans le cadre du projet, mais du point de vue de la « science pure », il s'agit d'un bug. Ce qui, d'ailleurs, a été corrigé avec succès par les développeurs dans la version 7.2.

De plus, lorsqu'un certain nœud de données s'éteignait, il s'est avéré que diffuser des informations sur sa sortie était plus important que de dire à l'ensemble du cluster qu'il y avait tel ou tel fragment primaire dessus (afin de promouvoir un fragment de réplique dans un autre data node). centre dans le primaire, et dans des informations pourraient être écrites dessus).

Par conséquent, lorsque tout s'est déjà calmé, les nœuds de données libérés ne sont pas immédiatement marqués comme obsolètes. En conséquence, nous sommes obligés d'attendre que tous les pings aient expiré vers les nœuds de données libérés, et seulement après cela, notre cluster commence à nous dire que là, là et là, nous devons continuer à enregistrer les informations. Vous pouvez en savoir plus à ce sujet ici.

De ce fait, l’opération de retrait d’un data center nous prend aujourd’hui environ 5 minutes aux heures de pointe. Pour un colosse aussi grand et maladroit, c'est un plutôt bon résultat.

En conséquence, nous sommes arrivés à la décision suivante :

  • Nous disposons de 360 ​​​​nœuds de données avec des disques de 700 Go.
  • 60 coordinateurs pour acheminer le trafic via ces mêmes nœuds de données.
  • 40 masters que nous avons laissés comme une sorte d'héritage depuis les versions antérieures à 6.4.0 - pour survivre au retrait du data center, nous étions mentalement préparés à perdre plusieurs machines afin d'avoir la garantie d'avoir un quorum de masters même en le pire des cas
  • Toute tentative de combiner des rôles sur un conteneur se heurtait au fait que tôt ou tard, le nœud se briserait sous la charge.
  • L'ensemble du cluster utilise une taille de tas de 31 gigaoctets : toutes les tentatives visant à réduire la taille ont abouti soit à la suppression de certains nœuds lors de requêtes de recherche lourdes avec le caractère générique principal, soit à l'obtention du disjoncteur dans Elasticsearch lui-même.
  • De plus, pour garantir les performances de recherche, nous avons essayé de maintenir le nombre d'objets dans le cluster aussi petit que possible, afin de traiter le moins d'événements possible dans le goulot d'étranglement que nous avons eu dans le maître.

Enfin sur la surveillance

Pour garantir que tout cela fonctionne comme prévu, nous surveillons les éléments suivants :

  • Chaque nœud de données signale à notre cloud qu'il existe et qu'il contient tels ou tels fragments. Lorsque nous éteignons quelque chose quelque part, le cluster signale après 2-3 secondes que dans le centre A, nous avons éteint les nœuds 2, 3 et 4 - cela signifie que dans d'autres centres de données, nous ne pouvons en aucun cas éteindre les nœuds sur lesquels il n'y a qu'un seul fragment. gauche.
  • Connaissant la nature du comportement du maître, nous examinons très attentivement le nombre de tâches en attente. Parce que même une tâche bloquée, si elle n'expire pas à temps, peut théoriquement, dans certaines situations d'urgence, devenir la raison pour laquelle, par exemple, la promotion d'un fragment de réplique dans le primaire ne fonctionne pas, c'est pourquoi l'indexation cessera de fonctionner.
  • Nous examinons également de très près les retards du garbage collector, car nous avons déjà rencontré de grandes difficultés avec cela lors de l'optimisation.
  • Rejets par fil de discussion pour comprendre à l'avance où se situe le goulot d'étranglement.
  • Eh bien, des métriques standard telles que le tas, la RAM et les E/S.

Lors de la création d'une surveillance, vous devez prendre en compte les fonctionnalités du pool de threads dans Elasticsearch. Documentation d'ElasticSearch décrit les options de configuration et les valeurs par défaut pour la recherche et l'indexation, mais est complètement silencieux sur thread_pool.management. Ces threads traitent notamment des requêtes telles que _cat/shards et d'autres similaires, qui sont pratiques à utiliser lors de l'écriture de la surveillance. Plus le cluster est grand, plus de telles requêtes sont exécutées par unité de temps, et le thread_pool.management susmentionné non seulement n'est pas présenté dans la documentation officielle, mais est également limité par défaut à 5 threads, ce qui est très rapidement éliminé, après quelle surveillance cesse de fonctionner correctement.

Ce que je veux dire en conclusion : nous l'avons fait ! Nous avons pu offrir à nos programmeurs et développeurs un outil qui, dans presque toutes les situations, peut fournir des informations de manière rapide et fiable sur ce qui se passe en production.

Oui, cela s'est avéré assez compliqué, mais nous avons néanmoins réussi à intégrer nos souhaits dans des produits existants, que nous n'avons pas eu à corriger et à réécrire nous-mêmes.

Cluster Elasticsearch 200 To+

Source: habr.com

Ajouter un commentaire