Mise à l'échelle de Logstash (avec redis / elasticsearch)

16

Sur un cluster de plus de 12 serveurs centos 5.8, j'ai déployé logstash à l'aide de l'expéditeur natif de logstash, qui renvoie /var/log/*/*.logà un serveur central de logstash.

Nous avons essayé d'utiliser rsyslogd comme expéditeur, mais en raison d'un bogue dans le module ImFile de rsyslogd, si l'extrémité distante ne répondait pas, les journaux s'empilaient en mémoire.

Nous utilisons actuellement Redis comme mécanisme de transport, donc logstash01 a redis s'exécutant localement, lié à l'IP du VLAN pour ces journaux.

Donc, logstash-shipper envoie à redis sur logstash01. logstash01 envoie à Elasticsearch s'exécutant dans un processus distinct.

Voici ce que nous voyons. Elasticsearch a 141 threads bloqués. Stracing le parent elasticsearch montre:

futex(0x7f4ccd1939d0, FUTEX_WAIT, 26374, NULL

Voici le jstack d'Elasticsearch

Voici le jstack de logstash

Alors .. Hier soir, certains des serveurs Web (dont les journaux sont suivis par logstash) sont devenus fous, avec des charges moyennes supérieures à 500.

Sur logstash01, il y a ceci

Dec 19 00:44:45 logstash01 kernel: [736965.925863] Killed process 23429 (redis-server) total-vm:5493112kB, anon-rss:4248840kB, file-rss:108kB

Donc , OOM-killer tué Redis-serveur qui se connecte ensuite destinés entassées dans la mémoire sur les serveurs qui étaient des choses .. Quels expédiaient en quelque sorte signifie que apache obtient ses petites culottes dans une torsion. (Franchement, je ne sais pas comment, je suppose simplement que c'est la queue du journal) ..

Voici ma théorie de la façon dont les événements se sont déroulés:

  1. Nous avons eu un pic de trafic.
  2. Une immense quantité de journaux a été générée.
  3. Celles-ci se sont empilées à Redis, car logstash / elasticsearch ne semble pouvoir gérer que 300 à 400 nouveaux événements / seconde.
  4. Redis s'était complètement rempli au point où le tueur OOM l'a massacré sans raison.
  5. Redis cesse d'accepter de nouveaux éléments.
  6. Les objets commencent maintenant à s'accumuler du côté des hôtes distants.
  7. Tout devient fou . Apache cesse d'accepter les demandes. (Pourquoi?).

Les questions sont les suivantes:

  1. Pourquoi Apache devient fou s'il y a juste quelque chose qui suit son journal. Est-ce que le truc qui l'empêche d'empêcher Apache d'écrire?

  2. Existe-t-il un moyen sensé de rendre elasticsearch plus rapide / meilleur / résistant?

  3. Existe-t-il un moyen sain de rendre les redis résilients et de ne pas mourir à cause du fait d'être OOM

  4. Y a-t-il un défaut fondamental dans la façon dont j'ai tout réglé, ou est-ce que tout le monde a ce problème?

-- ÉDITER --

Quelques spécifications pour @lusis.

admin@log01:/etc/init$ free -m
             total       used       free     shared    buffers     cached
Mem:          7986       6041       1944          0        743       1157
-/+ buffers/cache:       4140       3845
Swap:         3813       3628        185

Filesystem             Size  Used Avail Use% Mounted on
/dev/sda2               19G  5.3G   13G  31% /
udev                   3.9G  4.0K  3.9G   1% /dev
tmpfs                  1.6G  240K  1.6G   1% /run
none                   5.0M     0  5.0M   0% /run/lock
none                   3.9G     0  3.9G   0% /run/shm
/dev/sda1               90M   72M   14M  85% /boot
/dev/mapper/data-disk  471G  1.2G  469G   1% /data

/dev/sda2 on / type ext3 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/dev/sda1 on /boot type ext2 (rw)
/dev/mapper/data-disk on /data type ext3 (rw)
/data/elasticsearch on /var/lib/elasticsearch type none (rw,bind)

log01:/etc/init$ top 
top - 14:12:20 up 18 days, 21:59,  2 users,  load average: 0.20, 0.35, 0.40
Tasks: 103 total,   1 running, 102 sleeping,   0 stopped,   0 zombie
Cpu0  :  3.0%us,  1.0%sy,  0.0%ni, 95.7%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu1  : 12.0%us,  1.0%sy,  0.0%ni, 86.6%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu2  :  4.7%us,  0.3%sy,  0.0%ni, 94.9%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu3  :  5.6%us,  1.3%sy,  0.0%ni, 93.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu4  :  5.3%us,  1.3%sy,  0.0%ni, 93.3%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu5  :  6.4%us,  1.0%sy,  0.0%ni, 92.3%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Mem:   8178120k total,  6159036k used,  2019084k free,   761780k buffers
Tom O'Connor
la source
1
j'ai eu des problèmes avec ES et ces configurations super cool. J'écris maintenant mon propre récepteur syslog simple en python. La seule façon de traiter était de commencer à l'avance et de continuer à ajouter des nœuds ES, en augmentant la taille de logstash ... cauchemar. Je crois qu'apache bloque l'écriture du fichier journal, ce qui pourrait être un problème s'il ne pouvait pas écrire dans le fichier journal.
Abhishek Dujari
Re: le problème rsyslog, Bitbucket a également eu une panne en raison de problèmes rsyslog. Ils ont blogué à ce sujet et comment ils y ont travaillé.
James O'Gorman

Réponses:

22

Votre message ne décrit pas grand-chose en termes de spécifications (mémoire sur l'indexeur LS, volume de journal ou bien d'autre) mais je vais essayer de répondre à vos questions du mieux que je peux d'abord. Avertissement: je suis l'un des développeurs de logstash -

  1. Apache devenir fou était probablement un effet secondaire du processus logstash. Je mettrais cela de côté pour l'instant.

  2. La manière saine de faire ES f / b / s est d'ajouter plus de nœuds ES. C'est vraiment aussi simple que ça. Ils se découvrent même mutuellement en fonction de la topologie du réseau. Après 17 ans dans cette industrie, je n'ai jamais rien vu d'échelle horizontalement aussi simple qu'ElasticSearch.

  3. Pour f / b / s Redis, n'utilisez aucun cluster redis. Les versions plus récentes de Logstash peuvent effectuer l'équilibrage de charge Redis en interne. La sortie Redis prend en charge une liste d'hôtes Redis dans la configuration du plugin et la prise en charge est également sur le point d'être ajoutée pour correspondre à cela. Dans l'intervalle, vous pouvez utiliser plusieurs définitions d'entrée Redis du côté indexeur / consommateur.

  4. Je ne peux pas répondre à cela au-delà de dire qu'il semble que vous essayez de faire trop avec un seul hôte (peut-être sous-alimenté).

Tout bon processus de mise à l'échelle commence par la rupture des composants colocalisés en systèmes distincts. Je ne vois pas vos configurations n'importe où, mais les endroits où les «goulots d'étranglement» sont dans les filtres. Selon le nombre de transformations que vous effectuez, cela peut avoir un impact sur l'utilisation de la mémoire des processus Logstash.

Logstash fonctionne un peu comme les legos. Vous pouvez soit utiliser une brique 2x4, soit utiliser deux briques 2x2 pour accomplir la même tâche. Sauf dans le cas de logstash, il est en fait plus robuste d'utiliser des briques plus petites qu'une seule grosse brique.

Quelques conseils généraux que nous donnons normalement sont:

  • expédiez les journaux le plus rapidement possible à partir du bord Si vous pouvez utiliser le transport réseau pur au lieu d'écrire sur le disque, c'est bien mais pas obligatoire. Logstash est basé sur JVM et a de bonnes et de mauvaises implications. Utilisez un autre expéditeur. J'en ai écrit un basé sur python ( https://github.com/lusis/logstash-shipper ) mais je suggérerais que les gens utilisent Beaver à la place ( https://github.com/josegonzalez/beaver ).

  • générer vos journaux dans un format qui nécessite le moins de filtrage possible (format json ou de manière optimale json-event) Ce n'est pas toujours possible. J'ai écrit un appender log4j pour ce faire ( https://github.com/lusis/zmq-appender ) et j'ai finalement éclaté la disposition du modèle dans son propre référentiel ( https://github.com/lusis/log4j-jsonevent-layout ). Cela signifie que je n'ai à effectuer AUCUN filtrage dans logstash pour ces journaux. Je viens de définir le type d'entrée sur 'json-event'

Pour apache, vous pouvez essayer cette approche: http://cookbook.logstash.net/recipes/apache-json-logs/

  • casser les choses en plusieurs composants Dans chaque discussion que j'ai faite sur logstash, je le décris comme un tuyau unix sur les stéroïdes. Vous pouvez rendre le pipeline aussi long ou aussi court que vous le souhaitez. Vous modifiez le journal de bord en déplaçant les responsabilités horizontalement. Cela pourrait signifier allonger le pipeline, mais nous ne parlons de rien de statistiquement pertinent en termes de surcharge de latence. Si vous avez un meilleur contrôle sur votre réseau (c.-à-d. PAS sur EC2), vous pouvez faire des choses incroyables avec une isolation de trafic standard.

Notez également que la liste de diffusion logstash est TRÈS active, vous devez donc toujours commencer par là. Désinfectez et essuyez vos configurations car c'est le meilleur endroit pour commencer.

Il existe des entreprises (comme Sonian) qui adaptent ElasticSearch à des niveaux de pétaoctets et des entreprises (comme Mailchimp et Dreamhost) qui adaptent également Logstash à des niveaux insensés. Ça peut être fait.

lusis
la source
J'ai collé des informations système dans le Q
Tom O'Connor
Je dirais que la 8G est sous-alimentée en fonction du volume de journaux et de la durée de conservation. Je commencerais par déplacer Redis et Logstash vers un autre serveur. Exécutez-vous ES en cours avec Logstash ou en tant que service distinct?
lusis
1
C'est un service distinct. J'ai fait un geste audacieux avant Noël et j'ai désactivé le comportement de redis persist au disque, et le tout est devenu plus stable.
Tom O'Connor
Le lien apache-json-logs est rompu. Y a-t-il un remplaçant?
Kate Ebneter