Searchable Snapshots

En este blog vamos a tratar sobre los snapshots buscables, y como éstos transforman el modo de almacenar los datos y buscar en ellos. Al realizar la búsqueda de datos en copias de seguridad almacenadas en AWS S3, Microsoft Azure Storage y Google Cloud Storage, se reduce en gran medida el coste total de infraestructura. Vamos a ver cómo se consigue.

Elasticsearch y Lucene

Las principales características que definen a Elasticsearch son las siguientes:

  • Es un motor de búsqueda y analítica distribuido, gratuito y abierto para todos los tipos de datos, incluidos textuales, numéricos, geoespaciales, estructurados y no estructurados.
  • Está desarrollado a partir de Apache Lucene y es conocido por sus API REST simples, de naturaleza distribuida, veloces y escalables. 
  • Es el componente principal del  Elastic Stack, un conjunto de herramientas gratuitas y abiertas para la ingesta, el enriquecimiento, el almacenamiento, el análisis y la visualización de datos. Ahora también incluye una gran colección de agentes ligeros para enviar los datos.

El core de Elasticsearch es la biblioteca Apache Lucene, que incluye funciones para indexar, buscar, recuperar, actualizar documentos y análisis de texto. Sus principales características:

  • Una biblioteca de motores de búsqueda escrita en Java
  • Un proyecto Apache de alto nivel, a partir de 2005
  • Adecuado para aplicaciones que requieran búsqueda estructurada, búsqueda de texto completo, facetas, búsqueda del vecino más cercano en vectores de alta dimensionalidad, corrección ortográfica o sugerencias de consulta.
  • Apache Lucene es de código abierto disponible para descarga gratuita
  • Elasticsearch nace con el objetivo de simplificar la integración de la búsqueda en cualquier aplicación Java. El motor de búsqueda RESTful, distribuido y de código abierto se basa en Lucene.

Estructura de un índice

La estructura de datos en Elasticsearch se divide de la siguiente manera:

  • Un documento se indexa en un índice.

    Ejemplo de la creación de un índice a través de la API:

				
					curl -X POST "localhost:9200/my_blogs/_doc" -H 'Content-Type: application/json' -d
'{
  "title": "Fighting Ebola with Elastic",
  "category": "User Stories",
  "author": {
    "first_name": "Emily",
    "last_name": "Mosher"
  }
}'

				
			
  • Un índice es una manera lógica de agrupar datos, se puede pensar también como una colección de documentos optimizada. Cada documento es una colección de campos, dentro de estos campos se encuentran los datos. Estos campos se almacenan de forma clave-valor.
  • Elasticsearch almacena sus datos utilizando una estructura de datos llamada índice invertido. Éste numera cada palabra única que aparece en cualquier documento e identifica todos los documentos en los que aparece cada palabra.
Los índices alfabéticos siguen una estructura similar a los índices invertidos.
  • Los datos de Elasticsearch se almacenan a través de Lucene, que tiene un conjunto de índices invertidos en un compuesto de archivos llamados segmentos.
  • Los segmentos son índices independientes de Lucene.
  • Múltiples segmentos conforman un *shard.
  • Un shard es una fracción de un índice de Elasticsearch.

 

*Shard: Son muchos segmentos juntos. Lo que hace un segmento, se define en el punto anterior. Cada punto añade una capa más de definición.

Snapshot

Aunque la replicación puede proteger un clúster de los fallos de hardware, no puede ayudar cuando alguien elimina accidentalmente un índice. Por lo tanto, un clúster de Elasticsearch necesita realizar copias de seguridad periódicas.

Cada snapshot se deduplica automáticamente para ahorrar espacio de almacenamiento y reducir los costes de transferencia de red. Eso significa que, al hacer una copia de seguridad, se copian los segmentos del índice y se almacenan en el repositorio de snapshots. Dado que los segmentos son inmutables, el snapshot sólo necesita copiar cualquier segmento nuevo creado desde el último repositorio.

Ejemplo de lo que podría contener cada bloque:

				
					{
  "name" : "snapshot_1",
  "index-version" : 5,
  "files" : [ {
    "name" : "__0",
    "physical_name" : "_0.cfs",
    "length" : 8037,
    "checksum" : "trhzg",
    "part_size" : 104857600
  }, {
    "name" : "__1",
    "physical_name" : "_0.cfe",
    "length" : 314,
    "checksum" : "14i5z7r",
    "part_size" : 104857600
  }, {
    "name" : "__2",
    "physical_name" : "_0.si",
    "length" : 270,
    "checksum" : "19azdai",
    "part_size" : 104857600
  }, {
    "name" : "__3",
    "physical_name" : "segments_5",
    "length" : 107,
    "part_size" : 104857600
  } ]
}

				
			
				
					{
  "name" : "snapshot_2",
  "index-version" : 6,
  "files" : [ {
    "name" : "__0",
    "physical_name" : "_0.cfs",
    "length" : 8037,
    "checksum" : "trhzg",
    "part_size" : 104857600
  }, {
    "name" : "__1",
    "physical_name" : "_0.cfe",
    "length" : 314,
    "checksum" : "14i5z7r",
    "part_size" : 104857600
  }, {
    "name" : "__2",
    "physical_name" : "_0.si",
    "length" : 270,
    "checksum" : "19azdai",
    "part_size" : 104857600
  }, {
    "name" : "__4",
    "physical_name" : "segments_6",
    "length" : 107,
    "part_size" : 104857600
  } ]
}

				
			

Podemos observar que la información importante está en los bloques bajo los nombres “segments_*”. Se definen como:

NombreExtensiónDescripción
Segments Filesegments.gen, segments_NAlmacena información sobre un punto de commit. Los segmentos activos en el índice se almacenan en el archivo de información de segmento, segments_N.
Compound File.cfs, .cfeUn archivo "virtual" opcional que consta de todos los demás archivos de índice para sistemas que con frecuencia se quedan sin identificadores de archivos.

Data Tiers

Con el objetivo de optimizar los costes y el rendimiento de un cluster, Elasticsearch define los “data tiers” o niveles de datos. Estas definiciones permiten que un nodo de datos tenga un comportamiento específico, a través de la asignación de un rol, en vez de conseguir ese comportamiento a través de atributos y parámetros de configuración.

Antigua configuración:

				
					# En nodo hot 
node.attr.node_type: hot

# En nodo warm
node.attr.node_type: warm 

# En nodo cold
node.attr.node_type: cold

				
			
				
					PUT /myindex 
{ 
  "settings": { 
    "index.routing.allocation.include.node_type": "hot" 
  } 
}

				
			

Ahora directamente:

				
					#../elasticsearch.yml
node.roles: ["data_hot", "data_content","ingest", "ml"]

				
			

Esta funcionalidad es especialmente interesante para aquellos casos de uso en los que se debe gestionar un contenido de crecimiento rápido, como puede ser almacenamiento de catálogos o bien logs ingestados a diario.

La optimización se basa en la frecuencia de búsqueda de los datos:

HOT TIER

  • datos recientes

  • información muy relevante sobre la que se busca
    constantemente

  •  más cara

  •  mejor rendimiento

  • disco rápido

WARM TIER

  • precio medio

  • datos de las últimas semanas

  • información algo relevante

  • se realizan búsquedas ocasionalmente

 

COLD TIER

  • más barato

  • datos de meses recientes

  • no muy relevante

  • raramente se realizan búsquedas



FROZEN

  • muy barato, casi nulo

  • datos de años recientes

  • datos irrelevantes (para cuando pregunta el abogado)

 



Con estos niveles se observa el ciclo de vida de los datos. Cuando los datos se ingestan por primera vez, es probable que se realicen muchas búsquedas en ellos. Cuando se investiga un incidente, por ejemplo, se necesita acceso rápido a todos los datos relevantes para identificar y resolver el problema. Cuando un atacante compromete un host o una aplicación, la capacidad de responder con rapidez suele determinar el impacto de la vulneración.

Los datos también se pueden categorizar en diferentes niveles de uso según la fuente o el tipo. Es posible que algunos datos sólo sean necesarios por motivos legales o de cumplimiento, o para mirar retrospectivamente de forma ocasional para una comparación.

Por lo tanto, los usuarios necesitan diferentes niveles de potencia de procesamiento y almacenamiento para estos distintos niveles de necesidades, ya sea que se basen en la antigüedad, la fuente de los datos u otros criterios:

Lo que nos proporcionan los niveles de datos es:

  • Se gestionan textos y series temporales de manera simplificada.
  • Pasamos de configurar atributos del nodo a usar roles de nodos.
  • Elastic automáticamente gestiona la asignación y reubicación de los datos entre los niveles en la fase que toca.

Searchable Snapshots

Tras ver los diferentes “data tiers” para la gestión de ciclo de vida de los datos, nos vamos a centrar en los niveles “cold” y “frozen”. El nivel frío, impulsado por snapshots buscables, puede reducir costos de almacenamiento hasta en un 50%, aumentando la densidad de almacenamiento local de los datos de solo lectura a través de la descarga de la copia redundante de los datos a un almacén de objetos de bajo costo.

El nivel congelado, almacena los datos exclusivamente en el almacén de objetos de bajo costo al mismo tiempo que mantiene la capacidad de realizar búsquedas en ellos, con la caché local para búsquedas rápidas en datos a los que se accede con frecuencia.

La parte hot/warm en la que el disco tiene nuestros índices cortados en shards primarios y réplicas. Esta copia existe para cuando hay un problema en este shard, se pueda continuar indexandoy buscando datos, dando resiliencia al cluster.

En la parte cold tendremos los shards primarios en nuestro nodo y la réplica en s3, esta es un snapshot. En caso de problemas, se podrán reindexar de nuevo los datos. En esta parte cold, las réplicas ya no existen. Los datos se descargan y persisten localmente. En el tema de resiliencia, Elastic recupera desde snapshot cuando es necesario. Se reducen costes sin impactar realmente en cuestión de rendimiento, el almacenamiento se reduce a la mitad.

El tipo de dato que tenemos en este nivel no debe variar, no hay indexaciones nuevas ni modificaciones.

En la parte frozen, el snapshot está almacenado directamente en el cloud. Se trata de datos muy viejos que no buscamos frecuentemente, por lo tanto, queremos almacenar prácticamente todos nuestros datos en s3. Cuando queramos consultar un dato que se encuentre en este nivel, recuperaremos directamente de la copia.

¿Vale la pena restaurar todo un índice para luego ver que no tiene la información que queremos?

Nos interesamos en los datos que hay en Lucene (Meta Lookup, Doc Values, Stored Fields, Term Dictionary, Term Proximity, Normalization Factors, Point Values). Son los datos realmente indexados en los shards y que nos permiten realizar las peticiones de búsqueda/agregación.

 

Estos datos que están almacenados en los índices Lucene, hay diferentes tipos, algunos usados para efectuar búsquedas en periodos de tiempo, otros para búsquedas por palabra clave, otros para guardar el origen del dato, etc.

El equipo de Elastic decide optimizar el formato de los datos de Lucene y simplificar la estructura de este fichero, ya que no hay necesidad de acceder a los grandes documentos para realizar según qué tipo de petición.

No es necesario acceder a todos los documentos del snapshot, sólo a aquellos necesarios para realizar la búsqueda. Por lo tanto, se reducen los documentos a descargar a la hora de la consulta.

Tendremos shards que permitirán acceder a snapshots que han sido realizados, interrogar al shard, sabiendo que los datos importantes estarán en el nodo. Se restaurarán para la búsqueda. Esta es la base de la inteligencia del Searchable Snapshot y así recuperar datos a demanda, a través de un sistema de caché.

Por lo tanto los frozen searchable snapshots (ss):

  • un index snapshot que se parece a un índice regular.
  • las búsquedas se descargan sólo los datos necesarios
  • un caché persistente para que snapshots buscados recientemente busquen como si fuesen locales
  • los costes son como básicamente pagar el s3 únicamente

ILM y Mount API

La gestión de ciclo de vida del índice (ILM) proporciona algunas convenciones para facilitar la gestión de datos en nodos calientes (máquinas rápidas con SSD) y tibios/cálidos (máquinas de menor costo que pueden tener discos giratorios). La gestión de ciclo de vida de snapshots (SLM) facilita aún más el uso de almacenes de objetos de bajo costo de AWS, Google, Azure y proveedores de almacenamiento en las instalaciones para realizar y almacenar backups.

Para su creación, se debe inicializar el repositorio mediante:

				
					POST /_snapshot/<repository>/<snapshot>/_mount
				
			

Ejemplo:

  1. El nombre del índice en snapshot para montar
  2. El nombre del índice a crear.
  3. Cualquier configuración de índice para agregar al nuevo índice
  4. Lista de configuraciones de índice para ignorar al montar el índice instantáneo

Conclusión

Los searchable snapshots permiten usar las copias de seguridad para buscar datos a los que se acceden con poca frecuencia y de solo lectura de una manera muy rentable. Los niveles de datos fríos y congelados utilizan instantáneas que permiten realizar búsquedas para reducir los costos operativos y de almacenamiento. Estas se pueden realizar eliminando la necesidad de réplicas después de pasar del nivel activo, lo que podría reducir a la mitad el almacenamiento local necesario para buscar sus datos.

Irene Hernández Borrás
Imagen de Javier

Javier

¿Te ha resultado interesante?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Entradas relacionadas

Escalabilidad sin límites: El poder de Zabbix Proxy y su automatización dentro del ecosistema IOMETRICS® Observability

IA: ¿Ser agente o no ser? Esa no siempre es la pregunta.

Evento anual de clientes: innovación, Agentes Autónomos y alta cocina

¿Quieres saber más?