¿Es POSIX realmente inadecuado para almacenes de objetos? – CodesCode

¿Es POSIX realmente inadecuado para almacenes de objetos? Sumérgete en el análisis impulsado por datos de MinIO, s3fs-fuse y JuiceFS para descubrirlo.

El autor de esta publicación cuestiona la perspectiva presentada en un artículo de MinIO, que sugiere que POSIX no es adecuado para almacenamientos de objetos. Realizó pruebas exhaustivas que involucraron MinIO s3fs-fuse y JuiceFS. Los resultados indican que MinIO y JuiceFS ofrecen un excelente rendimiento mientras que s3fs-fuse se queda rezagado. En escenarios de sobrescritura de archivos pequeños, JuiceFS FUSE-POSIX supera a otras soluciones.

Recientemente, me encontré con un artículo en el blog de MinIO titulado “Poner un sistema de archivos encima de un almacenamiento de objetos es una mala idea. Aquí está el porqué.” El autor utilizó s3fs-fuse como ejemplo para ilustrar los desafíos de rendimiento que se encuentran al acceder a los datos de MinIO utilizando métodos de Portable Operating System Interface (POSIX), destacando que el rendimiento está significativamente rezagado en comparación con el acceso directo a MinIO. El autor atribuyó estos problemas de rendimiento a fallas inherentes en POSIX. Sin embargo, nuestra experiencia difiere un poco de esta conclusión.

POSIX es un estándar útil y ampliamente adoptado. Desarrollar software siguiendo POSIX garantiza la compatibilidad y portabilidad entre diferentes sistemas operativos. La mayoría de las aplicaciones en diversas industrias se adhieren al estándar POSIX. Con el avance de la computación en la nube, el Big Data y las tecnologías de inteligencia artificial, así como el aumento del volumen de datos almacenados, existe una creciente demanda de soluciones de almacenamiento elásticas como los almacenes de objetos. Aunque los almacenes de objetos como MinIO proporcionan SDKs en múltiples lenguajes, muchas aplicaciones tradicionales tienen dificultades para adaptar su código para utilizar las APIs de almacenamiento de objetos. Esto ha llevado a que varios productos de almacenamiento implementen interfaces POSIX encima de los almacenes de objetos para satisfacer esta demanda inflexible.

Muchos productos de la industria, como Ceph, JuiceFS y Weka, han implementado con éxito interfaces POSIX en almacenes de objetos. Estas soluciones tienen una gran base de usuarios y numerosos casos de éxito, y se desempeñan bien en términos de rendimiento.

Aunque es cierto que POSIX tiene una complejidad significativa, los problemas asociados no son insuperables. Con respeto y el deseo de verificar estas afirmaciones, configuro un entorno de prueba, utilizo los mismos datos de muestra y métodos de prueba que en el artículo de MinIO, y realizo una validación.

Productos Comparados y Objetivos de la Prueba

Para proporcionar una evaluación completa, introduje JuiceFS en la comparación.

JuiceFS es un sistema de archivos distribuido nativo de la nube de código abierto. Emplea almacenamiento de objetos como su capa de almacenamiento de datos y depende de una base de datos separada para almacenar metadatos. Ofrece varios métodos de acceso, incluyendo API POSIX, API S3, Controlador CSI, API HDFS y WebDAV, junto con mecanismos únicos de divisiones de datos, almacenamiento en caché y lectura/escritura concurrente. JuiceFS es un sistema de archivos, fundamentalmente distinto de herramientas como s3fs-fuse, que simplemente convierten el almacenamiento de objetos en protocolos POSIX.

Al introducir JuiceFS en la comparación, mi objetivo fue evaluar objetivamente las ventajas y desventajas de implementar protocolos como POSIX encima del almacenamiento de objetos.

Llevo a cabo las siguientes dos pruebas en MinIO, JuiceFS y s3fs-fuse:

  • Escritura de un archivo de 10 GB
  • Sobrescritura de archivos pequeños con Pandas

Todas las soluciones utilizan una instancia de MinIO desplegada en servidores separados como almacenamiento subyacente. Para las muestras de prueba, se utilizó un archivo de 10 GB, que es el mismo archivo CSV mencionado en el artículo de MinIO.

En este artículo, se proporciona el código completo e instrucciones para todos los entornos, software, scripts y datos de muestra, asegurando que puedas reproducir el entorno y los resultados de la prueba.

Configuración del Servidor y del Entorno de Prueba

Dos servidores en la nube configurados de manera idéntica:

  • Sistema: Ubuntu 22.04 x64
  • CPU: 8 núcleos
  • RAM: 16 GB
  • SSD: 500 GB
  • Red: VPC

La información para cada servidor:

Servidor IP Propósito
Servidor A 172.16.254.18 Despliegue de la instancia de MinIO
Servidor B 172.16.254.19 Como entorno de prueba

Preparación del Servidor A

1. Despliego MinIO en el Servidor A utilizando Docker con los siguientes comandos:

# Crear un directorio dedicado y navegar a él.
mkdir minio && cd minio
# Crear un archivo de configuración.
mkdir config
touch config/minio

2. Escribí la siguiente información en el archivo config/minio:

MINIO_ROOT_USER=adminMINIO_ROOT_PASSWORD=abc123abcMINIO_VOLUMES="/mnt/data"

3. Creé el contenedor de MinIO:

sudo docker run -d --name minio \  -p 9000:9000 \  -p 9090:9090 \  -v /mnt/minio-data:/mnt/data \  -v ./config/minio:/etc/config.env \  -e "MINIO_CONFIG_ENV_FILE=/etc/config.env" \  --restart unless-stopped \  minio/minio server --console-address ":9090"

4. En la Consola Web de MinIO, pre-creé tres buckets:

Nombre del Bucket Propósito
test-minio Para probar MinIO
test-juicefs Para probar JuiceFS
test-s3fs Para probar s3fs-fuse

Preparación del Servidor B

1. Descargué un archivo de prueba de 10 GB.

curl -LO https://data.cityofnewyork.us/api/views/t29m-gskq/rows.csv?accessType=DOWNLOAD

2. Instalé el cliente mc.

mc es un administrador de archivos de línea de comandos desarrollado por el proyecto MinIO. Permite operaciones de lectura y escritura en almacenamiento de objetos tanto local como compatible con S3 en la línea de comandos de Linux. El comando mc cp proporciona actualizaciones de progreso y velocidad en tiempo real durante la copia de datos, facilitando la observación de diversas pruebas.

Nota: Para mantener la equidad de las pruebas, los tres enfoques utilizaron mc para las pruebas de escritura de archivos.

# Descargar mc.wget https://dl.min.io/client/mc/release/linux-amd64/mc# Comprobar la versión de mc.mc -vmc version RELEASE.2023-09-20T15-22-31Z (commit-id=38b8665e9e8649f98e6162bdb5163172e6ecc187)Runtime: go1.21.1 linux/amd64# Instalar mc.sudo install mc /usr/bin# Establecer un alias para MinIO.mc alias set my http://172.16.254.18:9000 admin abc123abc

3. Descargué s3fs-fuse.

sudo apt install s3fs# Comprobar la versión.s3fs --versionAmazon Simple Storage Service File System V1.93 (commit:unknown) with OpenSSL# Establecer la clave de acceso al almacenamiento de objetos.echo admin:abc123abc >  ~/.passwd-s3fs# Modificar los permisos del archivo de clave.chmod 600  ~/.passwd-s3fs# Crear el directorio de montaje.mkdir mnt-s3fs# Montar el almacenamiento de objetos.s3fs test-s3fs:/ /root/mnt-s3fs -o url=http://172.16.254.18:9000 -o use_path_request_style

4. Instalé JuiceFS.

Utilicé el script oficial para instalar la última versión de JuiceFS Community Edition.

# Script de instalación con un cliccurl -sSL https://d.juicefs.com/install | sh -# Comprobar la versión.juicefs versionjuicefs version 1.1.0+2023-09-04.08c4ae6

5. Creé un sistema de archivos. JuiceFS es un sistema de archivos que debe crearse antes de su uso. Además del almacenamiento de objetos, requiere una base de datos como motor de metadatos. Admite varias bases de datos. Aquí, utilicé Redis, ampliamente utilizado, como el motor de metadatos.

Nota: He instalado Redis en el Servidor A, accesible a través de 172.16.254.18:6379 sin contraseña. El proceso de instalación se omite aquí. Puede consultar la documentación de Redis para obtener más detalles.

# Crear el sistema de archivos.juicefs format --storage minio \--bucket http://172.16.254.18:9000/test-juicefs \--access-key admin \--secret-key abc123abc \--trash-days 0 \redis://172.16.254.18/1 \myjfs

6. Accedí a JuiceFS utilizando los métodos más comunes de API POSIX y S3 y probé su rendimiento.

# Crear directorios de montaje.mkdir ~/mnt-juicefs# Montar el sistema de archivos en modo POSIX.juicefs mount redis://172.16.254.18/1 /root/mnt-juicefs# Acceder al sistema de archivos usando el método de API S3.export MINIO_ROOT_USER=adminexport MINIO_ROOT_PASSWORD=abc123abcjuicefs gateway redis://172.16.254.18/1 0.0.0.0:9000# Establecer un alias para la API S3 de JuiceFS en mc.mc alias set juicefs http://172.16.254.18:9000 admin abc123abc

Nota: El gateway de JuiceFS también se puede implementar en el Servidor A o en cualquier otro servidor accesible a través de Internet, ya que expone una API S3 basada en red.

Pruebas y resultados

Aquí tienes un resumen rápido de mis pruebas y resultados:

Prueba MinIO S3FS-FUSE JuiceFS(FUSE) JuiceFS(gateway S3)
Escritura de un archivo de 10 GB 0m27.651s 3m6.380s 0m28.107s 0m28.091s
Sobrescritura de archivos pequeños con Pandas 0.83s 0.78s 0.46s 0.96s

Prueba 1: Escritura de un archivo de 10 GB

Esta prueba fue diseñada para evaluar el rendimiento de la escritura de archivos grandes. Cuanto menor sea el tiempo requerido, mejor será el rendimiento. Utilicé el comando time para medir la duración de las operaciones de escritura, proporcionando tres métricas:

  • real: El tiempo real desde el inicio hasta el final del comando. Incluye todos los tiempos de espera, como la espera de operaciones de E/S para completarse, la espera de cambios de proceso y la espera de recursos.
  • usuario: El tiempo ejecutado en modo usuario, que indica el tiempo de CPU utilizado para ejecutar el código de usuario. Por lo general, representa la carga computacional del comando.
  • sistema: El tiempo ejecutado en modo kernel, que indica el tiempo de CPU utilizado para ejecutar el código del kernel. Por lo general, representa la carga relacionada con las llamadas al sistema, como la E/S de archivos y la administración de procesos.

MinIO

Ejecuté el siguiente comando para realizar una prueba de copia:

time mc cp ./2018_Yellow_Taxi_Trip_Data.csv  my/test-minio/

Resultados de la escritura de un archivo de 10 GB directamente en MinIO:

real    0m27.651susuario    0m10.767ssistema 0m5.439s

S3FS-FUSE

Ejecuté el siguiente comando para realizar una prueba de copia:

time mc cp ./2018_Yellow_Taxi_Trip_Data.csv /root/mnt-s3fs/

Resultados de la escritura de un archivo de 10 GB directamente en s3fs-fuse:

real 3m6.380susuario 0m0.012ssistema 0m5.459s

Nota: Aunque el tiempo de escritura fue de 3 minutos y 6 segundos para s3fs-fuse, no hubo fallos de escritura como se describe en el artículo de MinIO.

JuiceFS

Probé el rendimiento de JuiceFS para escritura de archivos grandes utilizando tanto los métodos de API POSIX como S3:

# Prueba de escritura POSIXtime mc cp ./2018_Yellow_Taxi_Trip_Data.csv /root/mnt-juicefs/# Prueba de escritura API S3time mc cp ./2018_Yellow_Taxi_Trip_Data.csv  juicefs/myjfs/

Resultados de la escritura POSIX de JuiceFS para un archivo de 10 GB:

real    0m28.107susuario    0m0.292ssistema 0m6.930s

Resultados para la escritura de un archivo de 10 GB con la API S3 de JuiceFS:

real    0m28.091suser    0m13.643ssys 0m4.142s

Resumen de los Resultados de Escritura de Archivos Grandes

La siguiente figura muestra los resultados de la prueba:

Resultados de la escritura de archivos grandes (menor es mejor)

Los resultados de la prueba muestran que tanto la escritura directa en MinIO como en JuiceFS ofrecen un rendimiento comparable, completando la tarea en aproximadamente 30 segundos. En contraste, s3fs-fuse tardó más de 3 minutos en escribir un archivo de 10 GB, lo que fue aproximadamente seis veces más lento que los dos anteriores.

Cuando se escriben archivos grandes, mc utiliza la API Multipart para cargar los archivos en fragmentos en la interfaz S3. Por otro lado, s3fs-fuse solo puede escribir en POSIX en un solo hilo. JuiceFS también divide automáticamente archivos grandes en fragmentos y los escribe concurrentemente en MinIO durante escrituras secuenciales, garantizando un rendimiento a la par de las escrituras directas en MinIO. S3FS, por otro lado, escribe primero en un disco caché en un solo hilo y luego carga el archivo en fragmentos en MinIO, lo que resulta en tiempos de escritura más largos.

Basado en el cálculo de que tomó 30 segundos escribir un archivo de 10 GB, la velocidad promedio fue de 333 MB/s. Esto estuvo limitado por el ancho de banda de las SSD del servidor en la nube. Estos resultados de prueba indicaron que tanto MinIO como JuiceFS podrían maximizar el ancho de banda de las SSD locales y su rendimiento mejorarían con mejoras en los discos de servidor en la nube y el ancho de banda de la red.

Prueba 2: Sobrescribir Archivos Pequeños con Pandas

Esta prueba evaluó el rendimiento de los sistemas de almacenamiento de objetos en escenarios de sobreescritura de archivos pequeños. Los scripts de prueba para cada software difieren ligeramente. Puedes encontrar todo el código de los scripts aquí.

MinIO

Obtuve el script de prueba y ejecuté la prueba:

# Obtén el script de prueba.curl -LO https://gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-minio.py# Ejecuta la prueba.python3 pandas-minio.py

El resultado fue el siguiente:

Tiempo de ejecución: 0.83 segundos

s3fs-fuse

Obtuve el script de prueba y ejecuté la prueba:

# Obtén el script de prueba.curl -LO gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-s3fs.py# Ejecuta la prueba.python3 pandas-s3fs.py

El resultado de la prueba fue el siguiente:

Tiempo de ejecución: 0.78 segundos

JuiceFS POSIX

Obtuve el script de prueba y ejecuté la prueba:

# Obtén el script de prueba.curl -LO gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-juicefs-posix.py# Ejecuta la prueba.python3 pandas-juicefs-posix.py

El resultado de la prueba fue el siguiente:

Tiempo de ejecución: 0.43 segundos

JuiceFS API S3

Obtuve el script de prueba y ejecuté la prueba:

# Obtén el script de prueba.curl -LO https://gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-juicefs-s3api.py# Ejecuta la prueba.python3 pandas-juicefs-s3api.py

El resultado de la prueba fue el siguiente:

Tiempo de ejecución: 0.86 segundos

Resumen de la sobreescritura de archivos pequeños en Pandas

La siguiente figura muestra los resultados de la prueba:

Resultados de sobreescritura en Pandas (menor es mejor)

En esta prueba, JuiceFS FUSE-POSIX demostró la velocidad más rápida, casi el doble de rápido que las otras soluciones. MinIO, s3fs-fuse y JuiceFS S3 Gateway muestran un rendimiento similar. Desde la perspectiva de la sobreescritura de archivos pequeños, la interfaz POSIX resultó más eficiente, ofreciendo un mejor rendimiento que las interfaces de almacenamiento de objetos.

Problemas y análisis

Problema 1: ¿Por qué S3FS fue tan lento?

Análisis: A partir de los datos de prueba, es evidente que al escribir el mismo archivo de 10 GB, S3FS tardó 3 minutos, mientras que MinIO y JuiceFS completaron la tarea en aproximadamente 30 segundos. Esta diferencia significativa de rendimiento se debió principalmente a diferentes implementaciones técnicas. Cuando s3fs-fuse escribe un archivo, primero lo escribe en un archivo temporal local y luego lo carga en el almacenamiento de objetos en fragmentos. Si no hay suficiente espacio en disco local, se carga de forma síncrona. Necesita copiar datos entre el disco local y el almacenamiento de S3. Por lo tanto, los archivos grandes o una cantidad sustancial de archivos resultan en una degradación del rendimiento.

Además, S3FS depende de las capacidades de gestión de metadatos del almacenamiento de objetos subyacente. Cuando maneja un gran número de archivos, la interacción frecuente con el almacenamiento de objetos para recuperar metadatos tiene un impacto significativo en el rendimiento. En términos simples, cuanto mayor sea el tamaño de archivo y la cantidad total de archivos escritos en S3FS, mayor será la sobrecarga proporcional de rendimiento.

Problema 2: ¿Por qué fue JuiceFS más rápido?

Análisis: En la prueba, tanto JuiceFS como S3FS utilizaron FUSE para lectura y escritura. JuiceFS utilizó completamente el ancho de banda del disco como MinIO, pero no tuvo problemas de rendimiento como S3FS.

La respuesta radica en sus respectivas arquitecturas técnicas. Mientras que los datos se procesan a través de la capa FUSE durante la escritura de archivos, JuiceFS utiliza técnicas de alta concurrencia, almacenamiento en caché y fragmentación de datos para reducir la sobrecarga de comunicación entre la capa FUSE y el almacenamiento de objetos subyacente. Esto permite que JuiceFS maneje más solicitudes de lectura y escritura para archivos simultáneamente, reduciendo los tiempos de espera y la latencia de transmisión.

Además, JuiceFS utiliza una base de datos dedicada (en este caso, Redis) para gestionar los metadatos. Al tratar con un número especialmente grande de archivos, un motor de metadatos independiente puede aliviar eficazmente la carga de trabajo, lo que permite una ubicación de archivos más rápida.

Conclusión

Las pruebas anteriores demuestran que utilizar el almacenamiento de objetos como base e implementar una interfaz POSIX encima de él no necesariamente causa una pérdida de rendimiento. Ya sea al escribir archivos grandes o pequeños, JuiceFS exhibe un rendimiento comparable a las escrituras directas en MinIO sin ninguna degradación en el rendimiento del almacenamiento de objetos subyacente debido al acceso POSIX. Además, en términos de sobreescritura de tablas de Pandas, el rendimiento de JuiceFS FUSE-POSIX se mantiene consistente e incluso supera a MinIO en casi el doble.

Los resultados de la prueba indican que algunos software, como s3fs-fuse, pueden experimentar una degradación del rendimiento al convertir entre la API de S3 y las interfaces POSIX. Si bien puede ser una herramienta conveniente para el acceso temporal a S3, para un uso estable y de alto rendimiento a largo plazo, es necesario realizar investigaciones y validaciones cuidadosas para seleccionar soluciones más adecuadas.

Para archivar archivos no estructurados simples, el uso directo de MinIO o almacenamiento de objetos en la nube es una buena elección. Sin embargo, para escenarios que implican almacenamiento y procesamiento de datos a gran escala, como el entrenamiento de modelos de IA, análisis de big data, persistencia de datos de Kubernetes y otras operaciones frecuentes de lectura y escritura, la gestión de metadatos independiente, las capacidades de lectura y escritura concurrentes y los mecanismos de caché de JuiceFS brindan un rendimiento superior. Es una solución de sistema de archivos de alto rendimiento que vale la pena considerar.


Leave a Reply

Your email address will not be published. Required fields are marked *