Usos de Elasticsearch y cosas que debes saber
ACTUALIZACIÓN: En este artículo se hace referencia a nuestra oferta de Elasticsearch hospedado con su nombre anterior, Found. Ten en cuenta que Found ahora es conocido como Elastic Cloud.
Elasticsearch se usa en muchos casos de uso distintos: búsquedas de texto "clásicas", almacén de analíticas, autocompletar, revisión ortográfica, motor de alertas y almacén de documentos de uso general. En este artículo se brinda una visión general breve de los distintos usos comunes y cuestiones importantes que debes considerar, con indicadores que muestran dónde puedes aprender más al respecto.
Introducción
En Found, vemos muchos casos de uso distintos de Elasticsearch. Con frecuencia nos preguntan: "¿Cuál es el cliente típico?". Sin embargo, no hay una respuesta bien definida más allá de: "Prefieren dedicar tiempo a compilar cosas, más que ocuparse de un montón de clusters". Vemos que Elasticsearch se usa en un motón de distintas situaciones asombrosas y también algunas uno poco descabelladas.
Elasticsearch aún es bastante joven, y nuestros clientes tienden a empezar a usar Elasticsearch en un proyecto determinado y luego agregan más clusters para logging y analíticas también.
Una evolución de desarrollo común comienza con la creación de una búsqueda simple en un sitio web o una recopilación de documentos. Luego, quizá se agrega navegación facetada y corrector ortográfico o respuestas del tipo "¿Quisiste decir…?". Tal vez la búsqueda imprecisa esté garantizada, además de la función de autocompletar, y posiblemente la "búsqueda a medida que escribes". Dado que la relevancia es importante, es probable que se agreguen más esquemas de clasificación avanzados eventualmente; posiblemente basados en quién es el usuario, dónde está o a quién conoce. Por supuesto, para saber qué hacen en realidad los usuarios, el uso debe registrarse; además de que se deben almacenar las métricas para saber que todo funciona bien.
Puedes usar Elasticsearch para todo esto y más, pero los distintos usos traen aparejados niveles de complejidad y requisitos de recursos muy diferentes.
Ya sabes, para hacer búsquedas (¡y más!)
Como era de esperar, Elasticsearch suele usarse para implementar la "búsqueda", lo que significa que por lo general hay un cuadro de entrada acompañado de un ícono de lupa. Nuestro concepto de "búsqueda" puede ser ambiguo en este caso, así que hablaremos de distintos tipos de búsqueda, por ejemplo, "búsqueda simple", "búsqueda imprecisa", "agregación"; simple significa que puedes lograr una búsqueda match sencilla.
Sorprende a muchos que la búsqueda simple sea de las tareas que menos recursos usa que puedes pedirle a Elasticsearch. Si todo lo que necesitas son los 10 primeros resultados de una búsqueda match regular precisa, puedes realizar cientos de búsquedas por segundo en recopilaciones de decenas de millones de documentos en hardware económico. Sin embargo, cuando agregas la búsqueda imprecisa o la navegación facetada a la lista de requisitos, las necesidades de CPU y memoria aumentan mucho.
Se espera que las interfaces de búsqueda modernas, en general, tengan algún tipo de navegación facetada, es decir, en la que un usuario pueda comprender rápido la distribución de los resultados de búsqueda. ¿Cuántos libros son de un autor en particular, se encuentran en un rango de precios determinado o tienen una calificación determinada? Se implementan mediante agregaciones en Elasticsearch y vienen en varias formas. Puedes agregar a términos, rangos numéricos, rangos de fechas, distancia geográfica y mucho más.
Para muchos, va en contra del sentido común que examinar millones de documentos para encontrar coincidencias requiera en cierta forma menos esfuerzo que contar y agregar las coincidencias de varias formas. Sin embargo, en comparación con el problema de recuperación de la información "¿Qué 10 documentos coinciden con estas condiciones (o son más relevantes para ellas)?", la agregación es más costosa. Al puntuar para encontrar los mejores documentos, Lucene usará trucos como "Este conjunto de documentos no coincide con todo lo que estos otros documentos coinciden, por lo que no puede ser lo mejor, hay que omitirlo". Al filtrar, Elasticsearch utilizará la memoria caché de filtro, mucho. Elasticsearch y Lucene son excelentes para evitar trabajo cuando es posible, pero con las agregaciones, deben contar todas las coincidencias todo el tiempo.
En Elasticsearch desde cero, vemos cómo funciona el índice invertido y cómo el diccionario y las listas de posteo se usan para realizar una búsqueda simple. Este y nuestros artículos sobre análisis de texto deberían aclarar por qué procesar el texto de forma correcta es muy importante al trabajar con la búsqueda. Sizing Elasticsearch (Dimensionar Elasticsearch) y Elasticsearch en producción detallan el tipo de uso de memoria que puedes esperar.
Analíticas
Las cargas de trabajo analíticas tienden a contar cosas y resumir tus datos; muchos datos, incluso tal vez big data, lo que sea que signifique. Dependen de las agregaciones de Elasticsearch, y las agregaciones suelen estar generadas por herramientas como Kibana.
Ya mencionamos que estas agregaciones pueden ser bastante costosas, tanto en cuanto a CPU como a memoria. Los requerimientos de memoria son importantes, ya que Elasticsearch necesita buscar rápido un valor dado un documento, lo cual involucra cargar todos los datos de todos los documentos a la memoria en una "caché de campo". Esto puede aliviarse usando "valores de documentos", que deben habilitarse en tu mapeo antes de indexar documentos.
Además, las búsquedas analíticas suelen ejecutarse sobre datos con marcas de tiempo, lo que puede tener sentido particionar, por ejemplo, en índices diarios o mensuales. Tener un índice por unidad de tiempo facilita acotar el espacio de búsqueda y limpiar y archivar datos antiguos.
Búsqueda imprecisa
Una búsqueda imprecisa es una tolerante a errores ortográficos. Por ejemplo, puedes encontrar Levenshtein cuando buscas Levenstein. Nuestro artículo sobre búsquedas imprecisas ofrece más detalles sobre cómo usar las búsquedas imprecisas y cómo funcionan.
Las búsquedas imprecisas son simples de habilitar y pueden mejorar mucho la "recuperación", pero también puede ser muy costoso ejecutarlas. De forma predeterminada, un término en la entrada puede reescribirse a un O de 50 términos por campo, lo cual en combinación con multi_field puede causar una explosión combinatoria de términos en la búsqueda reescrita resultante.
Siempre es importante probar los cambios y las mejoras en la búsqueda con cantidades realistas de datos antes de enviarlos a producción. En particular, cuando se agrega el parámetro fuzziness. Es fácil habilitar esta opción, pero hará que tus búsquedas sean más costosas en varios órdenes de magnitud.
Las búsquedas imprecisas demandan un uso intensivo de la CPU. Agrégalas con cuidado y, probablemente, no en todos los campos.
Autocompletar y búsqueda instantánea
La búsqueda mientras el usuario escribe puede ser de distintas formas. Pueden ser sugerencias simples de, por ejemplo, etiquetas existentes, intentar predecir una búsqueda basada en el historial de búsqueda o hacer una búsqueda totalmente nueva por cada pulsación de tecla (limitado).
Hay muchas características diferentes en Elasticsearch para asistir en la creación de estas característica, como búsquedas prefix, match_phrase_prefix, n-gramas de indexación y una familia de herramientas de sugerencia diferentes.
Las búsquedas como esta son muy sensibles a las latencias. El umbral de lo que ya no se siente "instantáneo" suele considerarse ser 100 milisegundos. Buscar casi todas las pulsaciones de tecla también significa más resultados de búsqueda. Por lo tanto, es esencial que las búsquedas sean económicas y que estos índices entren en la memoria.
Autocompletar las búsquedas mientras también se muestran resultados de la búsqueda completada más probable, muy similar a lo que hace Google, debería considerarse como dos problemas distintos de búsqueda. La cantidad de datos que se deben buscar al autocompletar búsquedas anteriores es probablemente mucho menor que el contenido en el que se busca, lo cual hace que sea más factible mantener todo en la memoria y brindar búsquedas imprecisas. Como una búsqueda de autocompletar verá una carga de búsqueda mucho más alta que la búsqueda completa, mantenerlas por separado posibilita escalarlas por separado también, posiblemente en clusters de Elasticsearch totalmente diferentes.
Cuando Soundcloud renovó su experiencia de búsqueda, trabajaron mucho en las sugerencias de búsqueda. Al implementarlas bien, no solo vieron un aumento en la precisión de búsqueda, sino también una gran reducción de la carga en la infraestructura que impulsa la búsqueda completa. Lo que las personas buscan suele seguir una distribución Zipf: por lo general, el 10 % de las búsquedas únicas dan cuenta del 90 % del volumen de búsqueda. Por lo tanto, es muy probable que los resultados completos de la mejor sugerencia de búsqueda ya estén en la memoria caché (en tu capa de aplicación) y puedan mostrarse "de forma instantánea".
Mucha de la ingeniería detrás de la herramienta de sugerencias de búsqueda de Soundcloud es lo que lleva a las características de la herramienta de sugerencias de Elasticsearch. Hay una presentación excelente que hicieron Muir y Willauer en Query Suggestions with Lucene (Sugerencias de búsqueda con Lucene) que vale la pena mirar para obtener más información.
Multitenancy
Con frecuencia, hay varios clientes o usuarios con distintas recopilaciones de documentos, y un usuario nunca debe poder buscar en documentos que no le pertenecen. Esto suele llevar a un diseño en el que cada usuario tiene su propio índice.
En la mayoría de los casos, esto lleva a demasiados índices. En casi todos los casos, vemos implementado el índice por usuario, un índice de Elasticsearch más grande en realidad sería mejor. Hay desventajas importantes de tener una gran cantidad de índices pequeños:
- La sobrecarga de memoria no es insignificante. Miles de pequeños índices consumirán mucho espacio en la memoria heap. La cantidad de descriptores de archivos también puede aumentar.
- Puede haber mucha duplicación. Considera cómo funciona el índice invertido y cómo Lucene escribe y comprime las cosas en segmentos.
- Snapshot/restauración es actualmente un proceso en serie, con una sobrecarga por índice. Realizar snapshots de miles de pequeños índices adquiere un orden de magnitud más prolongado que realizar snapshots de algunos índices grandes.
En Sizing Elasticsearch (Dimensionar Elasticsearch), hay más información sobre estrategias de shards y particionamiento, con varias referencias más. Corregir una aplicación con un diseño de índices subóptimo puede requerir de bastante esfuerzo, por lo que vale la pena tomarse el tiempo para comprender los distintos enfoques.
Probablemente no debas hacer un índice por usuario en tu aplicación de usuarios múltiples.
Sin esquema/esquemas definidos por el usuario
En relación con tener varios clientes individuales, también vemos muchos casos de uso en los que los distintos usuarios pueden tener documentos completamente diferentes. Por ejemplo, si proporcionas encuestas/cuestionarios a los usuarios como servicio, es probable que las distintas encuestas tengan campos completamente diferentes.
Con frecuencia, esto lleva a usar el "mapeo dinámico" de Elasticsearch, a veces publicitado como que Elasticsearch no tiene esquemas. Sin embargo, Elasticsearch creará un mapeo por ti en segundo plano, y puede ser problemático cuando crece demasiado, lo que lleva a una "explosión de mapeo". En cambio, es importante asegurarse de que los valores en un documento también terminen siendo valores, y no campos diferentes. Esto se explica un poco más en "Key/Value Woes" (Problemas de claves/valores).
Elasticsearch tiene capacidades de mapeo versátiles, con plantillas de índices, plantillas dinámicas, multicampos y más. ¡Úsalos!
Incluso cuando no uses un mapeo, debes saber qué mapeo Elasticsearch crea por ti.
Búsquedas definidas por usuarios
Con los esquemas definidos por el usuario suele estar la necesidad de permitir a los usuarios finales definir sus propias búsquedas, con filtros personalizados, puntuación y agregaciones. Un enfoque común es limitar la solicitud de búsqueda a ciertos índices o envolver la búsqueda de los usuarios con filtros.
Incluso al hacer esto, hay varias formas en las que un usuario puede causar estragos cuando las solicitudes de búsqueda personalizadas pueden definirse, como expresar búsquedas que demandan un uso intensivo de la CPU, acaparan la memoria o provocan que Elasticsearch falle. Estos temas se abarca en Six Ways to Crash Elasticsearch (Seis formas de hacer fallar Elasticsearch) y cómo asegurar tu cluster de Elasticsearch.
Ten cuidado con las solicitudes de búsqueda definidas por el usuario.
Rastreo y procesamiento de documentos
Existen varias formas de ingresar los datos en Elasticsearch.
Un río es un concepto de Elasticsearch en el que Elasticsearch toma los datos de una fuente, como una base de datos a través de JDBC, una cola de mensajes, una transmisión de Twitter o rastreando sitios web. Es bastante fácil comenzar a usarlos, pero el enfoque rápidamente se vuelve desafiante de escalar y operar en producción. Como tales, los ríos quedan obsoletos, y uno debe intentar resolver estos problemas fuera Elasticsearch. Logstash continúa obteniendo soporte para más sistemas y puede reemplazar a muchos ríos. En las aplicaciones personalizadas, hay suficientes desafíos al sincronizar los datos en Elasticsearch y preparar los documentos de Elasticsearch, por lo que no debería esperarse que algo simple y genérico como los ríos sea suficiente. Para el rastreo, las personas están usando Scrapy y Nutch junto con Elasticsearch.
En relación con esto, está el procesamiento y la conversión de documentos, como documentos de Word o PDF a texto sin formato que Elasticsearch puede indexar. Hay un plugin "mapper-attachments" que se puede usar para hacer esta conversión en Elasticsearch. Sin embargo, mientras que el plugin de archivos adjuntos es conveniente, recomendamos hacer la conversión de documentos antes de enviar los documentos a Elasticsearch. Esto te brinda el máximo control de cómo se convierten y refinan los documentos. La conversión de documentos de este tipo suele ser uno de los primeros pasos durante el "pipeline de procesamiento de documento/texto" de la "refinación de contenido". Los documentos que envías a Elasticsearch deben ser el resultado de esta "preparación/refinación de contenido", y dejar que Elasticsearch haga el procesamiento y la indexación finales del texto. La conversión de documentos demanda un uso intensivo de la CPU, pero puede paralelizarse con facilidad. Es preferible dejar que Elasticsearch dedique su tiempo a indexar y buscar, y dejar que los clientes "aguas arriba" realicen la conversión del documento.
Envía los datos procesados a Elasticsearch, no extraigas y proceses dentro de Elasticsearch.
Resumen
Hay mucho que aprender con Elasticsearch, y a veces puede ser difícil saber qué necesitas aprender.
En este artículo, abarcamos varios casos de uso comunes y algunas cuestiones importantes que debes conocer para todos ellos. Esperamos que hayas aprendido algo nuevo y relevante para tus necesidades, y que te hayas acercado a enviar tu aplicación de Elasticsearch a producción.