Hola amigos Hay gente con diferentes niveles de experiencia contribuyendo a nuestros foros, ¡y eso es genial! Pero ahora mismo, ¡estoy buscando verdaderos titanes de Ruby!
Elasticsearch es un motor de búsqueda basado en una biblioteca madura y de confianza: Apache Lucene. Enorme actividad en git proyecto y la implementación en proyectos como GitHub, SoundCloud, Stack Overflow y LinkedIn dan fe de su gran popularidad. La parte "Elastic" lo dice todo sobre la naturaleza del sistema, cuyas capacidades son enormes: desde una simple búsqueda de archivos a pequeña escala, pasando por el descubrimiento de conocimientos, hasta el análisis de big data en tiempo real.Lo que hace de Elastic un sistema más potente que la competencia es el conjunto de configuraciones y comportamientos predeterminados, que permiten crear un clúster y empezar a añadir documentos al índice en un par de minutos. Elastic configurará un clúster por ti, definirá un índice y definirá los tipos de campos para el primer documento obtenido, y cuando añadas otro servidor, se ocupará automáticamente de dividir los datos del índice entre los servidores.Desafortunadamente, la automatización mencionada anteriormente hace que no tengamos claro lo que implican las configuraciones por defecto, y a menudo resulta ser engañoso. Este artículo inicia una serie en la que trataré los problemas más comunes que pueden surgir durante el proceso de creación de aplicaciones basadas en Elastic.
El número de fragmentos no puede modificarse
Indexemos el primer documento con índice API:
$ curl -XPUT 'http://localhost:9200/myindex/employee/1' -d '{
"first_name" : "Jane",
"last_name" : "Smith",
"steet_number": 12
}'
En este momento, Elastic crea un índice para nosotros, titulado myindex. Lo que no es visible aquí es el número de shards asignados al índice. Los shards pueden entenderse como procesos individuales responsables de la indexación, almacenamiento y búsqueda de una parte de los documentos de un índice completo. Durante el proceso de indexación de documentos, elastic decide en qué shard debe encontrarse un documento. Esto se basa en la siguiente fórmula
shard = hash(document_id) % number_of_primary_shards
Ahora está claro que el número de shards primarios no puede cambiarse para un índice que contiene documentos. Por lo tanto, antes de indexar el primer documento, cree siempre un índice manualmente, dando el número de shards, que considere suficiente para un volumen de datos indexados:
$ curl -XPUT 'http://localhost:9200/myindex/' -d '{
"settings" : {
"number_of_shards" : 10
}
}'
Valor por defecto para número_de_chatarras
es 5. Esto significa que el índice puede escalarse hasta 5 servidores, que recopilan datos durante la indexación. Para el entorno de producción, el valor de los shards debe establecerse en función de la frecuencia prevista de indexación y del tamaño de los documentos. Para entornos de desarrollo y pruebas, recomiendo establecer el valor en 1 - ¿por qué? Se explicará en el siguiente párrafo de este artículo.
Clasificación de los resultados de la búsqueda de texto con un número relativamente pequeño de documentos
Cuando buscamos un documento con una frase:
$ curl -XGET 'http://localhost:9200/myindex/my_type/_search' -d
'{
"consulta": {
"match": {
"título": "El rápido zorro marrón"
}
}
}'
Elastic procesa la búsqueda de texto en pocos pasos, simplemente hablando:
- la frase de la solicitud se convierte en la misma forma idéntica en la que se indexó el documento, en nuestro caso será conjunto de términos:
["rápido", "marrón", "zorro"]
("el" se elimina porque es insignificante),
- se navega por el índice para buscar los documentos que contienen al menos una de las palabras buscadas,
- cada documento que coincide se evalúa en términos de pertinencia para la frase de búsqueda,
- los resultados se ordenan según la relevancia calculada y se devuelve al usuario la primera página de resultados.
En el tercer paso, se tienen en cuenta los siguientes valores (entre otros):
- cuántas palabras de la frase de búsqueda hay en el documento
- frecuencia con la que una palabra aparece en un documento (TF - frecuencia de términos)
- si las palabras coincidentes aparecen en otros documentos y con qué frecuencia (IDF - frecuencia inversa de documentos): cuanto más popular sea la palabra en otros documentos, menos significativa será.
- extensión del documento
El funcionamiento de IDF es importante para nosotros. Por razones de rendimiento, Elastic no calcula este valor para cada documento del índice, sino que cada shard (trabajador del índice) calcula su IDF local y lo utiliza para ordenar. Por lo tanto, durante la búsqueda en el índice con un número bajo de documentos podemos obtener resultados sustancialmente diferentes dependiendo del número de shards en un índice y de la distribución de documentos.
Imaginemos que tenemos 2 shards en un índice; en el primero hay 8 documentos indexados con la palabra "fox", y en el segundo sólo 2 documentos con la misma palabra. Como resultado, la palabra "fox" diferirá significativamente en ambos fragmentos, y esto puede producir resultados incorrectos. Por lo tanto, para fines de desarrollo debe crearse un índice que conste de un solo fragmento primario:
$ curl -XPUT 'http://localhost:9200/myindex/' -d
'{"settings" : { "number_of_shards" : 1 } }'
Ver los resultados de las páginas de búsqueda "lejanas" mata a tu clúster
Como ya he escrito en párrafos anteriores, los documentos de un índice se comparten entre procesos de índice totalmente individuales - shards. Cada proceso es completamente independiente y sólo se ocupa de los documentos que se le asignan.
Cuando buscamos en un índice con millones de documentos y esperamos a obtener los 10 mejores resultados, cada fragmento debe devolver sus 10 resultados mejor emparejados al cluster de nodoque inició la búsqueda. A continuación, se juntan las respuestas de cada fragmento y se eligen los 10 mejores resultados de la búsqueda (dentro de todo el índice). Este enfoque permite distribuir eficazmente el proceso de búsqueda entre varios servidores.
Imaginemos que nuestra aplicación permite ver 50 resultados por página, sin las restricciones relativas al número de páginas que puede ver un usuario. Recordemos que nuestro índice consta de 10 shards primarios (1 por servidor).
Veamos cómo será la adquisición de resultados de búsqueda para la 1ª y la 100ª página:
Página nº 1 de los resultados de búsqueda:
- El nodo que recibe una consulta (controlador) la transmite a 10 shards.
- Cada fragmento devuelve sus 50 mejores documentos coincidentes ordenados por relevancia.
- Una vez recibidas las respuestas de cada fragmento, el controlador fusiona los resultados (500 documentos).
- Nuestros resultados son los 50 mejores documentos del paso anterior.
Página nº 100 de los resultados de búsqueda:
- El nodo que recibe una consulta (controlador) la transmite a 10 shards.
- Cada fragmento devuelve sus 5.000 documentos más coincidentes ordenados por relevancia.
- Tras recibir las respuestas de cada fragmento, el controlador fusiona los resultados (50000 documentos).
- Nuestros resultados son los documentos del paso anterior posicionados 4901 - 5000.
Suponiendo que un documento tenga un tamaño de 1 KB, en el segundo caso significa que deben enviarse y procesarse unos 50 MB de datos en el clúster para ver 100 resultados de un usuario.
No es difícil darse cuenta de que el tráfico de red y la carga del índice aumentan significativamente con cada página de resultados sucesiva. Por eso no es recomendable poner a disposición del usuario las páginas de búsqueda "lejanas". Si nuestro índice está bien configurado, entonces el usuario debería encontrar el resultado que le interesa en las primeras páginas de búsqueda, y nos protegeremos de la carga innecesaria de nuestro cluster. Para probar esta regla, comprueba hasta qué número de páginas de resultados de búsqueda permiten ver los buscadores web más populares.
También es interesante observar el tiempo de respuesta del navegador para las sucesivas páginas de resultados de búsqueda. Por ejemplo, a continuación se muestran los tiempos de respuesta de páginas individuales de resultados de búsqueda en Google Search (el término de búsqueda era "motor de búsqueda"):
| Página de resultados de búsqueda (10 documentos por página) | Tiempo de respuesta
|——————————————–|—————|
| 1 250ms
| 10 | 290ms |
| 20 | 350ms |
| 30 | 380ms |
| 38 (último disponible) | |
En la próxima parte, examinaré más de cerca los problemas relativos a la indexación de documentos.