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 repository and the implementation in such projects as GitHub, SoundCloud, Stack Overflow and LinkedIn bear testimony to its great popularity. The part “Elastic” says it all about the nature of the system, whose capabilities are enormous: from a simple file search on a small scale, through knowledge discovery, to big data analysis in real time.What makes Elastic a more powerful than the competition is the set of default configurations and behaviors, which allow to create a cluster and start adding documents to the index in a couple of minutes. Elastic will configure a cluster for you, will define an index and define the types of fields for the first document obtained, and when you add another server, it will automatically deal with dividing index data between servers.Unfortunately, the above mentioned automation makes it unclear to us what the default settings implicate, and it often turns out to be misleading. This article starts a series where I will be dealing with the most popular gotchas, which you might encounter during the process of Elastic-based app creation.
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.