Infrastructure d'Elasticsearch

Bonjour à tous !

J'ai quelques questions concernant l’installation et le management d'ES :smiley:

J'ai pour l'instant un site web hébergé sur un mutualisé et je vais changer d'architecture (j'hésite entre soit google app engine soit un dédié).

Ma première question va être, est-il possible (question performance), de mettre mon site et ES sur un même serveur ? Ou il vaut mieux les séparer ? (donc 2 serveurs).

D'içi fin de l'été, je vais dupliquer ma bdd en 4 car nous allons internationaliser notre site (donc .fr, .uk, etc).
Il y aura donc 4 fois plus de recherche (logique héhé).

Est-ce que le serveur, avec Es et les 4 sites hébergés, peut supporter la charge ?
Ou une fois encore, c'est mieux de séparer les sites et ES.

Sachant qu'à terme, nous devrions nous développer dans plusieurs pays, donc toujours plus de bdd et ainsi de suite.

Deuxième question, c'est sur l'architecture d'ES.
Je n'ai pas bien compris les nodes. Un cluster regroupe des nodes. Les nodes contiennent des indexes qui eux contiennent les data (si j'ai bien suivis).

J'ai actuellement ce chemin : node-fr/utilisateur/id utilisateur (node-fr/utilisateur/1).
J'ai mis dans ce node mes utilisateur français.
Avec les futurs sites étrangers, je pense faire node-uk, node-es, etc.

Chaque site aura son node, qui contient les data soit des utilisateurs, soit d'autre objet que l'on peut rechercher dans notre site.

J'aurais donc un cluster contenant un node par site, et chaque node sera divisé en index d'objet (utilisateur, etc).

Est-ce une bonne logique ?
Je vois que si le cluster tombe pour x raisons, je n'ai plus de recherche sur tout mes sites :grin:
Vaut-il mieux faire un cluster par site ? Qui aura son node et donc le down d'un cluster n'impactera pas les autres.
Je ne sais pas si c'est pertinent de faire un cluster avec un seul node.

Dernière interrogation : les shards.
D’après la doc, les shards servent à stocker les data et on peut en définir plusieurs.
Ce que je ne comprend pas, en reprenant mon exemple node-fr/utilisateur/1, c'est que chaque nouveaux document sera indexé dans une shard aléatoirement ?
De ce fait, vaut-il mieux en avoir plusieurs ou simplement une seule ?

Voila voila, merci aux courageux qui auront tout lu :slight_smile:

Idéalement, il vaut mieux laisser toute la puissance à Elasticsearch histoire de ne pas être pertubé par d'autres services. Notamment mettre avec une BDD va typiquement dégrader fortement les IO d'Elasticsearch.

Si c'est possible pour toi, fais un cluster elasticsearch complètement séparé du reste.

Evidemment. C'est un moteur de recherche. Il est fait pour ça ! :stuck_out_tongue:
L'idéal à mon avis est de faire un index par langue.

Node: instance physique d'Elasticsearch. En gros: un process (une JVM). On ne met (sauf cas exceptionnel) qu'un seul noeud par machine physique.
Cluster: un ensemble de noeuds qui ont tous le même cluster name.
Un index contient en effet les data.

Non. En tant qu'utilisateur tu dois séparer les concepts. Les noeuds sont un pb d'architecture physique. En tant que DEV tu dois juste te dire que tu as un cluster elasticsearch (quelque soit le nombre de noeuds dedans.
Toi, tu créés un index fr sur elasticsearch et tu laisses elasticsearch se charger de son allocation sur les noeuds.

Quand tu cherches dans un index, tu n'as pas à savoir où son physiquement les données. C'est le pb d'elasticsearch.

Un index est découpé en shards (partitions). Chaque shard est une instance de Lucene. Quand tu indexes un document, ce document va aller vers un shard physique et y être indexé. Là encore, ce n'est pas ton problème. Laisse faire elasticsearch.

Su un cluster de 3 noeuds, avec 3 index (fr, de, us) et 1 primary shard par index (p) et un replica par shard (r), tu auras au final 6 shards alloués sur ton cluster.

Elasticsearch en mettra 2 sur chaque noeud.

Par exemple:

Noeud 1: fr-1-P et us-1-R
Noeud 2: de-1-P et fr-1-R
Noeud 3: us-1-P et de-1-R

Si tu perds un noeud, il rebalancera tout ça et tes utilisateurs ne verront probablement pas la panne.

En espérant que ça t'aide.

Tout d'abord merci de ta réponse claire, j'y vois un peu mieux !

Donc faire 2 serveurs, un pour le site et un autre pour ES.

Je reviens sur les nœuds.
Je viens de relire la doc et je crois que j'avais mal compris.

"localhost:9200/node-fr/candidat/1" -> je pensais que c'était nœud fr, index candidat et document numéro 1. Alors que c'est index node-fr, type candidat et document numéro 1.

Et je ne comprenais pas comment les nœuds fonctionnaient (savoir où les documents allaient pour les récupérer et ainsi de suite). C'est de suite plus clair, ES gère les nœuds et moi les indexes/types :grin:

Donc oui, dans la config du cluster, mettre 3 nœuds puis créer 3 index avec chacun une primary shard et une replica.

Question évolution du cluster, si demain j'ai une 4ème langue, je rajoute un nœud (avec index et shard) ? Ou seulement un 4ème index (primary et replica shard) ?

Pas besoin d'ajouter de noeud supplémentaire pour ça.
Tu crées simplement un nouvel index qui sera alloué par ES sur les 3 noeuds existants.

D'un point de vue performance, si j'ajoute de plus en plus d'index, à quel moment il sera pertinent d'ajouter des nœuds (pour diviser la charge de traitement) ?

Est-ce que 3 nœuds seront suffisant ou dans le futur il faudra en ajouter d'autre ?

Ça depend.

Réponse très commune dans le monde elastic.

En tout cas fais du monitoring de ton cluster. Si tu vois que les resources saturent, ajouter un noeud.
Tu peux aussi étendre verticalement (plus de CPU/Mémoire...)

Tu as quel volume environ ?

  • Nombre de doc
  • Taille de l'index en Mo

Oui ça dépend toujours :grin:

Alors pour l'instant j'aurais environ 40k de doc pour environ 270mo.

L'ajout de nœud se fait de manière transparente ? Ou il faut mettre offline ES, refaire la config, remettre les data et le relancer ?

Bonjour David,

De mon coté j'ai un 1 node "sur même serveur que le site + BDD" et 1 index de 200 MO et 3 Shards,
d'après le monitoring, j'ai just un PB de mémoire pour la JVM je lui est donné 3 Go sur les 16 de la machine et même sans requête elle en consomme 50% ,

Mais au delà de ça est-ce une mauvaise config ? "mon index est ré-indéxé tous les jours"

Merci.

40 k docs... 270 mo. C'est pas grand chose. Je veux dire que ça devrait très bien tenir la charge. Même en triplant les index.

Oui

Non. Juste que ce n'est pas la configuration idéale. Maintenant, si ça fonctionne et te donne les perfs que tu attends... Pas la peine de changer ça.
3 shards pour 200mo est inutile à mon avis. Avec un shard, tu devrais avoir assez, et consommer moins de mémoire.
Juste que l'indexation quotidienne pourrait prendre plus de temps peut-être...

Comme d'hab,
merci du retour !

c'est encore moi,

Pour mon Use case, j'ai testé avec 1 Shard au lieu de 3 :

  • Indexation est plus longue de 3 minutes
  • Test sur une grosse requête qui c'est envolé de +de 150 ms
  • Jmv plus tendu "heap usage : 70%

Puis j'ai testé avec 5 Shards au lieu de 3 :

  • Indexation est plus rapide de 5 minutes
  • Test sur une grosse requête -20ms que quand j'avais 3 Shards
  • Jmv plus détendu "heap usage : 22%

Conclusion, étant donné ma config,
il vaut mieux surdimensionner les Shards... ?

Etrange. Mais sans doute pas assez de RAM.
Est-ce toujours le cas après une 10aine d'appels ou seulement au premier appel ?

Et avec 8Go de RAM alloué à la JVM, en faisant des tests à 1, 3 et 5 shards, ça donnerait quoi ?

Est-ce toujours le cas après une 10aine d'appels ou seulement au premier appel ?

Oui, j'avais remarqué que la 1ere requête apres un nouvel index était Tjs longue

"Et avec 8Go de RAM alloué à la JVM"
VS test précédent à 3 GO

1 Shard

  • Indexation idem que précédent test
  • Test Grosse requête un léger mieux que précédent test
  • Jmv "heap usage : 17%"

3 Shards

  • Indexation idem que précédent test
  • Test Grosse requête un léger mieux que précédent test
  • Jmv "heap usage : 30%"

5 Shards

  • Indexation
  • Test Grosse requête encore + rapide de 10ms
  • Jmv fait presque dodo "heap usage : 5% hors indexation

De manière générale lui augmenter son ES_HEAP_SIZE à 8 Go lui à fait du bien en terme de perf d'autant plus que 2,9 Go max ont été utilisé pendant l'indexation,

Mais 5 Shards sont plus performant que 1

Après indexation JMV ne redéscend pas tout de suite...

Ca, c'est normal et pas grave. La mémoire est réservée de toute façon pour elasticsearch.

Intéressant. Cela semble signifier que tu atteins les limites "Lucene" par shard en terme de volume.

Peut-être regarde tes requêtes pour voir si elles sont améliorables...

J'ai oublié de demander :

  • Quelle version de JVM ?
  • Quelle version de ES ?

Quelle version de JVM ?
Quelle version de ES ?

JVM: 1.8.0_60
ES: 2.3.3

Pour mon ex, environ 200 MO de data sur 5 Shards, ce qui fait 40 MO par Shard,
et d'après mon Bench ma grosse requête de test est 5X fois plus rapide avec 5 Shards que 1 Shard.

voici ma requête de test, qui en Production sera plus précise "avec des Filter, bool...", mais toujours avec le random "oui c'est lui qui est gourmand ;)" sur 1 250 000 Docs

{
  "query": {

    "function_score": {       
      "functions": [ {
          "random_score": {}
        }],
      "score_mode": "sum"
    }
  }
}

Avec 5 Shards took : 50ms
Avec 1 Shard took : 250ms (!)

Logique. Obligé de passer par tous les documents !
Et obligé de faire ça à chaque appel (sans cache)...

Donc faire ça en /// ça va plus vite, c'est sûr...

Merci David,
Excellente Journée !