Ingeniería

Ahorro de espacio: Un beneficio poco conocido de "Index Sorting" en Elasticsearch

En Elasticsearch 6.0, lanzamos una nueva característica llamada clasificación de índices ("Index Sorting"). Si bien podrán encontrar más información en el blog del enlace, lo que esta característica hace, en pocas palabras, es tomar los documentos al momento de la indexación y clasificarlos mediante una clave o un conjunto de claves en el orden que elijan. Esto tiene algunas ventajas que hemos analizado:

  • Si solicitan a Elasticsearch que proporcione un conjunto de resultados clasificados con la misma clave con la que ordenaron un índice, la herramienta no necesitará hacer la clasificación de resultados al momento de la búsqueda. ¡Estarán previamente clasificados!
  • Si no necesitan el recuento total de resultados y hacen la clasificación con la clave, Elasticsearch puede anular la búsqueda una vez que encuentre suficientes resultados para cumplir con sus solicitudes. Esto puede generar mejoras ilimitadas en el rendimiento de las búsquedas.
  • Si tienen solicitudes que usan AND en diferentes campos, la clasificación de índices en estos campos puede agruparlos de modo tal que Elasticsearch podría omitir bloques grandes de documentos que no coincidan, lo que también podría agilizar la búsqueda.

En pocas palabras, la clasificación de índices puede agilizar la búsqueda en muchos casos; en particular, en aquellos en los que las personas tienen algunos métodos comunes para hacer búsquedas en sus documentos y clasificarlos. Con frecuencia no se menciona que la clasificación de índices también puede reducir el espacio en disco que ocupan sus índices. En este artículo diré por qué y cómo.

Precaución: La clasificación de índices no es para cualquiera

Antes de contar lo que sucede, quiero mencionar una vez más que la clasificación de índices no es para cualquiera. Hace que la acción de clasificación tenga lugar al momento de la indexación. La clasificación es una operación exigente; por ello, si la velocidad de indexación es un aspecto primordial, tomen precaución antes de activarla. Puede reducir el rendimiento de escritura entre un 40 y un 50 %. Por ello, si el resultado de indexación es un aspecto fundamental, algo que con frecuencia sucede en casos de uso de logging, métricas y analítica de seguridad de alto volumen, la clasificación de índices probablemente no sea para ustedes. Puede resultar útil si sus tasas de indexación son inferiores, si la velocidad es el aspecto más importante para sus casos de uso o si, de todos modos, cuentan con un proceso de reindexación regular que funcione durante períodos de indexación con menor demanda.

Análisis de posibles órdenes de clasificación: Ejemplo

Supongamos que ejecuto una instancia de Elasticsearch que se usan para la búsqueda de productos. Imaginen que dispongo de un conjunto de documentos que, al momento de la indexación, buscan algo como lo siguiente (aplicaré una reducción a una matriz para facilitar la visualización):

ID de productoCategoría de productoProduct ColorPrecio
206f467b-8cfe Zapatos Rojo $97.00
4f89fbec-acc3 Chaquetas Negro $120.50
47771396-dfe3 Chaquetas Gris $170.10
c6c8fbdf-651b Sombreros Amarillo $15.00
dc18c426-0eb3 Zapatos Rojo $107.20
ee304259-df57 Chaquetas Negro $88.00
9332c0ac-e55e Zapatos Negro $49.00
30e96765-52a1 Sombreros Azul $11.00
811cc8ca-d6bb Chaquetas Azul $92.99

Ahora supongamos que deseamos habilitar la clasificación de índices. ¿En qué basaríamos la clasificación? Tenemos algunas opciones; las de categoría de producto, color de producto o precio pueden resultar interesantes. Si las búsquedas de los usuarios casi siempre se clasifican por precio y no disponemos de filtros para categoría o color, la clasificación por precio puede ser la más lógica para una clave de clasificación. Sin embargo, es posible que los usuarios seleccionen al menos una categoría antes de encontrar el artículo más económico y que también prefieran un color. Apliquemos clasificaciones ascendentes por categoría, color y precio.

"sort.field" : ["product_category", "product_color", "price"], "sort.order" : ["asc", "asc", "asc"]

El índice clasificado tiene el siguiente aspecto:

ID de productoCategoría de productoProduct ColorPrecio
30e96765-52a1 Sombreros Azul $11.00
c6c8fbdf-651b Sombreros Amarillo $15.00
ee304259-df57 Chaquetas Negro $88.00
4f89fbec-acc3 Chaquetas Negro $120.50
811cc8ca-d6bb Chaquetas Azul $92.99
47771396-dfe3 Chaquetas Gris $170.10
9332c0ac-e55e Zapatos Negro $49.00
206f467b-8cfe Zapatos Rojo $97.00
dc18c426-0eb3 Zapatos Rojo $107.20

Suceden algunas cosas que explicaré con ejemplos:

  • Si solicito a Elasticsearch los 2 zapatos principales clasificados por precio en lugar de un recuento total de resultados de todos los zapatos, debe encontrar el bloque de zapatos, algo que puede hacer de manera eficaz omitiendo todas las demás categorías. Una vez que encuentre 2 resultados, podrá dejar de procesar el resto del índice y regresar. Tengan en cuenta que para que esto funcione, deben incluir cada elemento del orden de clasificación en el índice, aun cuando cuenten con filtros que coincidan.
  • Si envío a Elasticsearch la solicitud product_category:Jackets AND product_color:Black, puede omitir todos los sombreros y zapatos y, dentro de “Chaquetas”, encontrar las de color “Negro”. Una vez que esta búsqueda finaliza, puede omitir todos los demás colores de manera eficaz.
  • Elasticsearch usa un tipo de compresión que pasa considerablemente inadvertido. Esta funciona cuando hay valores repetidos y alcanza la mayor eficacia cuando los valores repetidos se encuentran cerca uno de otro en el índice. Al estar cerca uno de otro, todos los valores de “Chaquetas” o “Colores” pueden comprimirse de manera eficaz en el disco. Eso implica un menor espacio en disco, pero también significa que el sistema operativo podrá disponer de un mayor volumen en la caché del sistema de archivos, lo que aumentará aún más la velocidad.

En general, la práctica más recomendable consiste en usar órdenes de clasificación con cardinalidad creciente para poder aprovechar el beneficio de contar con la mayor cantidad posible de valores repetidos.

¿Cuánto espacio en disco ahorraré?

¿Cuánto espacio en disco ahorrarán al activar la clasificación de índices? Como sucede en muchos casos en la vida, la respuesta es: “Depende”. Uno de los principales aspectos que marcan esta dependencia es la cardinalidad del campo que usen para la clasificación. Sin embargo, el ahorro de espacio en disco puede ser notable. El fin de semana pasado, decidí mover de una máquina vieja a una nueva datos de automatización de IoT y del hogar que he usado para un proyecto personal. Hay maneras más rápidas de hacer esta migración de datos con snapshots o restauraciones, pero tuve tiempo para hacer una reindexación y captó mi interés el nivel de ahorro que puede ofrecer la clasificación de índices. Primero apliqué la reindexación remota en un índice no clasificado:

status    index           pri    docs.count    docs.deleted    pri.store.size 
open      devices-2017    1      33310674      0               4.2gb

Se trata de un poco más de 30 dispositivos y cada uno envía su estado aproximadamente una vez cada 30 segundos, de modo que la tasa de indexación total ronda la cifra de 1 documento por segundo. Nunca me encuentro cerca de lograr la regulación de la indexación. Además, tendría que aumentar enormemente la tasa de indexación o el número de dispositivos para que eso cambie. El caso parece ameritar clasificación de índices. Los datos contienen ID y nombres de hardware, horas y varias lecturas de sensores que indican, por ejemplo, la temperatura o si el dispositivo se encuentra activo o no a la hora en cuestión, o bien el nivel de algún otro sensor. Clasifiqué el índice por ID de dispositivo y luego por hora; consideré la posibilidad de que para un dispositivo determinado existe una probabilidad razonablemente alta de que haya valores similares o iguales a la misma hora, lo que puede mejorar la compresión. Por ejemplo, si un modificador pasa a un estado “on” a las 7:00:00, hay altas probabilidades de que su estado sea “on” a las 7:00:30 y las 7:01:00, y al menos varios minutos después, y la compresión debería ser buena. Las estadísticas del índice clasificado muestran lo siguiente…

status    index           pri    docs.count     docs.deleted    pri.store.size
open      devices-2017    1      3310674        0               2.5gb

¡Aproximadamente un 40 % de ahorro de espacio en disco!

Una vez más, precaución

En este punto, siento la obligación de prevenir nuevamente al lector, ya que a cualquiera le resultaría conveniente disponer de un 40 % más de espacio en disco con el mismo volumen de datos. Lo resumiré en dos afirmaciones breves:

  • Las cifras variarán. Usé la clasificación de índices en otro conjunto de datos y obtuve un ahorro del 20 %. Analicen con cuidado los campos en los que aplicarán la clasificación.
  • Tu tasa de indexación perderá velocidad. Si la velocidad de indexación les parece muy importante (p. ej., en sus casos de uso el volumen de logging o métricas es alto), probablemente sea para ustedes un aspecto sensible el número de documentos que se puedan indexar en poco tiempo y, como resultado, no sea una buena opción activar la clasificación de índices.

Si consideran que el espacio en disco es mucho más importante que la velocidad de indexación o si sus volúmenes de indexación son suficientemente reducidos como para que la velocidad de indexación no les presente una limitación, podría interesarles contemplar la viabilidad de la clasificación de índices.