
Bonjour Ă tous, je m'appelle Alexander, je travaille au CIAN en tant qu'ingĂ©nieur et je suis impliquĂ© dans l'administration systĂšme et l'automatisation des processus d'infrastructure. Dans les commentaires de l'un des articles prĂ©cĂ©dents, on nous a demandĂ© d'indiquer d'oĂč nous obtenons 4 To de journaux par jour et ce que nous en faisons. Oui, nous avons beaucoup de journaux et un cluster d'infrastructure distinct a Ă©tĂ© créé pour les traiter, ce qui nous permet de rĂ©soudre rapidement les problĂšmes. Dans cet article, je parlerai de la façon dont nous l'avons adaptĂ© au cours d'une annĂ©e pour travailler avec un flux de donnĂ©es toujours croissant.
Par oĂč avons-nous commencĂ© ?

Au cours des derniÚres années, la charge sur cian.ru a augmenté trÚs rapidement et au troisiÚme trimestre 2018, le trafic des ressources a atteint 11.2 millions d'utilisateurs uniques par mois. à cette époque, aux moments critiques, nous perdions jusqu'à 40 % des journaux, c'est pourquoi nous ne pouvions pas traiter rapidement les incidents et consacrions beaucoup de temps et d'efforts à les résoudre. Souvent, nous ne parvenions pas non plus à trouver la cause du problÚme, qui réapparaissait aprÚs un certain temps. C'était l'enfer et il fallait faire quelque chose.
Ă cette Ă©poque, nous utilisions un cluster de 10 nĆuds de donnĂ©es avec ElasticSearch version 5.5.2 avec des paramĂštres d'index standard pour stocker les journaux. Il a Ă©tĂ© introduit il y a plus d'un an comme une solution populaire et abordable : alors le flux de journaux n'Ă©tait pas si important, il ne servait Ă rien de proposer des configurations non standard.
Le traitement des journaux entrants Ă©tait assurĂ© par Logstash sur diffĂ©rents ports de cinq coordinateurs ElasticSearch. Un index, quelle que soit sa taille, Ă©tait composĂ© de cinq fragments. Une rotation horaire et quotidienne a Ă©tĂ© organisĂ©e, de sorte qu'environ 100 nouveaux fragments sont apparus dans le cluster chaque heure. MĂȘme sâil nây avait pas beaucoup de journaux, le cluster sâen sortait bien et personne ne prĂȘtait attention Ă ses paramĂštres.
Les dĂ©fis dâune croissance rapide
Le volume de journaux gĂ©nĂ©rĂ©s a augmentĂ© trĂšs rapidement, car deux processus se chevauchaient. Dâune part, le nombre dâutilisateurs du service a augmentĂ©. Dâun autre cĂŽtĂ©, nous avons commencĂ© Ă passer activement Ă une architecture de microservices, en sciant nos anciens monolithes en C# et Python. Plusieurs dizaines de nouveaux microservices qui ont remplacĂ© certaines parties du monolithe ont gĂ©nĂ©rĂ© beaucoup plus de journaux pour le cluster d'infrastructure.
Câest la mise Ă lâĂ©chelle qui nous a conduit au point oĂč le cluster est devenu pratiquement ingĂ©rable. Lorsque les journaux ont commencĂ© Ă arriver Ă un rythme de 20 6 messages par seconde, une rotation inutile et frĂ©quente a augmentĂ© le nombre de fragments Ă 600 XNUMX, et il y avait plus de XNUMX fragments par nĆud.
Cela a entraĂźnĂ© des problĂšmes d'allocation de RAM, et lorsqu'un nĆud tombait en panne, tous les fragments migraient simultanĂ©ment, augmentant le trafic et surchargeant les nĆuds restants, rendant pratiquement impossible l'Ă©criture de donnĂ©es sur le cluster. Pendant cette pĂ©riode, nous nous sommes retrouvĂ©s sans journaux. Et s'il y avait un problĂšme avec serveur Nous perdions 1/10 du cluster au total. Le grand nombre de petits index contribuait Ă la complexitĂ©.
Sans journaux, nous ne comprenions pas les raisons de l'incident et pourrions tĂŽt ou tard marcher Ă nouveau sur le mĂȘme rĂąteau, et dans l'idĂ©ologie de notre Ă©quipe, cela Ă©tait inacceptable, car tous nos mĂ©canismes de travail sont conçus pour faire exactement le contraire - ne jamais rĂ©pĂ©ter les mĂȘmes problĂšmes. Pour ce faire, nous avions besoin du volume total de journaux et de leur livraison presque en temps rĂ©el, puisqu'une Ă©quipe d'ingĂ©nieurs en service surveillait les alertes non seulement Ă partir des mĂ©triques, mais Ă©galement des journaux. Pour comprendre l'ampleur du problĂšme, Ă cette Ă©poque, le volume total de journaux Ă©tait d'environ 2 To par jour.
Nous nous sommes fixés pour objectif d'éliminer complÚtement la perte de logs et de réduire le délai de leur livraison au cluster ELK à un maximum de 15 minutes en cas de force majeure (nous nous sommes ensuite appuyés sur ce chiffre comme KPI interne).
Nouveau mĂ©canisme de rotation et nĆuds chauds

Nous avons commencé la conversion du cluster en mettant à jour la version d'ElasticSearch de 5.5.2 à 6.4.3. Une fois de plus, notre cluster version 5 est mort et nous avons décidé de le désactiver et de le mettre à jour complÚtement - il n'y a toujours pas de journaux. Nous avons donc effectué cette transition en quelques heures seulement.
La transformation la plus importante Ă ce stade a Ă©tĂ© la mise en Ćuvre d'Apache Kafka sur trois nĆuds avec un coordinateur comme tampon intermĂ©diaire. Le courtier de messages nous a Ă©vitĂ© de perdre des journaux lors de problĂšmes avec ElasticSearch. Dans le mĂȘme temps, nous avons ajoutĂ© 2 nĆuds au cluster et basculĂ© vers une architecture hot-warm avec trois nĆuds « chauds » situĂ©s dans diffĂ©rents racks du centre de donnĂ©es. Nous leur avons redirigĂ© les journaux Ă l'aide d'un masque qui ne doit en aucun cas ĂȘtre perdu - nginx, ainsi que les journaux d'erreurs des applications. Des journaux mineurs ont Ă©tĂ© envoyĂ©s aux nĆuds restants - dĂ©bogage, avertissement, etc., et aprĂšs 24 heures, les journaux « importants » des nĆuds « chauds » ont Ă©tĂ© transfĂ©rĂ©s.
Afin de ne pas augmenter le nombre de petits index, nous sommes passés de la rotation temporelle au mécanisme de rollover. Il y avait beaucoup d'informations sur les forums selon lesquelles la rotation par taille d'index est trÚs peu fiable, nous avons donc décidé d'utiliser la rotation par nombre de documents dans l'index. Nous avons analysé chaque index et enregistré le nombre de documents aprÚs lequel la rotation devrait fonctionner. Ainsi, nous avons atteint la taille de partition optimale - pas plus de 50 Go.
Optimisation des clusters

Cependant, nous nâavons pas complĂštement Ă©liminĂ© les problĂšmes. Malheureusement, de petits index sont toujours apparus : ils n'ont pas atteint le volume spĂ©cifiĂ©, n'ont pas subi de rotation et ont Ă©tĂ© supprimĂ©s par un nettoyage global des index de plus de trois jours, puisque nous avons supprimĂ© la rotation par date. Cela a entraĂźnĂ© une perte de donnĂ©es en raison du fait que l'index du cluster a complĂštement disparu et qu'une tentative d'Ă©criture dans un index inexistant a brisĂ© la logique du conservateur que nous utilisions pour la gestion. L'alias d'Ă©criture a Ă©tĂ© converti en index et a brisĂ© la logique de roulement, provoquant une croissance incontrĂŽlĂ©e de certains index jusqu'Ă 600 Go.
Par exemple, pour la configuration de rotation :
Ńurator-elk-rollover.yaml
---
actions:
1:
action: rollover
options:
name: "nginx_write"
conditions:
max_docs: 100000000
2:
action: rollover
options:
name: "python_error_write"
conditions:
max_docs: 10000000
S'il n'y avait pas d'alias de survol, une erreur se produisait :
ERROR alias "nginx_write" not found.
ERROR Failed to complete action: rollover. <type 'exceptions.ValueError'>: Unable to perform index rollover with alias "nginx_write".
Nous avons laissé la solution à ce problÚme pour l'itération suivante et avons abordé un autre problÚme : nous sommes passés à la logique pull de Logstash, qui traite les journaux entrants (suppression des informations inutiles et enrichissement). Nous l'avons placé dans Docker, que nous lançons via docker-compose, et nous y avons également placé logstash-exporter, qui envoie des métriques à Prometheus pour la surveillance opérationnelle du flux de journaux. De cette façon, nous nous sommes donné la possibilité de modifier en douceur le nombre d'instances logstash responsables du traitement de chaque type de journal.
Pendant que nous amĂ©liorions le cluster, le trafic de cian.ru a augmentĂ© pour atteindre 12,8 millions d'utilisateurs uniques par mois. En consĂ©quence, il s'est avĂ©rĂ© que nos transformations Ă©taient un peu en retard par rapport aux changements de production, et nous avons Ă©tĂ© confrontĂ©s au fait que les nĆuds « chauds » ne pouvaient pas supporter la charge et ralentissaient toute la livraison des grumes. Nous avons reçu des donnĂ©es « chaudes » sans Ă©chec, mais nous avons dĂ» intervenir dans la livraison du reste et effectuer un rollover manuel afin de rĂ©partir uniformĂ©ment les index.
Dans le mĂȘme temps, la mise Ă l'Ă©chelle et la modification des paramĂštres des instances logstash dans le cluster Ă©taient compliquĂ©es par le fait qu'il s'agissait d'un docker-compose local et que toutes les actions Ă©taient effectuĂ©es manuellement (pour ajouter de nouvelles fins, il Ă©tait nĂ©cessaire de parcourir manuellement toutes les serveurs et faites docker-compose up -d partout).
Redistribution des journaux
En septembre de cette année, nous étions encore en train de découper le monolithe, la charge sur le cluster augmentait et le flux de journaux approchait les 30 XNUMX messages par seconde.

Nous avons commencĂ© la prochaine itĂ©ration avec une mise Ă jour matĂ©rielle. Nous sommes passĂ©s de cinq coordinateurs Ă trois, avons remplacĂ© les nĆuds de donnĂ©es et avons gagnĂ© en termes d'argent et d'espace de stockage. Pour les nĆuds, nous utilisons deux configurations :
- Pour les nĆuds « chauds » : E3-1270 v6 / 960 Go SSD / 32 Go x 3 x 2 (3 pour Hot1 et 3 pour Hot2).
- Pour les nĆuds « chauds » : E3-1230 v6 / 4 To SSD / 32 Go x 4.
Lors de cette itĂ©ration, nous avons dĂ©placĂ© l'index avec les journaux d'accĂšs aux microservices, qui occupe le mĂȘme espace que les journaux nginx de premiĂšre ligne, vers le deuxiĂšme groupe de trois nĆuds « chauds ». Nous stockons dĂ©sormais les donnĂ©es sur des nĆuds « chauds » pendant 20 heures, puis les transfĂ©rons vers des nĆuds « chauds » vers le reste des journaux.
Nous avons rĂ©solu le problĂšme de la disparition des petits index en reconfigurant leur rotation. DĂ©sormais, les index changent toutes les 23 heures, mĂȘme s'il y a peu de donnĂ©es. Cela a lĂ©gĂšrement augmentĂ© le nombre de fragments (il y en avait environ 800), mais du point de vue des performances du cluster, c'est tolĂ©rable.
En consĂ©quence, il y avait six nĆuds « chauds » et seulement quatre nĆuds « chauds » dans le cluster. Cela entraĂźne un lĂ©ger retard dans les requĂȘtes sur de longs intervalles de temps, mais l'augmentation du nombre de nĆuds Ă l'avenir rĂ©soudra ce problĂšme.
Cette itération a également résolu le problÚme du manque de mise à l'échelle semi-automatique. Pour ce faire, nous avons déployé un cluster d'infrastructure Nomad - similaire à ce que nous avons déjà déployé en production. Pour l'instant, la quantité de Logstash ne change pas automatiquement en fonction de la charge, mais nous y reviendrons.

Plans pour l'avenir
La configuration mise en Ćuvre est parfaitement Ă©volutive et nous stockons dĂ©sormais 13,3 To de donnĂ©es - tous les journaux pendant 4 jours, ce qui est nĂ©cessaire pour l'analyse d'urgence des alertes. Nous convertissons certains journaux en mĂ©triques, que nous ajoutons Ă Graphite. Pour faciliter le travail des ingĂ©nieurs, nous disposons de mĂ©triques pour le cluster d'infrastructure et de scripts pour la rĂ©paration semi-automatique des problĂšmes courants. AprĂšs avoir augmentĂ© le nombre de nĆuds de donnĂ©es, prĂ©vu pour l'annĂ©e prochaine, nous passerons au stockage des donnĂ©es de 4 Ă 7 jours. Cela suffira pour le travail opĂ©rationnel, car nous essayons toujours d'enquĂȘter sur les incidents le plus rapidement possible, et pour les enquĂȘtes Ă long terme, nous disposons de donnĂ©es tĂ©lĂ©mĂ©triques.
En octobre 2019, le trafic vers cian.ru atteignait déjà 15,3 millions d'utilisateurs uniques par mois. Cela est devenu un test sérieux de la solution architecturale pour la livraison des journaux.
Nous nous préparons maintenant à mettre à jour ElasticSearch vers la version 7. Cependant, pour cela, nous devrons mettre à jour le mappage de nombreux index dans ElasticSearch, car ils sont passés de la version 5.5 et ont été déclarés obsolÚtes dans la version 6 (ils n'existent tout simplement pas dans la version 7). Cela signifie que pendant le processus de mise à jour, il y aura certainement une sorte de force majeure, qui nous laissera sans journaux jusqu'à ce que le problÚme soit résolu. De la version 7, nous attendons avec impatience Kibana avec une interface améliorée et de nouveaux filtres.
Nous avons atteint notre objectif principal : nous avons arrĂȘtĂ© de perdre des journaux et rĂ©duit les temps d'arrĂȘt du cluster d'infrastructure de 2 Ă 3 pannes par semaine Ă quelques heures de travail de maintenance par mois. Tout ce travail de production est presque invisible. Cependant, maintenant que nous pouvons dĂ©terminer exactement ce qui se passe avec notre service, nous pouvons le faire rapidement en mode silencieux et ne pas craindre que les journaux soient perdus. En gĂ©nĂ©ral, nous sommes satisfaits, heureux et nous prĂ©parons Ă de nouveaux exploits, dont nous parlerons plus tard.
Source: habr.com
