Al comprar almacenamiento, el énfasis suele estar en los medios, pero puede ser incluso más importante considerar también los métodos de acceso. Deberá tener en cuenta los protocolos de almacenamiento al diseñar y adquirir infraestructura, especialmente cuando deje atrás el almacenamiento heredado para migrar al almacenamiento de objetos nativo de la nube. Sin embargo, el almacenamiento de objetos depende de la API S3 para las comunicaciones, mientras que las cargas de trabajo heredadas dependen de POSIX, la interfaz del sistema operativo portátil que proporciona un conjunto de estándares desarrollados en la década de 1980 para permitir que las aplicaciones sean portátiles entre sistemas operativos Unix. Lo más probable es que la mayoría de las empresas hayan tenido aplicaciones en servicio durante décadas que fueron desarrolladas para ejecutarse en POSIX. También es probable que los ingenieros ya estén conscientes del pobre desempeño de POSIX.
Dicho esto, cuando tienes sistemas heredados que sólo pueden ingerir datos en un determinado formato o de una determinada fuente, tus opciones pueden ser limitadas y es posible que no tengas otra opción que implementar un protocolo obsoleto o reescribir tu código. Por ejemplo, si solo puede ingerir desde un disco local con un sistema de archivos y no con API RESTful a las que se accede a través de la red, primero debe hacer que esos datos estén disponibles en el disco antes de que su aplicación pueda usarlos. Sin embargo, utilizar un almacén de objetos como sistema de archivos tiene una serie de implicaciones negativas graves en lo que respecta al rendimiento, la compatibilidad, la integridad de los datos y la seguridad.
Demostremos esto con algunas pruebas del mundo real utilizando una pequeña utilidad llamada s3fs-fuse . Esta utilidad le permite montar un depósito S3 como un sistema de archivos local. Significa Sistema de archivos S3 (Servicio de almacenamiento simple) - FUSE (Sistema de archivos en el espacio de usuario). Es un proyecto de código abierto que aprovecha la interfaz FUSE (sistema de archivos en el espacio de usuario) para presentar una interfaz similar a un sistema de archivos para S3.
Una vez que se monta un depósito S3 usando s3fs-fuse
, puede interactuar con el depósito como si fuera un sistema de archivos local. Esto significa que puede utilizar operaciones de archivos normales (como leer, escribir, mover, etc.) en los archivos de su depósito. Esto suena increíblemente conveniente y podemos argumentar que simplifica el desarrollo de aplicaciones. Pero, inherentemente, el almacenamiento de objetos y los sistemas de archivos tienen diferencias fundamentales que afectarán al depósito s3 montado como sistema de archivos.
Tomémonos un momento para alejarnos de la utilidad s3fs-fuse
y discutir las verdaderas razones por las que tratar el almacenamiento de objetos como un sistema de archivos está lejos de ser óptimo. El problema es mucho mayor que s3fs-fuse
e incluye otras utilidades como Mountpoint basado en Rust para Amazon S3 , un cliente de archivos que traduce llamadas API del sistema de archivos local a llamadas API de objetos S3. La primera razón es que todas estas utilidades dependen de POSIX para las operaciones del sistema de archivos. POSIX es ineficiente y nunca estuvo pensado para trabajar con archivos muy grandes a través de la red.
La velocidad de los sistemas basados en POSIX disminuye a medida que aumenta la demanda, especialmente la demanda concurrente. Cuando las grandes organizaciones necesitan almacenar y acceder a océanos de datos para aprendizaje profundo, inteligencia artificial y otros casos de uso intensivo de datos, POSIX no tiene la capacidad ni la escalabilidad para satisfacer estas demandas. Si bien los arreglos totalmente flash han mantenido a POSIX en el juego, la escalabilidad y las API RESTful (las características distintivas de la nube) son como la kriptonita.
Debido a esto, ejecutar POSIX sobre un almacén de objetos no es óptimo. Echemos un vistazo a algunas de las razones:
Rendimiento: la interfaz POSIX FS está inherentemente centrada en IOPS. Son conversadores, caros y difíciles de escalar. La API RESTful S3 soluciona esto transformando IOPS en un problema de rendimiento. El rendimiento es más fácil y económico de escalar. Es por eso que el almacenamiento de objetos tiene un alto rendimiento a escala masiva. La superposición de POSIX sobre S3 no se escalará porque POSIX es demasiado hablador para realizarse a través de una interfaz HTTP RESTful.
Semántica: debido a que las operaciones de objetos son atómicas e inmutables, no hay forma de garantizar la corrección de la coherencia. Esto significa que puede perder los datos no confirmados en caso de una falla o tener problemas de corrupción en caso de montajes compartidos.
Integridad de los datos : las escrituras o cualquier mutación en un archivo no aparecerán en el espacio de nombres hasta que se confirme. Esto significa que el acceso simultáneo a través de montajes compartidos no verá las modificaciones. No es útil para acceso compartido.
Control de acceso: los permisos POSIX y las ACL son primitivos e incompatibles con la forma en que la API de S3 maneja las políticas de administración de acceso e identidad. No es posible implementar de forma segura la gestión de acceso POSIX en las principales API de S3.
POSIX también carece de la mayor parte de las funciones que a los desarrolladores les encantan de S3, como el cifrado a nivel de objeto, el control de versiones y la inmutabilidad; estas simplemente no tienen equivalente en el mundo POSIX y nada puede traducirlas.
Estos ejemplos ilustran la cuestión y sus implicaciones. Para comenzar, usaremos este archivo CSV que tiene aproximadamente 10 GB y 112 filas.
Nota: Supondremos que s3fs-fuse
ya está instalado y que ha montado uno de los depósitos del almacenamiento de objetos en su sistema de archivos. Si no, sigue las instrucciones aquí .
En estos ejemplos, asumiremos que el nombre del depósito es test-bucket y el nombre del archivo es taxi-data.csv está en el directorio /home/user/ y s3fs-fuse bucket
está montado en /home/user/test-bucket/
Primero intentaremos algo simple e intentaremos copiar el archivo CSV a nuestro depósito de prueba usando los comandos mc y registraremos el tiempo necesario.
time mc cp /home/user/taxi-data.csv minio/test-bucket/taxi-data.csv
Esto no debería llevar mucho tiempo y el archivo debería copiarse en nuestro depósito. Ahora intentemos hacer lo mismo con s3fs-fuse
time cp /home/user/taxi-data.csv /home/user/test-bucket/taxi-data.csv
Tiempo que tomó durante la prueba.
real 1m36.056s user 0m14.507s sys 0m31.891s
En mi caso solo pude copiar el archivo parcialmente al depósito y la operación falló con el siguiente error
cp: error writing '/home/user/test-bucket/taxi-data.csv': Input/output error cp: failed to close '/home/user/test-bucket/taxi-data.csv': Input/output error
Después de varios intentos lo consiguió.
real 5m3.661s user 0m0.053s sys 2m35.234s
Como puede ver, debido a la cantidad de llamadas API que la utilidad necesita realizar y la sobrecarga general de las operaciones, la utilidad se vuelve inestable y la mayoría de las operaciones ni siquiera finalizan.
Le hemos mostrado un ejemplo simple cp
, que puede haber sido convincente o no, porque seamos realistas, podría pensar que time cp
es bastante rudimentario.
Entonces, para las personas que necesitan más evidencia empírica, escribamos un fragmento de Python para probar esto. Haremos un ejemplo simple de Pandas con s3fs-fuse
y el paquete python s3fs
, y veremos el impacto en el rendimiento.
import timeit import os import fsspec import s3fs import pandas as pd # Write a dummy CSV file to test-bucket df = pd.DataFrame({"column1": ["new_value1"], "column2": ["new_value2"]}) df.to_csv("s3://test-bucket/data/test-data.csv", index=False) def process_s3(): # add fsspec for pandas to use `s3://` path style and access S3 buckets directly fsspec.config.conf = { "s3": { "key": os.getenv("AWS_ACCESS_KEY_ID", "minioadmin"), "secret": os.getenv("AWS_SECRET_ACCESS_KEY", "minioadmin"), "client_kwargs": { "endpoint_url": os.getenv("S3_ENDPOINT", "https://play.min.io") } } } s3 = s3fs.S3FileSystem() for i in range(100): # Read the existing data print(i) df = pd.read_csv('s3://test-bucket/data/test-data.csv') # Append a new row new_df = pd.concat([df, pd.DataFrame([{"column1": f"value{i}", "column2": f"value{i}"}])], ignore_index=True) # Write the data back to the file new_df.to_csv('s3://test-bucket/data/test-data.csv', index=False) execution_time = timeit.timeit(process_s3, number=1) print(f"Execution time: {execution_time:.2f} seconds")
Tiempo necesario durante la prueba.
Execution time: 8.54 seconds
Ahora intentemos lo mismo con s3fs-fuse
import timeit import pandas as pd # Write a dummy CSV file to test-bucket df = pd.DataFrame({"column1": ["new_value1"], "column2": ["new_value2"]}) df.to_csv("s3://test-bucket/data/test-data.csv", index=False) def process_s3fs(): for i in range(100): # Read the existing data print(i) df = pd.read_csv('/home/user/test-bucket/data/test-data.csv') # Append a new row new_df = pd.concat([df, pd.DataFrame([{"column1": f"value{i}", "column2": f"value{i}"}])], ignore_index=True) # Write the data back to the file new_df.to_csv('/home/user/test-bucket/data/test-data.csv', index=False) execution_time = timeit.timeit(process_s3fs, number=1) print(f"Execution time: {execution_time:.2f} seconds")
Tiempo necesario durante la prueba.
Execution time: 9.59 seconds
Estos ejemplos demuestran lecturas y escrituras constantes en archivos S3. Imagine esto realizado simultáneamente por varios clientes: la latencia aumenta dramáticamente.
Como puede ver, la diferencia entre usar la traducción POSIX para tratar objetos como archivos y usar la API directa para trabajar con objetos es de día y de noche. Simplemente no hay comparación cuando se trata de seguridad, rendimiento, integridad de datos y compatibilidad. MinIO tiene SDK para integrarse con casi cualquier lenguaje de programación popular y puede ejecutarse en casi cualquier plataforma, como Kubernetes, Linux básico, contenedores Docker y mucho más.
MinIO protege los objetos con cifrado en reposo y en tránsito, combinado con PBAC para regular el acceso y la codificación de borrado para proteger la integridad de los datos. Obtendrá el mejor rendimiento posible, independientemente de dónde ejecute MinIO, porque aprovecha el hardware subyacente (consulte Selección del mejor hardware para su implementación de MinIO ) para ofrecer el mayor rendimiento posible. Hemos evaluado MinIO a 325 GiB/s (349 GB/s) en GET y 165 GiB/s (177 GB/s) en PUT con solo 32 nodos de SSD NVMe disponibles en el mercado.
¡Simplemente no hay necesidad de una utilidad de sistema de archivos entre MinIO y su aplicación! Cualquier ventaja que puedan recibir las aplicaciones heredadas se verá compensada por los problemas de POSIX.
Si tiene alguna pregunta sobre el uso de la traducción POSIX para su aplicación, asegúrese de comunicarse con nosotros en Slack .
También publicado aquí .