ruby-on-rails - sitepoint - elasticsearch ruby
¿Hay alguna manera más inteligente de reindexar elasticsearch? (4)
Lo pregunto porque nuestra búsqueda está en un estado de cambio a medida que trabajamos las cosas, pero cada vez que hacemos un cambio en el índice (cambio de tokenizador o filtro, o número de fragmentos / réplicas), tenemos que eliminar todo el índice y volver a indexar todos nuestros modelos de Rails en Elasticsearch ... esto significa que tenemos que tener en cuenta el tiempo de inactividad para volver a indexar todos nuestros registros.
¿Hay alguna forma más inteligente de hacer esto de la que no tengo conocimiento?
¿Tal vez crear otro índice y reindexar todos los datos en ese, y luego hacer el cambio cuando haya terminado de volver a indexar?
Creo que @karmi lo hace bien. Sin embargo, permítanme explicarlo un poco más simple. Necesitaba ocasionalmente actualizar el esquema de producción con algunas propiedades nuevas o configuraciones de análisis. Recientemente comencé a usar el escenario que se describe a continuación para realizar migraciones de índice de tiempo de carga constante, en vivo, sin tiempo de inactividad. Puedes hacerlo de forma remota.
Aquí hay pasos:
Suposiciones
- Usted tiene index
real1
yreal_write
,real_read
apuntan, - el cliente solo escribe en
real_write
y solo lee dereal_read
, -
_source
propiedad del documento está disponible.
1. Nuevo índice
Crea real2
índice real2
con nuevas asignaciones y configuraciones de tu elección.
2. Alias del escritor
Utilizando el siguiente alias de escritura de solicitud masiva escribe alias.
curl -XPOST ''http://esserver:9200/_aliases'' -d ''
{
"actions" : [
{ "remove" : { "index" : "real1", "alias" : "real_write" } },
{ "add" : { "index" : "real2", "alias" : "real_write" } }
]
}''
Esta es una operación atómica. A partir de este momento, real2
se rellena con los datos del nuevo cliente en todos los nodos. Los lectores todavía usan el viejo real1
través de real_read
. Esto es una consistencia eventual.
3. Vieja migración de datos
Los datos se deben migrar de real1
a real2
, sin embargo, los documentos nuevos en real2
no se pueden sobrescribir con entradas antiguas. La secuencia de comandos de migración debe usar una API bulk
con la operación de create
(no el index
o la update
). Utilizo el sencillo script Ruby es-reindex que tiene un buen estado de ETA:
$ ruby es-reindex.rb http://esserver:9200/real1 http://esserver:9200/real2
ACTUALIZACIÓN 2017 Puede considerar la nueva API de Reindex en lugar de usar la secuencia de comandos. Tiene muchas características interesantes como informes de conflictos, etc.
4. Alias del lector
Ahora real2
está actualizado y los clientes le escriben, sin embargo, todavía están leyendo de real1
. Actualicemos el alias del lector:
curl -XPOST ''http://esserver:9200/_aliases'' -d ''
{
"actions" : [
{ "remove" : { "index" : "real1", "alias" : "real_read" } },
{ "add" : { "index" : "real2", "alias" : "real_read" } }
]
}''
5. Haga una copia de seguridad y elimine el índice anterior
Escribe y lee ir a real2
. Puede hacer una copia de seguridad y eliminar el índice real1
del clúster de ES.
¡Hecho!
Escribí una publicación de blog sobre cómo manejé reindexar sin tiempo de inactividad recientemente. Toma algo de tiempo descubrir todas las pequeñas cosas que necesitan estar en su lugar para hacerlo. ¡Espero que esto ayude!
https://summera.github.io/infrastructure/2016/07/04/reindexing-elasticsearch.html
Para resumir:
Paso 1: prepare un nuevo índice
Crea tu nuevo índice con tu nueva asignación. Esto puede ser en la misma instancia de Elasticsearch o en una instancia completamente nueva.
Paso 2: mantener los índices actualizados
Mientras está reindexando desea mantener actualizados sus índices nuevos y antiguos. Para una operación de escritura, esto se puede hacer enviando la operación de escritura a un trabajador de fondo tanto en el índice nuevo como en el antiguo.
Las eliminaciones son un poco más complicadas porque existe una condición de carrera entre borrar y reindexar el registro en el nuevo índice. Por lo tanto, querrá hacer un seguimiento de los registros que deben eliminarse durante su reindexación y procesarlos cuando haya terminado. Si no está realizando muchas eliminaciones, otra forma sería eliminar la posibilidad de una eliminación durante su reindexación.
Paso 3: realizar Reindexing
Querrá utilizar una búsqueda desplazada para leer los datos y una API masiva para insertar. Dado que después del Paso 2 escribirás documentos nuevos y actualizados en el nuevo índice en segundo plano, asegúrate de NO actualizar los documentos existentes en el nuevo índice con tus solicitudes de API masivas.
Esto significa que la operación que desea para sus solicitudes de API masivas es crear, no indexar. De la documentation : "crear fallará si ya existe un documento con el mismo índice y tipo, mientras que el índice agregará o reemplazará un documento según sea necesario". El punto principal aquí es que no desea que los datos antiguos de la instantánea de búsqueda desplazada sobrescriban datos nuevos en el nuevo índice.
Hay un gran script en github para ayudarte con este proceso: es-reindex .
Paso 4: Cambiar
Una vez que haya terminado de reindexar, es hora de cambiar su búsqueda al nuevo índice. Deseará volver a activar las eliminaciones o procesar las tareas de eliminación en cola para el nuevo índice. Puede observar que buscar el nuevo índice es un poco lento al principio. Esto se debe a que Elasticsearch y la JVM necesitan tiempo para calentarse.
Realice los cambios de código que necesite para que su aplicación comience a buscar el nuevo índice. Puede seguir escribiendo en el índice anterior en caso de que tenga problemas y necesite deshacer. Si siente que esto no es necesario, puede dejar de escribir en él.
Paso 5: limpiar
En este punto, debe pasar por completo al nuevo índice. Si todo va bien, realice las tareas de limpieza necesarias, como:
- Eliminar el host de índice anterior si es diferente del nuevo
- Elimine el código de serialización relacionado con su índice anterior
Sí, hay formas más inteligentes de volver a indexar sus datos sin tiempo de inactividad.
Primero, nunca use el nombre del índice "final" como su nombre de índice real. Por lo tanto, si desea ponerle nombre a sus "artículos" de índice, no los use como índice físico, sino que cree un índice como "artículos-2012-12-12" o "artículos-A", "artículos -1 ", etc.
En segundo lugar, cree un alias "alias" que apunte a ese índice. Su aplicación usará este alias, por lo que nunca necesitará cambiar manualmente el nombre del índice, reiniciar la aplicación, etc.
En tercer lugar, cuando quiera o necesite volver a indexar los datos, vuelva a indexarlos en un índice diferente , digamos "artículos-B", todas las herramientas en la herramienta de indexación de Tyre lo respaldan aquí.
Cuando termines, apunta el alias al nuevo índice. De esta forma, no solo minimiza el tiempo de inactividad (no hay ninguno), también tiene una instantánea segura: si de alguna manera desordena la indexación en el nuevo índice, puede simplemente volver al anterior, hasta que resuelva el problema. problema.