Delete_by_query vs index journalier

Bonjour à tous,
Je rencontre des soucis sur mon serveur ELK, et j'ai éventuellement plusieurs pistes pour y remédier mais aucune n'aboutit car j'ai toujours des contraintes que je ne peux pas gérer.

En fait, tout part du fait que mon index principale, celui sur lequel je travaille la plupart du temps, à visiblement atteint le nombre maximum de shard / documents :
number of documents in the index cannot exceed 2147483519

Cet index comporte moins d'un mois de log, période à laquelle j'avais prévu de configurer ma rotation.
Avec le recul, je me suis dit que dans cette optique de faire une rotation par mois, je me retrouvais avec pas ( ou peu ) de log en début de chaque rotation, ce qui n'est pas pratique dans mon utilisation car mes requêtes sont souvent basés sur des périodes plus ou moins longues.

Je me suis donc demandé si il n'était pas possible de simplement supprimer les documents de mon index qui sont plus vieux que day-21 par exemple et je me suis donc renseigné sur la commande _delete_by_query mais je ne comprends pas bien la syntaxe malgré mes recherches.
Dans la dev tool, j'ai quelque chose du genre :

POST index-name/_delete_by_query
{
  "query": { 
    "range": {
      "time": {
        "lte": "day-21"
      }
    }
  }
}

Mais ça ne semble pas matcher :
{
"took" : 66,
"timed_out" : false,
"total" : 0,
"deleted" : 0,
"batches" : 0,
"version_conflicts" : 0,
"noops" : 0,
"retries" : {
"bulk" : 0,
"search" : 0
},
"throttled_millis" : 0,
"requests_per_second" : -1.0,
"throttled_until_millis" : 0,
"failures" :
}

Le nom de mon index est correct, et il comporte bien des documents qui datent de plus de 21 jours ( pour précisions, on parle bien d'index basé sur @timestamp ). Qu'est ce que je loupe dans cette commande ?
J'ai essayé avec le range time, day, timestamp ...

Quand bien même, à terme je verrais bien une commande curl qui pourrait s’exécuter tout les jours via une crontab pour conserver uniquement 21 jours de logs dans mon index, mais pour que cette requête soit interprétable par le shell, je ne vois pas trop la syntaxe à renseigner.
Des idées ?

Autre point, lors de mes recherches je suis tombé sur plusieurs posts indiquant qu'il était grandement préférable de favoriser des daily index, ce qui simplifie grandement la gestion de la rotation dans ce cas. Je suis bien d'accord avec ce point, mais autre chose me dérange dans ce mode de fonctionnement. Les recherches kibana sont bien basés sur un seul et unique index nous sommes d'accord ? Il était noté sur ce post que j'ai lu que non, mais j'ai du mal à y croire.
Dans le cas contraire, si c'est gérable de faire des recherches sur plusieurs index simultanément, je veux bien savoir comment ça me faciliterai grandement la vie :slight_smile:

Désolé pour le pavé, et merci d'avance pour vos réponses.

Bonjour,

j'essaye avec une réponse succincte, :grinning:
Oui il est grandement préferable de laisser elastic gérer la rotation de tes donnees, faire un index journalier a l'air plus adapte pour ton besoin. Le fait d'utiliser delete by query peut rendre ton cluster lent (en gros lucene ne supprimer pas les documents mais les marquent comme supprimés et de temps en temps fait le ménage, ce qui coute en terme de CPU de plus a chaque requête il doit filtrer les documents supprimes. Y'a plein de ressources a ce propos, donc je ne m'étends pas).

Un exemple vaux mieux qu'un gros discours, avec un index journalier "mon_index_2019-11-15"
"mon_index_2019-11-14" etc...
Tu peux requeter sur n jours en faisant une requete dans dev tools

POST mon_index_2019-11-*/_search
{
"query": {"range": "@timestamp", "gte": day-21}
}

oui et non si les donnees se chevauchent sur 2 mois:

POST mon_index_2019-10-* ,mon_index_2019-11-*/_search
{
"query": {"range": "@timestamp", "gte": day-21}
}

EDIT: enlever l'espace avant la virgule dans "2019-10-* ,mon_index" l'editeur du forum supprime tous les * s'il n'y a pas d'espace.

Oui mais sur deux mois, deux années...

POST mon_index_*/_search
{
"query": {"range": "@timestamp", "gte": day-21}
}

ou si tu gère avec un alias explications en dessous:

POST mon_index_avec_mes_donnees/_search
{
"query": {"range": "@timestamp", "gte": day-21}
}

Autre ressources que tu peux lire pour gérer tes index c'est ILM mais c'est a partir de la version 6.6

Pour les versions précédente il y'a curator.

Tu peux aussi regarder du cote de rollover index si ton index est trop gros et si tu dois le scinder en deux ou trois, si ton index atteint la taille limite le même jour. Tu peux avoir les index suivant:
"mon_index_2019-11-15_1"
"mon_index_2019-11-15_2"
"mon_index_2019-11-15_3"
avec un alias "mon_index_2019-11-15" du coup tu peux requêter sur mon_index_2019-11-15 de facon transparente, si un jour t'as un seul index mon_index_2019-11-16_1 avec l'alias mon_index_2019-11-16 ta requête ne changera pas ca te permet de ne pas avoir a te soucier de combien d'index tu peux avoir derrière l'alias. Tu peux appliquer la règle a une rotation journalière semestriel etc...

Bonjour @gabriel_tessier
Tout d'abord merci d'avoir pris le temps pour tes différentes explications qui sont très clair ( et c'est pas évident quand on parle d'ELK :slight_smile: )
Je ne savais pas que _delete_by_query marquait pour suppression, dans ce cas effectivement pas vraiment d'intêret car même en paramétrant ça dans une crontab en HNO, je risque de rendre indispo mon serveur sera surchargé en ressources quand j'en ai besoin ( à moins qu'on ai le contrôle sur les heures de garbage collection ? )

L'idée de requêter via la dev tool n'est pas pratique pour moi, car les syntaxes sont plutôt complexe et d'autant plus que des personnes non initiés à ce langage utilisent également Kibana.
Par contre, tes requêtes m'ont donné une idée.

En fait j'ai les logs d'environ 70 sites que je faisais arriver dans un seul et même index afin de pouvoir centraliser et simplifier mes requêtes en utilisant des tag sur chaque évènement en input selon l'IP source pour pouvoir les identifier.
Je viens de tester une autre approche : scinder les logs sur 70 index en fonction de la provenance, ce qui me permets d'avoir des index pas trop gros, avec pour chaque index un nom du genre FR.SITE1, FR.SITE2 etc...
Une fois tout les index crées et renseigné dans Kibana, je crée un autre index en wildcard du genre FR.*, qui n'est pas un index elasticsearch à proprement parlé ( du moins il n'existe pas quand je regarde les index présent avec _cat/indices ).
Est ce que dans ce cas de figure, selon toi, je serais soumis aux limitations java sur le nombre de document max par index ?

En ce qui concerne ILM, de ce que j'en ai lu, ça permets de gérer les rotations directement au niveau des index, et non pas des documents par index. Jusque la, j'utilisais des requêtes curl dans une crontab pour supprimer périodiquement les index, qui se recréaient tout seul au prochain évènement. Dans l'optique ou je n'ai pas ( encore ) de restrictions d'espace disque, je ne vois pas trop la différence ou l'intêret d'utiliser cet API.

Pour curator, j'ai souvent vu l'utilisation de ce plugin, mais j'ai commencé à utiliser ELK à partir de la 6.4, et il n'était déjà plus compatible. A ce jour, mon serveur est en 7.4.

Par contre, le rollover index parait très intéressant effectivement, en cas d'index trop gros. Je vais me renseigner la dessus et voir comment appliquer ça si je dois revenir sur un seul gros index.

Mais du coup, pour en revenir à ma question principale, si je comprends bien il n'y a donc aucuns moyen efficace et transparent de supprimer des documents en masse dans un index selon un critère timestamp ?

Non t'as pas besoin de créer quoi que ce soit elastic résout le nom de l'index avec une expression régulier, commence par....
Donc non t'auras pas la limitation de création de doc vu que ton index FR.* n'existe pas...

Si delete by query c'est transparent efficace mais dans ton cas ca peux faire mal. :sweat_smile:
Avec elasticsearch y'a beaucoup de ca dépends et ton cas rentre dedans.

La bonne pratique est de diviser tes index mais ta solution de créer 70 index n'est pas bonne, si tu créer 70 index par jour et t'as besoin de 20 jours de rétention tu va finir avec 1400 index (si mes calculs sont bons) ce qui peux aussi entraîner des problèmes de stabilité et rendre ton serveur lent.

La solution proposé au-dessus parait convenir avec l'utilisation de rollover et d'index journalier.
Tu peux utiliser ILM pour ne conserver que les 20 derniers index.

Dans kibana quand tu crée tes visualisation tu defini un pattern d'index donc tu peux définir FR.* et utiliser tout tes index. Nul besoin de dev tools, c'etait juste pour l'exemple. (D7ailleurs j'ai édité les examples j'avais oublié des * :astonished:)

Si je crée un index par site, je pense que je peux ( et je dois :slight_smile: ) me passer des index journaliers effectivement, j'ai déjà revu la configuration de mon LS dans ce sens.
Le fait de gérer les index de façon journalières ne m'arrange pas et ne me servira pas vraiment, je n'ai quasiment aucune requêtes effectué sur une seule journée.
Donc actuellement, j'ai bien mes 70 index ( un par site et donc volume beaucoup moins important que sur ma config de base avec un seul gros index et regroupant tout le monde ) avec une rotation de 1 mois ça devrait le faire. Mes recherches et mes dashboard sont donc maintenant basés sur la recherche FR.* pour englober chaque site sans pour autant tout regrouper dans un seul index.

Dans tout les cas mes logs sont sauvegardés en amont et zippé sur une autre machine, le stockage dans ELK me permets ici de requêter plus facilement mais le stockage à long terme n'est pas prévu sur cette machine.

Si j'ai bien compris tout ce que tu m'a dis, ma configuration devrait être viable sur le long terme, au moins jusqu'à ce que je sois à court d'espace disque. D'ici la je vais sérieusement me pencher sur le fonctionnement d'ILM et de rollover.

Merci en tout cas pour ton aide et ta patience, et tes précieux conseils.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.