web-dev-qa-db-fra.com

L'utilisation d'un équilibreur de charge avec ElasticSearch est-elle inutile?

J'ai un cluster de 3 nœuds ElasticSearch fonctionnant sur AWS EC2. Ces nœuds sont configurés à l'aide d'OpsWorks/Chef. Mon intention est de concevoir ce cluster de manière très résiliente et élastique (les nœuds peuvent entrer et sortir en cas de besoin).

D'après tout ce que j'ai lu sur ElasticSearch, il semble que personne ne recommande de mettre un équilibreur de charge devant le cluster; au lieu de cela, il semble que la recommandation est de faire l'une des deux choses suivantes:

  1. Pointez votre client vers l'URL/IP d'un nœud, laissez ES effectuer l'équilibrage de charge pour vous et espérez que ce nœud ne tombe jamais en panne.

  2. Codez en dur les URL/IP de TOUS vos nœuds dans votre application cliente et demandez à l'application de gérer la logique de basculement.

Mon expérience est principalement dans les fermes Web où il est juste de créer un énorme pool de serveurs Web autonomes, de lancer un ELB devant eux et de laisser l'équilibreur de charge décider quels nœuds sont vivants ou morts. Pourquoi ES ne semble-t-il pas prendre en charge cette même architecture?

48
user2719100

Vous n'avez pas besoin d'un équilibreur de charge - ES fournit déjà cette fonctionnalité. Vous auriez juste un autre composant, qui pourrait mal se comporter et qui ajouterait un saut de réseau inutile.

ES partagera vos données (par défaut en 5 fragments), qu'il essaiera de répartir également entre vos instances. Dans votre cas, 2 instances devraient avoir 2 fragments et 1 juste un, mais vous souhaiterez peut-être changer les fragments en 6 pour une distribution égale.

Par défaut, la réplication est définie sur "number_of_replicas":1, donc une réplique de chaque fragment. En supposant que vous utilisez 6 fragments, cela pourrait ressembler à ceci (R est un fragment répliqué):

  • node0: 1, 4, R3, R6
  • node1: 2, 6, R1, R5
  • node2: 3, 5, R2, R4

En supposant que node1 meurt, le cluster passera à la configuration suivante:

  • node0: 1, 4, 6, R3 + nouvelles répliques R5, R2
  • node2: 3, 5, 2, R4 + nouvelles répliques R1, R6

Selon votre paramètre de connexion, vous pouvez soit vous connecter à une instance (client de transport), soit rejoindre le cluster (client de noeud). Avec le client de noeud, vous éviterez les doubles sauts, car vous vous connecterez toujours au bon fragment/index. Avec le client de transport, vos demandes seront acheminées vers la bonne instance.

Il n'y a donc rien pour équilibrer la charge pour vous-même, il vous suffit d'ajouter des frais généraux. L'auto-clustering est probablement la plus grande force d'ES.

17
xeraa

Je pense que l'équilibrage de charge d'un cluster Elasticsearch est une bonne idée (conception d'un système tolérant aux pannes, résilient à la défaillance d'un nœud unique.)

Pour concevoir votre cluster, vous aurez besoin d'informations sur les deux fonctions principales d'Elasticsearch: 1. Rédaction et mise à jour de documents et 2. Interrogation de documents.

Rédaction/indexation de documents dans elasticsearch:

  1. Lorsqu'un nouveau document arrive dans Elasticsearch pour être indexé, Elasticsearch détermine le "fragment principal" auquel le document doit être affecté à l'aide de "l'algorithme de routage Shard"
  2. Le processus Lucene associé au fragment "mappe" les champs du document;
  3. Le processus Lucene ajoute le document à "l'index inversé" Lucene du fragment
  4. Tout "fragment de réplique" reçoit alors le document; le fragment de réplique "mappe" le document et ajoute le document à "l'index inversé" Lucene du fragment de réplique

Interrogation de documents dans Elasticsearch:

  1. Par défaut, lorsqu'une requête est envoyée à Elasticsearch, la requête atteint un nœud - cela devient le "nœud de requête" ou le "nœud de requête de passerelle" pour cette requête
  2. Le nœud diffuse la requête à chaque fragment de l'index (principal et réplique)
  3. chaque fragment effectue une requête sur l'index inversé Lucene local du fragment.
  4. chaque fragment renvoie les 10 - 20 premiers résultats au "nœud de requête de passerelle"
  5. le "nœud de requête de passerelle" effectue ensuite un tri par fusion sur les résultats combinés renvoyés par les autres fragments,
  6. une fois le tri par fusion terminé, le "nœud de requête de passerelle" et renvoie les résultats au client
    • le tri par fusion est gourmand en ressources CPU et mémoire

Architecte un équilibreur de charge pour les écritures/indexation/mises à jour

Elasticsearch gère lui-même l'emplacement des fragments sur les nœuds. Le "nœud maître" conserve et met à jour la "table de routage des fragments". Le "nœud maître" fournit une copie de la table de routage des fragments aux autres nœuds du cluster.

En règle générale, vous ne voulez pas que votre nœud maître fasse bien plus que des vérifications de l'état du cluster, la mise à jour des tables de routage et la gestion des partitions.

Il est probablement préférable de pointer l'équilibreur de charge pour les écritures vers les "nœuds de données" (les nœuds de données sont des nœuds qui contiennent des données = fragments) et de laisser les nœuds de données utiliser leurs tables de routage de fragments pour obtenir les écritures sur les fragments appropriés.

Architecture pour les requêtes

Elasticsearch a créé un type de nœud spécial: "nœud client", qui ne contient "aucune donnée" et ne peut pas devenir un "nœud maître". La fonction du nœud client consiste à effectuer le tri par fusion lourd des ressources finales à la fin de la requête.

Pour AWS, vous utiliseriez probablement un type d'instance c3 ou c4 en tant que "nœud client"

La meilleure pratique consiste à pointer l'équilibreur de charge des requêtes vers les nœuds clients.

À votre santé!

Références:

  1. Elasticsearch Node Types
  2. Elasticsearch: Shard Routing Algorithm
  3. Elasticsearch: Replica Shards
  4. Elasticsearch: État du cluster, c'est-à-dire la table de routage des fragments
  5. ElasticHQ - Introduction à Elasticsearch Video
  6. Elasticsearch: nombres d'éclats et mise à l'échelle des clusters
50
Manchego

Vous avez tout à fait raison de vouloir concevoir un `` basculement '', et dans AWS, voici comment je vous recommande de le faire.

1) Limitez les nœuds de votre cluster pouvant être élus maîtres. Pour le reste, définissez node.client: true. Basez votre choix du nombre de nœuds principaux éligibles sur le nombre de nœuds disponibles pour le basculement.

2) Créez un ELB qui comprend uniquement les nœuds électifs maîtres.

3) Dans Route 53, créez un CNAME pour votre cluster, avec la valeur définie sur le nom DNS de votre ELB.

12
GlenRSmith