Existe-t-il une manière plus intelligente de réindexer elasticsearch?

Je demande parce que notre recherche est dans un état de stream au fur et à mesure que nous travaillons, mais chaque fois que nous modifions l’index (modificateur de jeton ou filtre, nombre de partitions / répliques), nous devons faire disparaître tout l’index et réindexer tous nos modèles Rails dans Elasticsearch … cela signifie que nous devons tenir compte des temps d’arrêt pour réindexer tous nos enregistrements.

Y a-t-il une manière plus intelligente de faire cela que je ne connais pas?

Je pense que @ karmi le fait bien. Cependant, laissez-moi vous expliquer un peu plus facilement. Je devais parfois mettre à jour le schéma de production avec de nouvelles propriétés ou parameters d’parsing. J’ai récemment commencé à utiliser le scénario décrit ci-dessous pour effectuer des migrations d’index en temps réel, à charge constante et sans arrêt. Vous pouvez le faire à distance.

Voici les étapes:

Hypothèses:

  • Vous avez l’index real1 et les alias real_write , real_read pointant vers lui,
  • le client écrit uniquement dans real_write et lit uniquement à partir de real_read ,
  • _source propriété _source du document est disponible.

1. Nouvel index

Créez l’index real2 avec le nouveau mappage et les parameters de votre choix.

2. commutateur d’alias écrivain

Utiliser l’alias de commutateur de requête en bloc suivant.

 curl -XPOST 'http://esserver:9200/_aliases' -d ' { "actions" : [ { "remove" : { "index" : "real1", "alias" : "real_write" } }, { "add" : { "index" : "real2", "alias" : "real_write" } } ] }' 

C’est une opération atomique. À partir de ce moment, real2 les données du nouveau client sur tous les nœuds. Les lecteurs utilisent toujours l’ancien real1 via real_read . C’est la cohérence finale.

3. Ancienne migration de données

Les données doivent être migrées de real1 à real2 , mais les nouveaux documents dans real2 ne peuvent pas être remplacés par d’anciennes entrées. Le script de migration doit utiliser l’API en bulk avec l’opération de create (pas d’ index ni de update ). J’utilise le script Ruby simple es-reindex qui a un bon statut ETA:

 $ ruby es-reindex.rb http://esserver:9200/real1 http://esserver:9200/real2 

MISE À JOUR 2017 Vous pouvez envisager une nouvelle API Reindex au lieu d’utiliser le script. Il a beaucoup de fonctionnalités intéressantes comme les rapports de conflits, etc.

4. commutateur d’alias de lecteur

Maintenant, real2 est à jour et les clients y écrivent, mais ils sont toujours en train de lire à partir de real1 . Mettons à jour l’alias de lecteur:

 curl -XPOST 'http://esserver:9200/_aliases' -d ' { "actions" : [ { "remove" : { "index" : "real1", "alias" : "real_read" } }, { "add" : { "index" : "real2", "alias" : "real_read" } } ] }' 

5. Sauvegardez et supprimez l’ancien index

Écrit et lit aller à real2 . Vous pouvez sauvegarder et supprimer l’index real1 du cluster ES.

Terminé!

Oui, il existe des moyens plus intelligents pour réindexer vos données sans temps d’arrêt.

Tout d’abord, n’utilisez jamais le nom d’index “final” comme nom d’index réel. Donc, si vous souhaitez nommer vos index “articles”, n’utilisez pas ce nom comme index physique, mais créez un index tel que “articles-2012-12-12” ou “articles-A”, “articles -1 “, etc.

Deuxièmement, créez un alias “alias” pointant vers cet index. Votre application utilisera alors cet alias, vous n’aurez donc jamais besoin de modifier manuellement le nom de l’index, de redémarrer l’application, etc.

Troisièmement, lorsque vous voulez ou devez réindexer les données, ré-indexez-les dans un index différent , disons “articles-B” – tous les outils de la chaîne d’outils d’indexation de Tyre vous aident ici.

Lorsque vous avez terminé, pointez l’alias sur le nouvel index. De cette manière, non seulement vous réduisez les temps d’arrêt (il n’y en a pas), mais vous avez également un instantané sûr: si vous gâchez l’indexation dans le nouvel index, vous pouvez revenir à l’ancien jusqu’à ce que vous résolviez le problème. problème.

A écrit un blog sur la façon dont j’ai géré la réindexation sans aucun temps d’arrêt récemment. Il faut du temps pour comprendre toutes les petites choses qui doivent être en place pour le faire. J’espère que cela t’aides!

https://summera.github.io/infrastructure/2016/07/04/reindexing-elasticsearch.html

Résumer:

Étape 1: Préparer un nouvel index

Créez votre nouvel index avec votre nouveau mappage. Cela peut être sur la même instance d’Elasticsearch ou sur une nouvelle instance.

Étape 2: Gardez les index à jour

Pendant que vous réindexez, vous souhaitez conserver à la fois vos anciens et nouveaux index. Pour une opération d’écriture, cela peut être effectué en envoyant l’opération d’écriture à un agent d’arrière-plan sur le nouvel et l’ancien index.

Les suppressions sont un peu plus délicates car il existe une condition de concurrence entre la suppression et la réindexation de l’enregistrement dans le nouvel index. Donc, vous voudrez garder une trace des enregistrements qui doivent être supprimés pendant votre réindexation et les traiter lorsque vous avez terminé. Si vous n’effectuez pas beaucoup de suppressions, une autre solution consisterait à éliminer la possibilité d’une suppression pendant votre réindexation.

Étape 3: Réindexer

Vous souhaiterez utiliser une recherche déroulée pour lire les données et les API en vrac pour l’insertion. Étant donné qu’après l’étape 2, vous allez écrire des documents nouveaux et mis à jour dans le nouvel index en arrière-plan, vous devez vous assurer de ne PAS mettre à jour les documents existants dans le nouvel index avec vos demandes d’API en bloc.

Cela signifie que l’opération que vous souhaitez pour vos demandes d’API en masse est create, pas index. A partir de la documentation : “create échouera si un document avec le même index et le même type existe déjà, alors qu’index appenda ou remplacera un document si nécessaire”. Le point principal ici est que vous ne souhaitez pas que les anciennes données de l’instantané de recherche déroulé écrasent les nouvelles données du nouvel index.

Il existe un excellent script sur github pour vous aider dans ce processus: es-reindex .

Étape 4: Commutation

Une fois la réindexation terminée, il est temps de passer votre recherche au nouvel index. Vous souhaitez réactiver les suppressions ou traiter les tâches de suppression mises en queue pour le nouvel index. Vous remarquerez peut-être que la recherche du nouvel index est un peu lente au début. En effet, Elasticsearch et la JVM ont besoin de temps pour se réchauffer.

Effectuez les modifications de code nécessaires pour que votre application commence à rechercher le nouvel index. Vous pouvez continuer à écrire dans l’ancien index, même si vous rencontrez des problèmes et devez revenir en arrière. Si vous estimez que cela n’est pas nécessaire, vous pouvez cesser d’écrire.

Étape 5: Nettoyage

À ce stade, vous devriez être complètement passé au nouvel index. Si tout se passe bien, effectuez tout nettoyage nécessaire, tel que:

  • Supprimez l’ancien hôte d’index s’il est différent du nouveau
  • Supprimer le code de sérialisation lié à votre ancien index

Peut-être créer un autre index et réindexer toutes les données sur celui-ci, puis faire le changement quand il est fini de réindexer?