Capítulo 1. Introducción a Apache Iceberg

Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com

Los datos son un activo primario del que las organizaciones extraen la información y los conocimientos necesarios para tomar decisiones empresariales críticas. Tanto si se utilizan para analizar las tendencias de las ventas anuales de un determinado producto como para predecir futuras oportunidades de mercado, los datos marcan la dirección que deben seguir las organizaciones para tener éxito. Además, hoy en día los datos no son sólo algo que se puede tener. Es un requisito, no sólo para ganar en el mercado, sino para competir en él. Con una demanda tan masiva de información, se ha hecho un enorme esfuerzo por acumular los datos generados por los diversos sistemas de una organización para obtener información.

Al mismo tiempo, el ritmo al que los sistemas operativos y analíticos han ido generando datos se ha disparado. Aunque más datos han brindado a las empresas la oportunidad de tomar decisiones mejor informadas, también hay una necesidad imperiosa de disponer de una plataforma que almacene y analice todos estos datos, de modo que puedan utilizarse para crear productos analíticos, como informes de inteligencia empresarial (BI) y modelos de aprendizaje automático (ML), para apoyar la toma de decisiones. La arquitectura Lakehouse, que desarrollaremos en este capítulo, desvincula cómo almacenamos nuestros datos de cómo los procesamos para obtener más flexibilidad. Este capítulo te guiará a través de la historia y la evolución de las plataformas de datos desde un punto de vista práctico y te presentará las ventajas de una arquitectura lakehouse con los formatos de tablas abiertas de Apache Iceberg.

¿Cómo hemos llegado hasta aquí? Breve historia

En términos de almacenamiento y sistemas de procesamiento, los sistemas de gestión de bases de datos relacionales (RDBMS) han sido durante mucho tiempo una opción estándar para que las organizaciones mantengan un registro de todos sus datos transaccionales. Por ejemplo, supongamos que diriges una empresa de transportes y quieres mantener información sobre las nuevas reservas realizadas por tus clientes. En este caso, cada nueva reserva sería una nueva fila en un RDBMS. Los RDBMS utilizados para este fin admiten una categoría específica de procesamiento de datos denominada procesamiento de transacciones en línea (OLTP) . Ejemplos de SGBDR optimizados para OLTP son PostgreSQL, MySQL y Microsoft SQL Server. Estos sistemas están diseñados y optimizados para permitirte interactuar muy rápidamente con una o unas pocas filas de datos a la vez y son una buena opción para dar soporte a las operaciones cotidianas de una empresa.

Pero supongamos que quisieras conocer el beneficio medio que obtuviste con todas tus nuevas reservas del trimestre anterior. En ese caso, utilizar los datos almacenados en un RDBMS optimizado para OLTP habría provocado importantes problemas de rendimiento una vez que tus datos fueran lo suficientemente grandes. Algunas de las razones son las siguientes:

  • Los sistemas transaccionales de se centran en insertar, actualizar y leer un pequeño subconjunto de filas de una tabla, por lo que almacenar los datos en un formato basado en filas es lo ideal. Sin embargo, los sistemas analíticos suelen centrarse en agregar determinadas columnas o trabajar con todas las filas de una tabla, por lo que resulta más ventajosa una estructura columnar.

  • Ejecutar cargas de trabajo transaccionales y analíticas en la misma infraestructura puede dar lugar a una competición por los recursos.

  • Las cargas de trabajo transaccionales se benefician de la normalización de los datos en varias tablas relacionadas que se unen si es necesario, mientras que las cargas de trabajo analíticas pueden rendir mejor cuando los datos se desnormalizan en la misma tabla para evitar operaciones de unión a gran escala.

Ahora imagina que tu organización tuviera un gran número de sistemas operativos que generaran una enorme cantidad de datos y tu equipo de análisis quisiera construir cuadros de mando que se basaran en agregaciones de los datos de estas diferentes fuentes de datos (es decir, bases de datos de aplicaciones). Por desgracia, los sistemas OLTP no están diseñados para tratar consultas agregadas complejas que impliquen un gran número de registros históricos. Estas cargas de trabajo se conocen como cargas de trabajo de procesamiento analítico en línea (OLAP). Para hacer frente a esta limitación, se necesitaría otro tipo de sistema optimizado para cargas de trabajo OLAP. Fue esta necesidad la que impulsó el desarrollo de la arquitectura lakehouse.

Componentes básicos de un sistema diseñado para cargas de trabajo OLAP

Un sistema diseñado para cargas de trabajo OLAP se compone de un conjunto de componentes tecnológicos que permiten soportar las cargas de trabajo analíticas actuales, como se muestra en la Figura 1-1 y se describe en los siguientes subapartados.

Figura 1-1. Componentes técnicos que soportan las cargas de trabajo analíticas

Almacenamiento

Para analizar datos históricos procedentes de diversas fuentes, necesitas disponer de un sistema que te permita almacenar cantidades de datos de grandes a significativas. Por tanto, el almacenamiento es el primer componente que necesitarías en un sistema que pueda hacer frente a consultas analíticas sobre grandes conjuntos de datos. Hay muchas opciones para el almacenamiento, incluido un sistema de archivos local en almacenamiento de conexión directa (DAS) ; un sistema de archivos distribuido en un conjunto de nodos que tú manejas, como el Sistema de Archivos Distribuidos Hadoop (HDFS); y almacenamiento de objetos proporcionado como servicio por proveedores en la nube, como Amazon Simple Storage Service (Amazon S3).

En cuanto a los tipos de almacenamiento, puedes utilizar bases de datos orientadas a filas o bases de datos columnares, o puedes mezclar ambas en algunos sistemas. En los últimos años, las bases de datos columnares han disfrutado de una enorme adopción, ya que han demostrado ser más eficientes cuando se trata de grandes volúmenes de datos.

Formato de archivo

A efectos de almacenamiento, tus datos brutos deben organizarse en un formato de archivo concreto. La elección del formato de archivo influye en aspectos como la compresión de los archivos, la estructura de los datos y el rendimiento de una determinada carga de trabajo.

Los formatos de archivo suelen clasificarse en tres categorías de alto nivel: estructurados (CSV), semiestructurados (JSON) y no estructurados (archivos de texto) . En las categorías estructurado y semiestructurado, los formatos de archivo pueden estar orientados a filas u orientados a columnas (columnar). Los formatos de archivo orientados a filas almacenan juntas todas las columnas de una fila determinada, mientras que los formatos de archivo orientados a columnas almacenan juntas todas las filas de una columna determinada. Dos ejemplos comunes de formatos de archivo orientados a filas son los valores separados por comas (CSV) y Apache Avro. Ejemplos de formatos de archivo orientados a columnas son Apache Parquet y Apache ORC.

Según el caso de uso, determinados formatos de archivo pueden ser más ventajosos que otros. Por ejemplo, los formatos de archivo orientados a filas suelen ser mejores si tratas con un pequeño número de registros a la vez. En cambio, los formatos de archivo en columnas suelen ser mejores si tratas con un número considerable de registros a la vez.

Formato de la tabla

El formato de tabla es otro componente crítico para un sistema que pueda soportar cargas de trabajo analíticas con consultas agregadas sobre un gran volumen de datos. El formato de tabla actúa como una capa de metadatos sobre el formato de archivo y se encarga de especificar cómo deben disponerse los archivos de datos en el almacenamiento.

En última instancia, el objetivo de un formato de tabla es abstraer la complejidad de la estructura física de los datos y facilitar capacidades como las operaciones del Lenguaje de Manipulación de Datos (DML) (por ejemplo, hacer inserciones, actualizaciones y eliminaciones) y cambiar el esquema de una tabla. Los formatos de tabla modernos también aportan las garantías de atomicidad y consistencia necesarias para la ejecución segura de las operaciones DML sobre los datos.

Motor de almacenamiento

El motor de almacenamiento es el sistema responsable de realizar realmente el trabajo de disponer los datos en la forma especificada por el formato de tabla y de mantener todos los archivos y estructuras de datos actualizados con los nuevos datos. Los motores de almacenamiento se encargan de algunas de las tareas críticas, como la optimización física de los datos, el mantenimiento de los índices y la eliminación de los datos antiguos.

Catálogo

Cuando tratas con datos de diversas fuentes y a gran escala, es importante identificar rápidamente los datos que podrías necesitar para tu análisis. La función de un catálogo es abordar este problema aprovechando los metadatos para identificar los conjuntos de datos. El catálogo es la ubicación central a la que pueden acudir los motores de cálculo y los usuarios para averiguar la existencia de una tabla, así como información adicional como el nombre de la tabla, el esquema de la tabla y dónde se almacenan los datos de la tabla en el sistema de almacenamiento. Algunos catálogos son internos a un sistema y sólo se puede interactuar directamente con ellos a través del motor de ese sistema; ejemplos de estos catálogos son Postgres y Snowflake. Otros catálogos, como Hive y Project Nessie, están abiertos para que los utilice cualquier sistema. Ten en cuenta que estos catálogos de metadatos no son lo mismo que los catálogos para el descubrimiento humano de datos, como Colibra, Atlan y el catálogo interno de Dremio Software.

Motor de cálculo

El motor de cálculo es el componente final necesario para tratar eficazmente una cantidad masiva de datos persistentes en un sistema de almacenamiento. El papel de un motor de cálculo en un sistema de este tipo sería ejecutar cargas de trabajo de usuario para procesar los datos. Según el volumen de datos, la carga de cálculo y el tipo de carga de trabajo, puedes utilizar uno o varios motores de cálculo para esta tarea. Cuando se trata de un gran conjunto de datos y/o grandes requisitos de cálculo, puede que necesites utilizar un motor de cálculo distribuido en un paradigma de procesamiento denominado procesamiento paralelo masivo (MPP) . Algunos ejemplos de motores de cálculo basados en MPP son Apache Spark, Snowflake y Dremio.

Reunirlo todo

Tradicionalmente, para las cargas de trabajo OLAP, todos estos componentes técnicos se han acoplado estrechamente en un único sistema conocido como almacén de datos. Los almacenes de datos permiten a las organizaciones almacenar datos procedentes de diversas fuentes y ejecutar cargas de trabajo analíticas sobre los datos. En la siguiente sección, analizaremos en detalle las capacidades de un almacén de datos, cómo se integran los componentes técnicos y los pros y los contras de utilizar un sistema de este tipo .

El almacén de datos

Un almacén de datos o base de datos OLAP es un repositorio centralizado que admite el almacenamiento de grandes volúmenes de datos ingestados desde diversas fuentes, como sistemas operativos, bases de datos de aplicaciones y registros. La Figura 1-2 presenta una visión general de la arquitectura de los componentes técnicos de un almacén de datos.

Figura 1-2. Componentes técnicos de un almacén de datos

Un almacén de datos posee todos los componentes técnicos en un único sistema. En otras palabras, todos los datos se almacenan en sus propios formatos de archivos y tablas, en su propio sistema de almacenamiento. Estos datos son gestionados exclusivamente por el motor de almacenamiento del almacén de datos, se registran en su catálogo y sólo el usuario o los motores analíticos pueden acceder a ellos a través de su motor de cálculo.

Breve historia

Hasta aproximadamente 2015, la mayoría de los almacenes de datos tenían los componentes de almacenamiento y computación estrechamente acoplados en los mismos nodos, ya que la mayoría se diseñaban y ejecutaban in situ. Sin embargo, esto provocó muchos problemas. El escalado se convirtió en un gran problema porque los conjuntos de datos crecían en volumen a un ritmo acelerado, mientras que el número y la intensidad de las cargas de trabajo (es decir, las tareas de cálculo que se ejecutaban en el almacén) también aumentaban. Concretamente, no había forma de aumentar independientemente los recursos de cálculo y almacenamiento en función de tus tareas. Si tus necesidades de almacenamiento crecían más rápidamente que tus necesidades de cálculo, no importaba. Seguías teniendo que pagar por el cálculo adicional aunque no lo necesitaras.

Esto llevó a que la siguiente generación de almacenes de datos se construyera con un gran enfoque en la nube. Estos almacenes de datos empezaron a ganar adeptos en torno a 2015, cuando irrumpió en escena la computación nativa en la nube, que te permitía separar los componentes de cálculo y almacenamiento y escalar estos recursos para adaptarlos a tus tareas. Incluso te permitían apagar la computación cuando no la utilizabas y no perder el almacenamiento.

Ventajas e inconvenientes de un almacén de datos

Aunque los almacenes de datos, ya sean locales o basados en la nube, facilitan a las empresas dar sentido rápidamente a todos sus datos históricos, hay ciertas áreas en las que un almacén sigue causando problemas. La Tabla 1-1 enumera los pros y los contras de un almacén de datos.

Tabla 1-1. Pros y contras de un almacén de datos
Pros Contras
Sirve como única fuente de verdad, ya que permite almacenar y consultar datos de varias fuentes Bloquea los datos en un sistema específico del proveedor que sólo puede utilizar el motor de cálculo del almacén
Admite la consulta de grandes cantidades de datos históricos, lo que permite ejecutar rápidamente cargas de trabajo analíticas Caro tanto en términos de almacenamiento como de cálculo; a medida que aumenta la carga de trabajo, el coste se hace difícil de gestionar
Proporciona políticas eficaces de gobernanza de datos para garantizar que los datos estén disponibles, sean utilizables y estén alineados con las políticas de seguridad Soporta principalmente datos estructurados
Organiza la disposición de los datos por ti, asegurándote de que está optimizada para la consulta No permite a las organizaciones ejecutar de forma nativa cargas de trabajo analíticas avanzadas como ML
Garantiza que los datos escritos en una tabla se ajustan al esquema técnico

Un almacén de datos actúa como un repositorio centralizado para que las organizaciones almacenen todos sus datos procedentes de multitud de fuentes, permitiendo a los consumidores de datos, como analistas e ingenieros de BI, acceder fácil y rápidamente a los datos desde una única fuente para iniciar sus análisis. Además, los componentes tecnológicos que potencian un almacén de datos te permiten acceder a grandes volúmenes de datos, al tiempo que soportan cargas de trabajo de BI para ejecutarse sobre ellos.

Aunque los almacenes de datos han sido elementales en la democratización de los datos y han permitido a las empresas obtener información histórica de diversas fuentes de datos, se limitan principalmente a cargas de trabajo relacionales. Por ejemplo, volviendo al ejemplo anterior de la empresa de transportes, supongamos que quieres obtener información sobre el volumen total de ventas del próximo trimestre. En este caso, necesitarías construir un modelo de previsión utilizando datos históricos. Sin embargo, no puedes conseguir esta capacidad de forma nativa con un almacén de datos, ya que el motor de cálculo y los demás componentes técnicos no están diseñados para tareas basadas en ML. Así que tu principal opción viable sería trasladar o exportar los datos del almacén a otras plataformas que admitan cargas de trabajo de ML. Esto significa que tendrías los datos en varias copias, y tener que crear canalizaciones para cada movimiento de datos puede dar lugar a problemas críticos como la deriva de los datos y la descomposición del modelo cuando las canalizaciones mueven los datos de forma incorrecta o incoherente.

Otro obstáculo para ejecutar cargas de trabajo analíticas avanzadas sobre un almacén de datos es que éste sólo admite datos estructurados. Pero la rápida generación y disponibilidad de otros tipos de datos, como los semiestructurados y los no estructurados (JSON, imágenes, texto, etc.), ha permitido que los modelos ML revelen perspectivas interesantes. Para nuestro ejemplo, podría tratarse de comprender los sentimientos de todas las nuevas revisiones de reservas realizadas en el trimestre anterior. En última instancia, esto repercutiría en la capacidad de una organización para tomar decisiones orientadas al futuro.

También hay retos de diseño específicos en un almacén de datos. Volviendo a la Figura 1-2, puedes ver que los seis componentes técnicos están estrechamente acoplados en un almacén de datos. Antes de que entiendas lo que esto implica, algo esencial que debes observar es que tanto el formato de los archivos como el de las tablas son internos a un almacén de datos concreto. Este patrón de diseño conduce a una forma cerrada de arquitectura de datos. Significa que sólo se puede acceder a los datos reales utilizando el motor de cálculo del almacén de datos, que está específicamente diseñado para interactuar con los formatos de tabla y archivo del almacén. Este tipo de arquitectura deja a las organizaciones con una enorme preocupación por los datos bloqueados. Con el aumento de las cargas de trabajo y los enormes volúmenes de datos que se ingieren en un almacén a lo largo del tiempo, estás atado a esa plataforma concreta. Y eso significa que tus cargas de trabajo analíticas, como BI y cualquier herramienta futura que planees incorporar, sólo pueden ejecutarse sobre este almacén de datos concreto. Esto también te impide migrar a otra plataforma de datos que pueda satisfacer específicamente tus necesidades.

Además, el almacenamiento de datos en un almacén de datos y el uso de los motores informáticos para procesarlos conllevan un importante factor de coste. Este coste aumenta con el tiempo, a medida que aumenta el número de cargas de trabajo en tu entorno, invocando así más recursos informáticos. Además de los costes monetarios, hay otros gastos generales, como la necesidad de que los equipos de ingeniería construyan y gestionen numerosos conductos para mover los datos desde los sistemas operativos, y el retraso en la obtención de información por parte de los consumidores de datos. Estos retos han impulsado a las organizaciones a buscar plataformas de datos alternativas que permitan que los datos estén bajo su control y se almacenen en formatos de archivo abiertos, permitiendo así que las aplicaciones posteriores, como BI y ML, se ejecuten en paralelo con costes muy reducidos. Esto condujo a la aparición de los lagos de datos.

El Lago de Datos

Aunque los almacenes de datos proporcionaban un mecanismo para ejecutar análisis sobre datos estructurados, seguían presentando varios problemas:

  • Un almacén de datos sólo podía almacenar datos estructurados.

  • El almacenamiento en un almacén de datos suele ser más caro que los clusters Hadoop on-prem o el almacenamiento de objetos en la nube.

  • El almacenamiento y la informática en los almacenes de datos tradicionales in situ suelen estar mezclados y, por tanto, no pueden escalarse por separado. Más costes de almacenamiento venían acompañados de más costes de cálculo, tanto si necesitabas la potencia de cálculo como si no.

Abordar estos problemas requería una solución de almacenamiento alternativa que fuera más barata y pudiera almacenar todos tus datos sin necesidad de ajustarse a un esquema fijo. Esta solución alternativa era el lago de datos.

Breve historia

Originalmente, se utilizaba Hadoop , un marco informático distribuido de código abierto, y su componente de sistema de archivos HDFS para almacenar y procesar grandes cantidades de conjuntos de datos estructurados y no estructurados a través de clusters de ordenadores de bajo coste. Pero no bastaba con poder almacenar todos estos datos. También querrías ejecutar análisis sobre ellos.

El ecosistema Hadoop incluía MapReduce, un marco analítico desde el que podías escribir trabajos analíticos en Java y ejecutarlos en el clúster Hadoop. Escribir trabajos MapReduce era prolijo y complejo, y muchos analistas se sienten más cómodos escribiendo SQL que Java, así que se creó Hive para convertir sentencias SQL en trabajos MapReduce.

Para escribir SQL, se necesitaba un mecanismo que permitiera distinguir qué archivos de tu almacenamiento forman parte de un conjunto de datos o tabla concretos. Esto dio lugar al nacimiento del formato de tabla Hive, que reconocía un directorio y los archivos que contenía como una tabla.

Con el tiempo, la gente dejó de utilizar los clusters de Hadoop para utilizar el almacenamiento de objetos en la nube (por ejemplo, Amazon S3, Minio, Azure Blob Storage), ya que era más fácil de gestionar y más barato de utilizar. MapReduce también dejó de utilizarse en favor de otros motores de consulta distribuida como Apache Spark, Presto y Dremio. Lo que sí se mantuvo fue el formato de tabla Hive, que se convirtió en el estándar del espacio para reconocer los archivos de tu almacenamiento como tablas singulares sobre las que puedes ejecutar análisis. Sin embargo, el almacenamiento en la nube requería más costes de red para acceder a esos archivos, algo que la arquitectura del formato Hive no había previsto y que provocaba un exceso de llamadas a la red debido a la dependencia de Hive de la estructura de carpetas de la tabla.

Una característica que distingue un lago de datos de un almacén de datos es la capacidad de aprovechar diferentes motores informáticos para diferentes cargas de trabajo. Esto es importante porque nunca ha existido un motor informático milagroso que sea el mejor para todas las cargas de trabajo y que pueda escalar la computación independientemente del almacenamiento. Esto es inherente a la naturaleza de la informática, ya que siempre hay compensaciones, y lo que decides compensar determina para qué es bueno un sistema determinado y para qué no es tan adecuado.

Ten en cuenta que en los lagos de datos, no existe realmente ningún servicio que satisfaga las necesidades de la función del motor de almacenamiento. Por lo general, el motor de cálculo decide cómo escribir los datos, y luego éstos no suelen revisarse ni optimizarse, a menos que se reescriban tablas o particiones enteras, lo que suele hacerse ad hoc. La Figura 1-3 muestra cómo interactúan entre sí los componentes de un lago de datos.

Figura 1-3. Componentes técnicos de un lago de datos

Ventajas e inconvenientes de un lago de datos

Por supuesto, ningún patrón arquitectónico es perfecto, y eso se aplica a los lagos de datos. Aunque los lagos de datos tienen muchas ventajas, también presentan varias limitaciones. Las ventajas son las siguientes:

Menor coste

Los costes de almacenar datos y ejecutar consultas en un lago de datos son mucho menores que en un almacén de datos. Esto hace que un lago de datos sea especialmente útil para permitir el análisis de datos cuya prioridad no es lo suficientemente alta como para justificar el coste de un almacén de datos, permitiendo un mayor alcance analítico.

Almacena datos en formatos abiertos

En un lago de datos, puedes almacenar los datos en cualquier formato de archivo que desees, mientras que en un almacén de datos, no tienes nada que decir sobre cómo se almacenan los datos, que normalmente sería un formato propietario construido para ese almacén de datos concreto. Esto te permite tener más control sobre los datos y consumirlos en una mayor variedad de herramientas compatibles con estos formatos abiertos.

Maneja datos no estructurados

Los almacenes de datos no pueden manejar datos no estructurados como datos de sensores, archivos adjuntos de correo electrónico y archivos de registro, por lo que si querías ejecutar análisis sobre datos no estructurados, el lago de datos era la única opción.

Estas son las limitaciones:

Rendimiento

Como cada componente de un lago de datos está desacoplado, faltan muchas de las optimizaciones que pueden existir en los sistemas estrechamente acoplados, como los índices y las garantías ACID (Atomicidad, Consistencia, Aislamiento, Durabilidad). Aunque pueden volver a crearse, requiere mucho esfuerzo e ingeniería ensamblar los componentes (almacenamiento, formato de archivo, formato de tabla, motores) de forma que se obtenga un rendimiento comparable al de un almacén de datos. Esto hacía que los lagos de datos no fueran deseables para el análisis de datos de alta prioridad, donde el rendimiento y el tiempo importaban.

Requiere mucha configuración

Como ya se ha dicho, crear un acoplamiento más estrecho de los componentes elegidos con el nivel de optimizaciones que cabría esperar de un almacén de datos requeriría una ingeniería considerable. Esto daría lugar a la necesidad de muchos ingenieros de datos para configurar todas estas herramientas, lo que también puede ser costoso.

Falta de transacciones ACID

Un inconveniente notable de los lagos de datos es la ausencia de garantías de transacción ACID incorporadas, habituales en las bases de datos relacionales tradicionales. En los lagos de datos, los datos se ingieren a menudo de forma de esquema en lectura, lo que significa que la validación del esquema y las comprobaciones de coherencia se producen durante el procesamiento de los datos y no en el momento de la ingestión. Esto puede suponer un reto para las aplicaciones que requieren una sólida integridad transaccional, como los sistemas financieros o las aplicaciones que manejan datos sensibles. Conseguir garantías transaccionales similares en un lago de datos suele implicar la implementación de complejos conductos de procesamiento de datos y mecanismos de coordinación, lo que aumenta el esfuerzo de ingeniería necesario para casos de uso críticos. Aunque los lagos de datos destacan por su escalabilidad y flexibilidad, pueden no ser la opción ideal cuando el cumplimiento estricto de ACID es un requisito primordial.

El Cuadro 1-2 resume estos pros y contras.

Tabla 1-2. Pros y contras de un lago de datos
Pros Contras
Menor coste
Almacena datos en formatos abiertos
Maneja datos no estructurados
Admite casos de uso de ML
Rendimiento
Falta de garantías ACID
Requiere mucha configuración

¿Debo ejecutar los análisis en un lago de datos o en un almacén de datos?

Aunque los lagos de datos proporcionaban un lugar estupendo para aterrizar todos tus datos estructurados y no estructurados, seguía habiendo imperfecciones. Después de ejecutar ETL (extraer, transformar y cargar) para aterrizar tus datos en tu lago de datos, generalmente tomarías una de dos vías al ejecutar los análisis.

Por ejemplo, podrías configurar una canalización ETL adicional para crear una copia de un subconjunto curado de datos destinados a análisis de alta prioridad y almacenarlo en el almacén para obtener el rendimiento y la flexibilidad del almacén de datos.

Sin embargo, esto da lugar a algunos problemas:

  • Costes adicionales en el cálculo para el trabajo ETL adicional y en el coste de almacenar una copia de los datos que ya estás almacenando en un almacén de datos, donde los costes de almacenamiento suelen ser mayores.

  • Copias adicionales de los datos, que pueden ser necesarias para rellenar los marts de datos de las distintas líneas de negocio, e incluso más copias, ya que los analistas crean copias físicas de subconjuntos de datos en forma de extractos de BI para acelerar los cuadros de mando, lo que conduce a una red de copias de datos difíciles de gobernar, rastrear y mantener sincronizadas.

Como alternativa, puedes utilizar motores de consulta que admitan cargas de trabajo de lago de datos, como Dremio, Presto, Apache Spark, Trino y Apache Impala, para ejecutar consultas en el lago de datos. Estos motores suelen ser adecuados para cargas de trabajo de sólo lectura. Sin embargo, debido a las limitaciones del formato de tabla Hive, se topan con la complejidad cuando intentan actualizar los datos de forma segura desde el lago de datos.

Como puedes ver, los lagos de datos y los almacenes de datos tienen sus propias ventajas y limitaciones. Esto ha hecho necesario desarrollar una nueva arquitectura que ofrezca sus ventajas minimizando sus defectos, y esa arquitectura se llama data lakehouse.

La Casa del Lago de Datos

Mientras que el uso de un almacén de datos nos proporcionaba rendimiento y facilidad de uso, la analítica en lagos de datos nos ofrecía costes más bajos, flexibilidad al utilizar formatos abiertos, la posibilidad de utilizar datos no estructurados y mucho más. El deseo de enhebrar la aguja conduce a grandes avances e innovaciones, que desembocan en lo que hoy conocemos como lago de datos.

La arquitectura data lakehouse desacopla el almacenamiento y el cálculo de los lagos de datos e introduce mecanismos que permiten una funcionalidad más parecida a la de un almacén de datos (transacciones ACID, mejor rendimiento, coherencia, etc.). Habilitan esta funcionalidad los formatos de tabla de los lagos de datos, que eliminan todos los problemas anteriores con el formato de tabla Hive. Almacenas los datos en los mismos lugares en los que los almacenarías con un lago de datos, utilizas los motores de consulta que utilizarías con un lago de datos, y tus datos se almacenan en los mismos formatos en los que se almacenarían en un lago de datos. Lo que realmente transforma tu mundo de datos "sólo de lectura" en un lago de datos "centro de mi mundo de datos" es el formato de tabla que proporciona una capa de metadatos/abstracción entre el motor y el almacenamiento para que interactúen de forma más inteligente (ver Figura 1-4).

Los formatos de tabla crean una capa de abstracción sobre el almacenamiento de archivos que permite mejorar la coherencia, el rendimiento y las garantías ACID cuando se trabaja con datos directamente en el almacenamiento del lago de datos, lo que da lugar a varias propuestas de valor:

Menos copias = menos deriva

Con las garantías ACID y un mejor rendimiento, ahora puedes trasladar las cargas de trabajo que normalmente se guardan para el almacén de datos -como las actualizaciones y otras manipulaciones de datos- al lago de datos para reducir los costes y el movimiento de datos. Si trasladas tus datos al lago de datos, puedes tener una arquitectura más racionalizada con menos copias. Menos copias significa menos costes de almacenamiento, menos costes de computación por trasladar los datos a un almacén de datos, menos deriva (el modelo de datos cambia/se rompe en diferentes versiones de los mismos datos), y una mejor gobernanza de tus datos para mantener el cumplimiento de la normativa y los controles internos.

Consultas más rápidas = información más rápida

El objetivo final es siempre obtener valor empresarial mediante perspectivas de calidad a partir de nuestros datos. Todo lo demás no son más que pasos hacia ese fin. Si puedes hacer consultas más rápidas, eso significa que puedes obtener información más rápidamente. Los almacenes de lagos de datos permiten realizar consultas más rápidas que los lagos de datos y almacenes de datos comparables mediante optimizaciones en el motor de consulta (optimizadores basados en costes, almacenamiento en caché), el formato de las tablas (mejor omisión de archivos y planificación de consultas mediante metadatos) y el formato de los archivos (ordenación y compresión).

Instantáneas de datos históricos = errores que no hacen daño

Los formatos de tablas de Data lakehouse mantienen instantáneas de datos históricos, permitiendo la posibilidad de consultar y restaurar tablas a sus instantáneas anteriores. Puedes trabajar con tus datos y no tener que pasar la noche en vela preguntándote si un error te llevará horas de auditoría, reparación y posterior relleno.

Arquitectura asequible = valor empresarial

Hay dos formas de aumentar los beneficios: aumentar los ingresos y disminuir los costes. Y los lagos de datos no sólo te ayudan a obtener información empresarial para aumentar los ingresos, sino que también pueden ayudarte a disminuir los costes. Esto significa que puedes reducir los costes de almacenamiento evitando la duplicación de tus datos, evitar costes adicionales de computación por el trabajo adicional de ETL para mover los datos, y disfrutar de precios más bajos por el almacenamiento y la computación que estás utilizando en relación con las tarifas típicas de los almacenes de datos.

Arquitectura abierta = tranquilidad

Los lagos de datos se construyen sobre formatos abiertos, como Apache Iceberg como formato de tabla y Apache Parquet como formato de archivo. Muchas herramientas pueden leer y escribir en estos formatos, lo que te permite evitar la dependencia del proveedor. La dependencia de un proveedor provoca un aumento de los costes y el bloqueo de las herramientas, ya que tus datos se almacenan en formatos a los que las herramientas no pueden acceder. Al utilizar formatos abiertos, puedes estar tranquilo, sabiendo que tus datos no quedarán aislados en un estrecho conjunto de herramientas.

Figura 1-4. Componentes técnicos de un lago de datos

En resumen, con las modernas innovaciones de los estándares abiertos comentados anteriormente, puede existir lo mejor de todos los mundos operando estrictamente en el lago de datos, y este patrón arquitectónico es el data lakehouse. El componente clave que hace todo esto posible es el formato de tabla que permite a los motores tener las garantías y el rendimiento mejorado sobre los lagos de datos cuando trabajan con datos que antes simplemente no existían. Pasemos ahora a hablar del formato de tabla Apache Iceberg.

¿Qué es un formato de tabla?

Un formato de tabla es un método de estructurar los archivos de un conjunto de datos para presentarlos como una "tabla" unificada. Desde la perspectiva del usuario, puede definirse como la respuesta a la pregunta "¿qué datos hay en esta tabla?".

Esta sencilla respuesta permite que varias personas, equipos y herramientas interactúen simultáneamente con los datos de la tabla, tanto si leen de ella como si escriben en ella. El objetivo principal de un formato de tabla es proporcionar una abstracción de la tabla a los usuarios y herramientas, facilitándoles la interacción con los datos subyacentes de forma eficiente.

Los formatos de tabla existen desde los inicios de los RDBMS, como System R, Multics y Oracle, que implementaron por primera vez el modelo relacional de Edgar Codd, aunque en aquella época no se utilizaba el término formato de tabla. En estos sistemas, los usuarios podían referirse a un conjunto de datos como una tabla, y el motor de la base de datos se encargaba de gestionar la disposición en bytes del conjunto de datos en el disco en forma de archivos, a la vez que gestionaba complejidades como las transacciones.

Todas las interacciones con los datos en estos RDBMS, como la lectura y la escritura, son gestionadas por el motor de almacenamiento de la base de datos. Ningún otro motor puede interactuar directamente con los archivos sin arriesgarse a que se corrompa el sistema. Los detalles de cómo se almacenan los datos se abstraen, y los usuarios dan por sentado que la plataforma sabe dónde se encuentran los datos de una tabla concreta y cómo acceder a ellos.

Sin embargo, en el mundo actual de los grandes datos, confiar en un único motor cerrado para gestionar todo el acceso a los datos subyacentes ya no es práctico. Tus datos necesitan acceder a una variedad de motores de cálculo optimizados para diferentes casos de uso, como BI o ML.

En un lago de datos, todos tus datos se almacenan como archivos en alguna solución de almacenamiento (por ejemplo, Amazon S3, Azure Data Lake Storage [ADLS], Google Cloud Storage [GCS]), por lo que una sola tabla puede estar formada por docenas, cientos, miles o incluso millones de archivos individuales en ese almacenamiento. Cuando utilizamos SQL con nuestras herramientas analíticas favoritas o escribimos scripts ad hoc en lenguajes como Java, Scala, Python y Rust, no nos gustaría definir constantemente cuáles de estos archivos están en la tabla y cuáles no. Esto no sólo sería tedioso, sino que probablemente provocaría incoherencias en los distintos usos de los datos.

Así que la solución fue crear un método estándar para entender "qué datos hay en esta tabla" para los lagos de datos, como se ilustra en la Figura 1-5.

Figura 1-5. Archivos de datos organizados en tablas utilizando un formato de tabla

Colmena: El formato de tabla original

En el mundo de la ejecución de análisis en lagos de datos Hadoop, se utilizaba el marco MapReduce, que obligaba a los usuarios a escribir complejos y tediosos trabajos en Java, lo que no estaba al alcance de muchos analistas. Facebook, sintiendo el dolor de esta situación, desarrolló un marco llamado Hive en 2009. Hive proporcionó una ventaja clave para hacer mucho más fácil la analítica en Hadoop: la posibilidad de escribir SQL en lugar de trabajos MapReduce directamente.

El marco Hive tomaba las sentencias SQL y luego las convertía en trabajos MapReduce que podían ejecutarse. Para escribir sentencias SQL, tenía que haber un mecanismo para comprender qué datos de tu almacenamiento Hadoop representaban una tabla única, y así nacieron el formato de tabla Hive y Hive Metastore para rastrear estas tablas.

El formato de tabla Hive adoptó el enfoque de definir una tabla como todos y cada uno de los archivos dentro de un directorio especificado (o prefijos para el almacenamiento de objetos). Las particiones de esas tablas serían los subdirectorios. Estas rutas de directorio que definen la tabla son rastreadas por un servicio llamado Hive Metastore, al que pueden acceder los motores de consulta para saber dónde encontrar los datos aplicables a su consulta. Esto se ilustra en la Figura 1-6.

Figura 1-6. Arquitectura de una tabla almacenada con el formato de tabla Hive

El formato de tabla Colmena tenía varias ventajas:

  • Permitía patrones de consulta más eficientes que los escaneos completos de tablas, por lo que técnicas como la partición (dividir los datos basándose en una clave de partición) y el bucketing (un enfoque de la partición o agrupación/clasificación que utiliza una función hash para distribuir uniformemente los valores) permitían evitar escanear cada archivo para realizar consultas más rápidas.

  • Era agnóstico en cuanto al formato de los archivos, por lo que con el tiempo permitió a la comunidad de datos desarrollar mejores formatos de archivo, como Apache Parquet, y utilizarlos en sus tablas Hive. Tampoco requería transformación antes de poner los datos a disposición en una tabla Hive (por ejemplo, Avro, CSV/TSV).

  • Mediante intercambios atómicos del directorio listado en el Hive Metastore, puedes hacer cambios de todo o nada (atómicos) en una partición individual de la tabla.

  • Con el tiempo, esto se convirtió en la norma de facto, funcionando con la mayoría de las herramientas de datos y proporcionando una respuesta uniforme a "¿qué datos hay en esta tabla?"

Aunque estas ventajas eran importantes, también había muchas limitaciones que se hicieron evidentes con el paso del tiempo:

  • Los cambios a nivel de archivo son ineficaces, ya que no existía ningún mecanismo para intercambiar atómicamente un archivo de la misma forma que se podía utilizar el Hive Metastore para intercambiar un directorio de partición. Básicamente, tienes que hacer intercambios a nivel de partición para actualizar un único archivo de forma atómica.

  • Aunque podías intercambiar atómicamente una partición, no existía un mecanismo para actualizar atómicamente varias particiones en una sola transacción. Esto abre la posibilidad de que los usuarios finales vean datos incoherentes entre transacciones que actualizan varias particiones.

  • Realmente no existen buenos mecanismos para permitir actualizaciones simultáneas, especialmente con herramientas que no sean el propio Hive.

  • Un motor que enumeraba archivos y directorios consumía mucho tiempo y ralentizaba las consultas. Tener que leer y listar archivos y directorios que quizá no necesiten ser escaneados en la consulta resultante tiene un coste.

  • Las columnas de partición se derivaban a menudo de otras columnas, como derivar una columna de mes de una marca de tiempo. La partición sólo ayudaba si se filtraba por la columna de partición, y alguien que tuviera un filtro en la columna de fecha y hora podía no saber intuitivamente que también debía filtrar por la columna de mes derivada, lo que provocaba un escaneo completo de la tabla, ya que no se aprovechaba la partición.

  • Las estadísticas de las tablas se recopilaban mediante trabajos asíncronos, lo que a menudo daba lugar a estadísticas de estado de las tablas, si es que se disponía de alguna estadística. Esto dificultaba la optimización de las consultas por parte de los motores de consulta.

  • Dado que el almacenamiento de objetos suele estrangular las peticiones contra el mismo prefijo (piensa en un prefijo de almacenamiento de objetos como algo análogo a un directorio de archivos), las consultas sobre tablas con un gran número de archivos en una única partición (de modo que todos los archivos estarían en un mismo prefijo) pueden tener problemas de rendimiento.

Cuanto mayor fuera la escala de los conjuntos de datos y los casos de uso, más se amplificarían estos problemas. Esto provocó un dolor considerable que hizo necesaria una nueva solución, por lo que se crearon nuevos formatos de tablas.

Formatos modernos de tablas de lago de datos

Al tratar de abordar las limitaciones del formato de tabla Hive, surgió una nueva generación de formatos de tabla con distintos enfoques para resolver los problemas de Hive.

Los creadores de formatos de tabla modernos se dieron cuenta de que el fallo que provocaba problemas con el formato de tabla Hive era que la definición de la tabla se basaba en el contenido de los directorios, no en los archivos de datos individuales. Los formatos de tabla modernos, como Apache Iceberg, Apache Hudi y Delta Lake, adoptaron este enfoque de definir las tablas como una lista canónica de archivos, proporcionando metadatos a los motores que informan de qué archivos componen la tabla, no de qué directorios. Este enfoque más granular de la definición de "qué es una tabla" abrió la puerta a características como las transacciones ACID, el viaje en el tiempo y mucho más.

Todos los formatos de tabla modernos pretenden aportar un conjunto básico de ventajas importantes sobre el formato de tabla Colmena :

  • Permiten transacciones ACID, que son transacciones seguras que se completan en su totalidad o se cancelan. En los formatos heredados, como el formato de tabla Hive, muchas transacciones no podían tener estas garantías.

  • Permiten transacciones seguras cuando hay varios escritores. Si dos o más escritores escriben en una tabla, existe un mecanismo para asegurarse de que el escritor que completa su escritura en segundo lugar conoce y tiene en cuenta lo que han hecho los demás escritores para mantener la coherencia de los datos.

  • Ofrecen una mejor recopilación de estadísticas de tablas y metadatos que pueden permitir a un motor de consulta planificar los escaneos de forma más eficiente, de modo que necesite escanear menos archivos .

Exploremos qué es Apache Iceberg y cómo surgió.

¿Qué es el Iceberg Apache?

Apache Iceberg es un formato de tabla creado en 2017 por Ryan Blue de Netflix y Daniel Weeks. Surgió de la necesidad de superar los problemas de rendimiento, consistencia y muchos de los retos anteriormente expuestos con el formato de tabla Hive. En 2018, el proyecto se convirtió en código abierto y se donó a la Apache Software Foundation, donde muchas otras organizaciones empezaron a implicarse en él, como Apple, Dremio, AWS, Tencent, LinkedIn y Stripe. Muchas otras organizaciones han contribuido al proyecto desde entonces.

Cómo surgió el Iceberg Apache

Netflix, en la creación de lo que se convirtió en el formato Apache Iceberg, llegó a la conclusión de que muchos de los problemas del formato Hive derivaban de un defecto simple pero fundamental: cada tabla se rastrea como directorios y subdirectorios, lo que limita la granularidad necesaria para ofrecer garantías de coherencia, mejor concurrencia y varias de las características que suelen estar disponibles en los almacenes de datos.

Teniendo esto en cuenta, Netflix se propuso crear un nuevo formato de mesa con varios objetivos en mente:

Coherencia

Si las actualizaciones de una tabla se producen a través de múltiples particiones, no debe ser posible que los usuarios finales experimenten incoherencias en los datos que están viendo. Una actualización de una tabla a través de múltiples particiones debe hacerse rápida y atómicamente para que los datos sean coherentes para los usuarios finales. Éstos ven los datos antes o después de la actualización, y no entre medias.

Rendimiento

Con el cuello de botella del listado de archivos/directorios de Hive, la planificación de consultas tardaría excesivamente en completarse antes de ejecutar realmente la consulta. La tabla debe proporcionar metadatos y evitar el excesivo listado de archivos para que no sólo la planificación de la consulta sea un proceso más rápido, sino que también los planes resultantes puedan ejecutarse más rápidamente, ya que sólo escanean los archivos necesarios para satisfacer la consulta.

Fácil de usar

Para obtener los beneficios de técnicas como la partición, los usuarios finales no deberían tener que conocer la estructura física de la tabla. La tabla debe ser capaz de ofrecer a los usuarios las ventajas de la partición basándose en consultas naturalmente intuitivas y no depender del filtrado de columnas de partición adicionales derivadas de una columna por la que ya están filtrando (por ejemplo, filtrar por una columna de mes cuando ya has filtrado la marca de tiempo de la que deriva).

Evolucionabilidad

Actualizar los esquemas de las tablas Hive podría dar lugar a transacciones inseguras, y actualizar cómo se particiona una tabla haría necesario reescribir toda la tabla. Una tabla debería poder evolucionar su esquema y su esquema de partición de forma segura y sin necesidad de reescribirla.

Escalabilidad

Todos los objetivos anteriores deberían poder alcanzarse a la escala de petabytes de los datos de Netflix.

Así que el equipo empezó a crear el formato Iceberg, que se centra en definir una tabla como una lista canónica de archivos en lugar de seguir una tabla como una lista de directorios y subdirectorios. El proyecto Apache Iceberg es una especificación, o un estándar de cómo deben escribirse los metadatos que definen una tabla de un lago de datos en varios archivos. Para apoyar la adopción de este estándar, Apache Iceberg dispone de muchas bibliotecas de soporte para ayudar a las personas a trabajar con el formato o a los motores de cálculo a implementar el soporte. Junto con estas bibliotecas, el proyecto ha creado implementaciones para motores de cálculo de código abierto como Apache Spark y Apache Flink.

Apache Iceberg pretende que las herramientas existentes adopten el estándar y está diseñado para aprovechar las soluciones de almacenamiento y los motores de cálculo existentes y populares, con la esperanza de que las opciones existentes admitan trabajar con el estándar. El propósito de este enfoque es dejar que el ecosistema de herramientas de datos existentes desarrolle la compatibilidad con las tablas de Apache Iceberg y que Iceberg se convierta en la norma sobre cómo los motores pueden reconocer y trabajar con tablas en el lago de datos. El objetivo es que Apache Iceberg sea tan omnipresente en el ecosistema que se convierta en otro detalle de implementación en el que muchos usuarios no tengan que pensar. Simplemente saben que están trabajando con tablas y no necesitan pensar más allá de eso, independientemente de la herramienta que utilicen para interactuar con la tabla. Esto ya se está convirtiendo en una realidad, pues muchas herramientas permiten a los usuarios finales trabajar con tablas Apache Iceberg con tanta facilidad que no necesitan entender el formato Iceberg subyacente. Con el tiempo, gracias a las herramientas automatizadas de optimización e ingestión de tablas, los usuarios aún más técnicos, como los ingenieros de datos, no tendrán que pensar tanto en el formato subyacente y podrán trabajar con el almacenamiento de su lago de datos de la misma forma que lo han hecho con los almacenes de datos, sin tener que tratar nunca directamente con la capa de almacenamiento.

La arquitectura Iceberg de Apache

Apache Iceberg rastrea la partición de una tabla, la ordenación, el esquema a lo largo del tiempo y mucho más mediante un árbol de metadatos que un motor puede utilizar para planificar consultas en una fracción del tiempo que tardaría con los patrones de lago de datos heredados. La Figura 1-7 muestra este árbol de metadatos.

Figura 1-7. La arquitectura Iceberg de Apache

Este árbol de metadatos desglosa los metadatos de la tabla en cuatro componentes:

Archivo de manifiesto

Una lista de archivos de datos, que contiene la ubicación/ruta de cada archivo de datos y metadatos clave sobre esos archivos de datos, lo que permite crear planes de ejecución más eficientes.

Lista de manifiestos

Archivos que definen una única instantánea de la tabla como una lista de archivos de manifiesto junto con estadísticas sobre esos manifiestos que permiten crear planes de ejecución más eficientes.

Archivo de metadatos

Ficheros que definen la estructura de una tabla, incluyendo su esquema, esquema de particiones y un listado de instantáneas.

Catálogo

Rastrea la ubicación de la tabla (similar al Hive Metastore), pero en lugar de contener un mapeo de nombre de tabla -> conjunto de directorios, contiene un mapeo de nombre de tabla -> ubicación del archivo de metadatos más reciente de la tabla. Varias herramientas, incluido un Hive Metastore, pueden utilizarse como catálogo, y hemos dedicado el Capítulo 5 a este tema .

Cada uno de estos archivos se tratará con más profundidad en el capítulo 2.

Características principales de Apache Iceberg

La arquitectura única de Apache Iceberg permite un número cada vez mayor de características que van más allá de la mera resolución de los retos con Hive y, en su lugar, desbloquean una funcionalidad totalmente nueva para los lagos de datos y las cargas de trabajo de los lagos de datos. En esta sección, ofrecemos una visión general de alto nivel de las características clave de Apache Iceberg. Profundizaremos en estas funciones en capítulos posteriores.

Transacciones ACID

Apache Iceberg utiliza el control optimista de la concurrencia para permitir las garantías ACID, incluso cuando tienes transacciones gestionadas por múltiples lectores y escritores. La concurrencia optimista asume que las transacciones no entrarán en conflicto y comprueba los conflictos sólo cuando es necesario, con el objetivo de minimizar los bloqueos y mejorar el rendimiento. De este modo, puedes ejecutar transacciones en tu lago de datos que o bien se comprometen o bien fallan, y nada entre medias. Un modelo de concurrencia pesimista, que utiliza bloqueos para evitar conflictos entre transacciones, asumiendo que es probable que se produzcan conflictos, no estaba disponible en Apache Iceberg en el momento de escribir esto, pero puede que llegue en el futuro.

Las garantías de concurrencia las gestiona el catálogo, ya que suele ser un mecanismo que tiene incorporadas garantías ACID. Esto es lo que permite que las transacciones en las tablas Iceberg sean atómicas y ofrezcan garantías de corrección. Si esto no existiera, dos sistemas diferentes podrían tener actualizaciones conflictivas, con la consiguiente pérdida de datos.

Evolución de la partición

Un gran quebradero de cabeza de los lagos de datos antes de Apache Iceberg era lidiar con la necesidad de cambiar la optimización física de la tabla. Con demasiada frecuencia, cuando hay que cambiar el particionamiento, la única opción que tienes es reescribir toda la tabla, y a escala esto puede resultar muy caro. La alternativa es vivir con el esquema de particionado existente y sacrificar las mejoras de rendimiento que puede proporcionar un esquema de particionado mejor.

Con Apache Iceberg puedes actualizar cómo se particiona la tabla en cualquier momento sin necesidad de reescribir la tabla y todos sus datos. Como la partición tiene todo que ver con los metadatos, las operaciones necesarias para realizar este cambio en la estructura de tu tabla son rápidas y baratas.

La Figura 1-8 muestra una tabla que inicialmente se particionó por meses y luego evolucionó para particionarse en función del día en adelante. Los datos escritos anteriormente permanecen en particiones de mes, mientras que los nuevos datos se escriben en particiones de día, y en una consulta, el motor realiza un plan para cada partición basado en el esquema de partición que se le aplica.

Figura 1-8. Evolución de la partición

Partición oculta

A veces los usuarios no saben cómo está particionada físicamente una tabla, y francamente, no debería importarles. A menudo, una tabla está particionada por algún campo de fecha y hora y un usuario quiere consultar por ese campo (por ejemplo, obtener los ingresos medios por día de los últimos 90 días). Para un usuario, la forma más intuitiva de hacerlo es incluir un filtro de event_timestamp >= DATE_SUB(CURRENT_DATE, INTERVAL 90 DAY). Sin embargo, esto dará lugar a un escaneo completo de la tabla, porque en realidad la tabla está particionada por campos separados llamados event_year, event_month y event_day. Esto ocurre porque la partición en una marca de tiempo da lugar a particiones diminutas, ya que los valores están en segundo, milisegundo o granularidad inferior.

Este problema se resuelve con la forma en que Apache Iceberg gestiona el particionamiento. En Iceberg, el particionado se produce en dos partes: la columna, en la que debe basarse el particionado físico; y una transformación opcional de ese valor que incluye funciones como bucket, truncar, año, mes, día y hora. La posibilidad de aplicar una transformación elimina la necesidad de crear nuevas columnas sólo para la partición. Esto da lugar a consultas más intuitivas que se benefician de la partición, ya que los consumidores no necesitarán añadir predicados de filtro adicionales a sus consultas sobre columnas de partición adicionales.

En la Figura 1-9, supongamos que la tabla utiliza la partición por días. La consulta representada en la figura daría lugar a un escaneo completo de la tabla en Hive, ya que probablemente se creó otra columna "día" para la partición, mientras que en Iceberg los metadatos rastrearían la partición como "el valor transformado de CURRENT_DATE" y, por tanto, utilizarían la partición al filtrar por CURRENT_DATE (hablaremos de esto con más detalle más adelante en el libro).

Figura 1-9. Las ventajas de la partición en Apache Iceberg

Operaciones de tabla a nivel de fila

Puedes optimizar los patrones de actualización a nivel de fila de la tabla para que adopten una de las dos formas siguientes: copia en escritura (COW) o fusión en lectura (MOR). Cuando se utiliza COW, para un cambio de cualquier fila en un archivo de datos determinado, se reescribe todo el archivo (con el cambio a nivel de fila realizado en el nuevo archivo) incluso si se actualiza un solo registro en él. Cuando se utiliza MOR, para cualquier actualización a nivel de fila, sólo se escribe un nuevo archivo que contiene los cambios de la fila afectada que se concilia en las lecturas. Esto proporciona flexibilidad para acelerar las cargas de trabajo pesadas de actualización y eliminación.

Viaje en el tiempo

Apache Iceberg proporciona instantáneas inmutables , de modo que la información del estado histórico de la tabla es accesible, lo que te permite ejecutar consultas sobre el estado de la tabla en un momento dado del pasado, o lo que comúnmente se conoce como viaje en el tiempo. Esto puede ayudarte en situaciones como la elaboración de informes de final de trimestre sin necesidad de duplicar los datos de la tabla en una ubicación distinta o para reproducir la salida de un modelo ML a partir de un momento determinado. Esto se representa en la Figura 1-10.

Figura 1-10. Consulta de la tabla tal y como era con el viaje en el tiempo

Retroceso de versión

El aislamiento de instantáneas de Iceberg no sólo te permite consultar los datos tal cual, sino que también revierte el estado actual de la tabla a cualquiera de esas instantáneas anteriores. Por tanto, deshacer errores es tan fácil como retroceder (ver Figura 1-11).

Figura 1-11. Desplazar el estado de la tabla a un momento anterior retrocediendo

Evolución del esquema

Las tablas cambian, ya sea añadiendo/eliminando una columna, renombrando una columna o cambiando el tipo de datos de una columna. Independientemente de cómo deba evolucionar tu tabla, Apache Iceberg te ofrece sólidas funciones de evolución del esquema: por ejemplo, actualizar una columna int a una columna long a medida que los valores de la columna aumentan.

Conclusión

En este capítulo, has aprendido que Apache Iceberg es un formato de tabla de lago de datos construido para mejorar muchas de las áreas en las que las tablas Hive tenían carencias. Al desvincularse de la estructura física de los archivos junto con su árbol de metadatos multinivel, Iceberg es capaz de proporcionar transacciones Hive, garantías ACID, evolución de esquemas, evolución de particiones y otras muchas características que permiten el lago de datos. El proyecto Apache Iceberg es capaz de hacer esto mediante la construcción de una especificación y bibliotecas de apoyo que permiten a las herramientas de datos existentes construir soporte para el formato de tabla abierta.

En el Capítulo 2, profundizaremos en la arquitectura de Apache Iceberg que hace posible todo esto.

Get Apache Iceberg: La Guía Definitiva now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.