2 puntos por GN⁺ 2024-03-11 | 1 comentarios | Compartir por WhatsApp
  • Amazon S3 es una tecnología temprana de la nube que apareció en 2006; es fuerte para almacenar archivos, pero no es un sistema de archivos que reemplace tal cual la API de archivos de Unix
  • La API de archivos de Unix se parece más a un módulo profundo que esconde detrás de una interfaz reducida operaciones como open, read, write, seek y close, junto con buffering, page cache, permisos y programación de IO
  • S3 parece simple porque se centra en GetObject y PutObject, pero solo permite lecturas parciales mediante Range y no soporta sobrescritura parcial
  • Bases de datos como Postgres, SQLite, MySQL, MongoDB y Elasticsearch dependen de sobrescrituras por página, por lo que subir un archivo de SQLite o DuckDB a S3 tal cual difícilmente encaja fuera de datasets pequeños
  • El alto ancho de banda de lectura y escritura, junto con la baja carga operativa, son puntos fuertes de S3, pero también hay que considerar limitaciones como la ausencia de rename/move, listados lentos, una API solo en XML y la falta de un entorno local de pruebas

S3 almacena archivos, pero no es un sistema de archivos

  • S3 es una tecnología temprana de la nube que apareció en 2006 y, siguiendo la terminología de moda en ese momento, se describía como un “object store”
  • En la práctica se usa ampliamente como almacén de archivos, pero entenderlo como si fuera algo como “Amazon Cloud Filesystem” solo es correcto a medias
  • Guarda archivos bien, pero no reemplaza tal cual el comportamiento ni las expectativas de un sistema de archivos tradicional

La API de archivos de Unix y los módulos profundos

  • La esencia de la API de archivos de Unix puede resumirse en estas cinco llamadas
    • open(filepath): abre el archivo
    • file.read(size=100): lee desde la posición actual y avanza la posición
    • file.write("hello, world"): escribe en la posición actual y avanza la posición
    • file.seek(94): mueve la posición a un byte específico
    • file.close(): cierra el archivo
  • Estas llamadas están entre las partes centrales del conjunto completo de system calls y se acercan a la funcionalidad mínima necesaria para leer y escribir archivos
  • Como detrás de esta interfaz reducida ocurre mucho procesamiento, la API de archivos de Unix puede verse como un módulo profundo (deep module)
    • buffering y page cache
    • manejo de fragmentación
    • gestión de permisos
    • programación de IO
    • incluso funciones como el wear-levelling de una tarjeta SD benefician al usuario sin que tenga que preocuparse directamente por ello

Módulos superficiales, YAML y ORM

  • Un módulo superficial tiene una superficie de API relativamente grande en comparación con lo que realmente resuelve
  • Hoy, una pista para reconocer un módulo superficial es que su interfaz sea YAML
    • YAML parece un lenguaje de marcado, pero en la práctica se usa como una sintaxis reutilizable sobre la que puede montarse casi cualquier semántica
    • En el mundo DevOps, YAML muchas veces funciona como si fuera un “lenguaje de programación”
    • Si un mini lenguaje basado en YAML ofrece estructuras de repetición, es posible que sea Turing completo
  • Un módulo superficial no siempre es algo malo
    • Un SQL ORM es, en esencia, una abstracción con fugas y es difícil usarlo sin entender SQL
    • En algunos casos, un módulo superficial puede ser la mejor forma posible
  • A igualdad de condiciones, un módulo más profundo es mejor

La API de S3 es simple, pero distinta a la API de archivos

  • La API de archivos de Unix quedó establecida a inicios de los años 70 y, por compatibilidad, su interfaz se ha mantenido mientras su implementación interna cambió muchas veces
  • Amazon S3 no vuelve a implementar la API del sistema de archivos de Unix
  • Las operaciones básicas de S3 solo corresponden parcialmente con la API de archivos de Unix
    • GetObject(Bucket, Key, Range=None): lee todo el objeto o una parte
    • PutObject(Bucket, Key): escribe el objeto completo
  • Existe además el concepto adicional de bucket, pero si se mira la relación entre funcionalidad y superficie de interfaz, S3 puede considerarse incluso más simple que la API de archivos de Unix
  • La diferencia decisiva es la ausencia de sobrescritura parcial
    • El parámetro Range de GetObject permite leer solo una parte del objeto
    • No es posible sobrescribir solo una parte del objeto
    • La sobrescritura debe hacerse a nivel del archivo completo
  • Por esta diferencia, S3 solo encaja bien en una parte de los casos de uso tradicionales de archivos

Las bases de datos son difíciles de portar tal cual a S3

  • Muchas bases de datos almacenan sus datos en archivos sobre un sistema de archivos
    • Postgres mantiene 2 o 3 archivos por tabla, además de varios archivos de administración
    • SQLite es conocido por guardar todos los datos en un solo archivo
    • MySQL, MongoDB y Elasticsearch también guardan datos en archivos
  • El problema es que las bases de datos suelen depender de sobrescrituras parciales por página
    • Los datos normalmente se guardan en páginas de 4 KB u 8 KB
    • Un heap file puede contener miles de páginas
    • Las páginas se sobrescriben parcialmente para guardar la información necesaria
  • Si se pone una base de datos SQLite en S3, cada escritura obliga a reescribir todo el archivo de la base de datos
  • S3 puede manejar escrituras grandes con rapidez, pero salvo en los datasets más pequeños, una estrategia de sobrescribir el archivo completo cada vez es difícil de sostener
  • Si se reescribe el archivo de la base de datos en cada operación, también se vuelve difícil aprovechar la integridad transaccional que implementó el autor de la base de datos
  • En S3, gana la última escritura

Lo que S3 hace bien y lo que no

  • La fortaleza de S3 está en su ancho de banda muy alto para lectura y escritura
    • No es difícil encontrar casos en línea de más de 10 GB por segundo de escritura o lectura hacia S3
    • También hay experiencia directa de trabajos de escritura a S3 que saturaron la red de oficina de clientes del sector financiero
  • Además de no tener sobrescritura parcial, hay otras limitaciones frente a un sistema de archivos
  • S3 no tiene operación de rename ni move
    • El cambio de nombre se resuelve con CopyObject seguido de DeleteObject
    • CopyObject toma tiempo lineal en proporción al tamaño del archivo
    • Si se escriben muchos archivos en el lugar equivocado y luego hay que revertirlo, el proceso es muy lento
  • Obtener el listado de archivos es lento
    • El ancho de banda de lectura y escritura es muy alto, pero listar lo almacenado es mucho más lento
    • Incluso puede ser más lento que un sistema de archivos local lento
  • A cambio, la carga operativa es menor que en un sistema de archivos
    • Basta con definir el bucket y el nombre de la key; el resto lo resuelve la nube
    • Reduce la carga de tareas repetitivas como backups, replicación offsite y provisioning
    • El provisioning no aplica solo a la capacidad, sino también a las operaciones de IO

En interfaces entre organizaciones, los módulos profundos importan más

  • Que S3 haya sido la primera API de nube realmente popular se relaciona con las ventajas de una API profunda
  • Las APIs profundas son útiles para ocultar complejidad entre módulos dentro de un solo sistema, y son aún más importantes cuando la relación es costosa, como en la interacción entre dos empresas
  • Tradicionalmente, conectar sistemas informáticos entre empresas se llamaba integration, casi como sinónimo de dolor
  • Un gran software empresarial como SAP no es un módulo profundo
    • Casi toda la organización necesita entender SAP
    • Hay que ajustarlo continuamente con la forma existente de trabajar
    • Los proyectos de integración con SAP son caros, enormes y han acumulado repetidos fracasos
  • La complejidad interna de S3 no es necesariamente menor que la de una instalación de SAP
    • Amazon lo llamó “Simple Storage Service”, pero la complejidad real de S3 es grande
    • Incluye teoría de colas, contención de IO, sharding y muchos de los problemas que resuelve un sistema de archivos
  • Lo “simple” de S3 se parece más a una interfaz profunda que a una simplicidad real

Excepciones que sí encajan en S3 y limitaciones que siguen ahí

  • Esto no excluye el problema de que S3 pueda ser caro en relación con el caso de uso
  • Los conceptos de módulo profundo y módulo superficial vienen de A Philosophy of Software Design de John Ousterhout
  • También existen bases de datos diseñadas desde el inicio para usar la API de S3 como capa de almacenamiento
    • Snowflake es un ejemplo
    • Pero eso requiere una decisión de diseño desde el principio, no una portabilidad transparente
    • Snowflake es, al menos hasta 2016, un caso de una decisión tomada muy temprano
  • Las bases de datos no son las únicas que tienen dificultades en S3
    • Muchos formatos de archivo asumen un seek barato
    • Los archivos Zip son un ejemplo representativo de algo que funciona mejor en disco que en S3

Lo que deja a deber S3

  • La API de S3 es solo XML
    • JSON ya existía en 2006, pero en esa época XML dominaba
    • Es una lástima que Amazon, al pasar de SOAP a REST, no haya publicado una versión en JSON
  • Amazon también dejó de mantener el XSD schema
    • Uno de los beneficios clave de una API XML es precisamente el esquema, pero hoy la documentación estándar es el sitio web
  • Amazon no ofrece un entorno local de pruebas
    • En Python, para hacer pruebas serias, a veces se usa la librería moto
    • Aunque es una herramienta para probar un servicio comercial, moto la mantienen voluntarios
  • Amazon S3 soporta checksum, pero no viene activado por defecto
    • Amazon hace varias afirmaciones sobre su durabilidad
    • No se ha oído de problemas reales, pero tampoco se han visto casos donde esas afirmaciones hayan sido puestas a prueba
  • En el pasado, S3 tenía la trampa de la eventual consistency
    • Si se leía un archivo, se sobrescribía y luego se volvía a leer, todavía podía verse el contenido anterior
    • Ocurría ocasionalmente durante un corto periodo y generaba confusión
    • Otras implementaciones de S3 no copiaron esta característica, y Amazon la corrigió hace algunos años con strong read-after-write consistency

1 comentarios

 
GN⁺ 2024-03-11
Opiniones de Hacker News
  • La durabilidad de S3 puede parecer exagerada, pero la considero confiable y difícil de comparar con los sistemas de archivos tradicionales.
    La diferencia no está solo en el software, sino también en la infraestructura física y la cultura de seguridad; siento que el aislamiento de zonas de disponibilidad de AWS es mejor que el de otras nubes.
    Cuando trabajaba en S3, nos comparaban mucho en precio con GCP Blob Storage, pero Google podía poner los datos en el mismo edificio o en otra sala del mismo edificio, así que no era una comparación justa con la separación al estilo AWS.
    Toda la organización estaba extremadamente obsesionada con la integridad de los datos, ponía checksums en todo y se preparaba incluso para eventos grandes como desastres naturales.
    A la escala de S3, incluso se podía detectar bit rot como inversiones aleatorias de bits causadas por rayos gamma que golpean los platos de los discos duros; también se medían las tasas de falla por fabricante de disco y época de producción para reducir la posibilidad de pérdida de datos incluso si un lote específico salía defectuoso.
    Llegaría al punto de no guardar datos importantes en otro lugar, y yo mismo construí el sistema de despliegue de S3.

    • Me da curiosidad la experiencia en otros proveedores de almacenamiento.
      Esta explicación suena como elogiar a Cinnabon por hacer su propia masa; las cosas mencionadas son lo que normalmente haría cualquier empresa de almacenamiento.
      Poner checksums en todo es una función básica de muchos sistemas de archivos, y si en una computadora de casa se puede detectar bit rot y recibir alertas, por supuesto que un gran proveedor de almacenamiento lo hace.
      Rastrear tasas de falla por fabricante de disco también es común; las empresas de almacenamiento incluso publican reportes, y hasta en una organización de TI de 6 personas lo administrábamos con una hoja de cálculo.
      Fuera de AWS también ha habido mucha gente inteligente trabajando en almacenamiento desde mucho antes de que existiera AWS.
    • El aislamiento de zonas de disponibilidad de AWS no es mejor que el de todos los proveedores.
      Las cuentas con redundancia geográfica de rsync.net, por ejemplo, existen en distintos estados o países, como un almacenamiento principal en Fremont y uno secundario en Denver.
      Tampoco es correcto decir que S3 puede detectar bit rot por su escala; incluso corriendo ZFS en un servidor personal se detecta bien el bit rot a pequeña escala.
      [1] sede de he.net
    • Poner checksums a los datos no es tanto por paranoia, sino porque para ejecutar el algoritmo Reed-Solomon hay que saber qué bloques están inutilizables, así que es algo naturalmente necesario.
      Si hay suficientes eventos de corrupción de este tipo, también parece que podrían usarse como señal para “curar” el sistema moviendo bloques de datos individuales a otras máquinas.
      En general, las cosas mencionadas son bastante típicas en sistemas de almacenamiento y no son características exclusivas de S3.
    • No parece cierto que Google almacene los datos en el mismo edificio.
      Según la documentación de Google Cloud Storage, los datos se replican en varias zonas y cada zona se mapea a clústeres distintos.
      https://cloud.google.com/compute/docs/regions-zones/zone-vir...
    • Más que “créanme”, quisiera creer en resultados de pruebas.
      Me pregunto si existe un tercero neutral que haya verificado la durabilidad, integridad y consistencia de S3 con tanto rigor como Jepsen.
      Si alguien comparara rigurosamente los almacenamientos en la nube compatibles con S3, podrían salir a la luz problemas enormes y aterradores; quizá esa comparación ya exista.
  • Creo que lo realmente útil de S3 no es la velocidad de lectura/escritura, sino el listado.
    En buckets sin versiones o sin marcadores de borrado, listar un prefijo específico funciona prácticamente en tiempo constante, de modo que incluso en un bucket con 100 mil millones de objetos se pueden pedir 1000 claves en orden alfabético posteriores a una cadena arbitraria.
    Usar / como delimitador es solo el valor predeterminado; se puede usar cualquier carácter para obtener conjuntos de prefijos comunes, y los directorios en realidad no existen, solo parecen crearse cuando se necesitan.
    Gracias a esta característica, se pueden dividir los datos de varias maneras según los identificadores necesarios sin preocuparse por el rendimiento.
    Si el listado simplemente fuera lento, no permitiera consultas por prefijo de archivo y se volviera más lento en proporción al número de claves, como un sistema de archivos Unix tradicional, S3 no sería útil en absoluto.

    • No me convence mucho.
      La capacidad de obtener claves antes y después de un prefijo es lo básico de un índice de base de datos que existe desde los años 70, así que no me parece especialmente impresionante.
      Los casos de uso pueden ser distintos, pero muchas veces el listado de buckets era lo bastante lento como para estorbar, y en cuanto un bucket crece un poco, enumerar las claves tarda más que leerlas.
      Según recuerdo, el listado estaba por debajo de 1 Mbps, aunque ahora no tengo un bucket grande para probarlo.
    • La diferencia entre una jerarquía plana de claves lexicográficas y una jerarquía de sistema de archivos anidada por directorios queda clara con un ejemplo.
      Si existen claves de dir1/a/000000 a dir1/a/999999 y también dir1/b, en un sistema de archivos verdaderamente jerárquico ls dir1/ solo tiene que recorrer y devolver dos entradas: "a" y "b".
      En cambio, un almacén clave-valor con índice plano de cadenas sin manejo de delimitadores tiene que pasar por un millón de entradas de directorio, desde "a/00000" hasta "a/999999", antes de llegar a "b".
      Por eso, una jerarquía plana simple hace que listar el contenido de un directorio sea O(todos los hijos recursivos) en vez de O(hijos directos), como en un sistema de archivos real, y por lo tanto es mucho más lento.
      Sin embargo, si al algoritmo de listado se le informa un carácter delimitador como /, un trie de prefijos lexicográficos puede saltarse eficientemente el subárbol en el siguiente /.
      La documentación de Amazon S3 también indica que en el campo CommonPrefixes se omiten y resumen millones de claves anidadas en niveles más profundos.
      https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-...
      No he probado si la implementación real de verdad evita el recorrido o si recorre todo y solo reduce los resultados, pero espero que lo evite.
    • Desde XFS en 1993, los buenos sistemas de archivos UNIX influenciados por HPFS han implementado los directorios como alguna forma de B-tree.
      Por eso no se vuelven más lentos en proporción al número de entradas, y el listado basado en prefijos de archivo también es muy rápido.
    • Me parece que el 99% del uso de S3 consiste en obtener objetos por claves que ya se conocen.
      Ver el listado por prefijo como una función central se siente raro.
    • No sé si aquí estamos usando la misma definición de “tiempo constante”.
      Recibir 1000 claves en una sola llamada de red no garantiza nada sobre la complejidad del backend.
  • Hace poco, mientras retocaba un script de gestión de assets en S3, me sorprendió la velocidad de listado
    Un colega me dijo que hacía falta una caché de la lista de archivos y me mandó una caché precargada; al principio pensé que no podía ser realmente necesaria, pero al comprobarlo yo mismo vi que sí
    Hay alrededor de 100 mil directorios raíz para assets individuales, cada uno con 5 o 6 directorios y unos pocos archivos; en total probablemente hay menos de 1 millón de archivos, y la profundidad máxima es de unas 3 capas
    Listar estos archivos de forma recursiva tarda literalmente 15 minutos
    Probé varias sugerencias de Stack Overflow y ChatGPT para mejorar la velocidad, pero nada dio resultados significativos, y no entiendo por qué es tan lento
    No sé por qué Amazon no arregló esto; visto desde afuera, parecería que basta con poner unos cuantos B-tree en cada bucket
    Si es un problema difícil, me interesaría escuchar por qué

    • S3 es, fundamentalmente, un almacén clave-valor
      Que los objetos puedan verse como “directorios” es solo un filtro por prefijo; no es un sistema de archivos y tampoco existe el concepto de directorio
    • Me preocupa el uso de “recursivamente” y la larga explicación sobre “directorios” y “capas”
      La forma más rápida de listar objetos en S3 no necesita recursión en absoluto: simplemente se listan todos los objetos bajo un prefijo
      Si usas separadores de ruta para hacer pasar las claves de S3 por una estructura de carpetas y recorres “carpeta por carpeta”, se vuelve mucho más lento
      Al llamar a ListObjectsV2 no debes pasar delimiter; si no usas la función de separador, los “directorios” y las “capas” no afectan el rendimiento
      Para alcanzar el tiempo total que quieres, puedes dividir una operación de listado en listados paralelos sobre varios prefijos
    • Una consecuencia interesante de este problema es que eliminar un bucket de S3 no es sencillo
      No puedes eliminar un bucket que contiene objetos, y tampoco puedes pedirle a S3 de una sola vez que borre todos los objetos
      Debes enviar una solicitud de API de eliminación individual por cada objeto; para eso también debes enviar solicitudes que listen los objetos de a 1000, y esas llamadas de listado toman tiempo y cuestan dinero
      Este artículo resume bien la situación: https://cloudcasts.io/article/deleting-an-s3-bucket-costs-mo...
      Al final, la forma más rápida de deshacerse rápido de un bucket de S3 es eliminar la cuenta de AWS a la que pertenece
    • La razón puede ser mucho más mundana
      En una solicitud puedes listar 10 mil objetos, y para obtener los siguientes 10 mil necesitas el resultado de la solicitud anterior, así que todo es serial
      Para listar 1 millón de archivos se necesitan 100 solicitudes consecutivas; con solo 50 ms de ida y vuelta, eso ya son 5 segundos solo en round trips, sin contar el costo de construir la lista en una iteración plana
      El costo de listar 10 mil elementos es parecido al de una escritura, lo cual ya es bastante lento, y cada listado también podría ser una instantánea con consistencia fuerte, lo que agrega más costo
      Un B-tree no parece ayudar mucho salvo que estés recorriendo directorios, e incluso en ese caso es probable que el cuello de botella sean las operaciones de red y la API expuesta externamente
      En definitiva, listar archivos no es un caso de uso tan importante; normalmente se delega a S3 lo que se quiere hacer mediante funciones como el ciclo de vida de objetos, para que lo procese eficientemente en la capa interna del sistema de archivos
    • Pensar que dentro de un bucket de S3 hay directorios no es un buen modelo
      Todo son objetos, y la interfaz web solo muestra de forma agradable los prefijos separados por barras
      Cada objeto tiene una clave, y esa clave puede contener barras; si quieres, puedes pensar en cada segmento como un directorio
      Pero cuando intentas hacer las operaciones que normalmente harías sobre directorios, esa ilusión se rompe
  • Quienes crearon S3 sabían que no era un sistema de archivos, y creo que el nombre almacén de objetos buscaba explicar precisamente las diferencias señaladas en el artículo
    Que “los objetos estaban de moda” se refiere a los objetos como componentes de software que combinan código ejecutable y estado local, pero los ejemplos iniciales de S3 no iban de “serializar un objeto vivo y deserializarlo en otro proceso”
    Todos los ejemplos eran cosas como assets estáticos de sitios web, y en el mundo de las bases de datos de la época también se usaba el sentido de objeto en expresiones como “binary large object” o “blob”
    S3 se parecía más a un lugar para guardar cosas que no encajaban bien en una base de datos, y el hecho de que el listado fuera lento describe justo esa naturaleza, porque los casos de uso previstos al diseñarlo asumían que el índice del contenido estaba en algún otro lugar

    • El autor parece no saber que “almacén de objetos” es un término de sistemas de almacenamiento sin relación con la programación orientada a objetos
      https://en.wikipedia.org/wiki/Object_storage
    • Me preocupa que el autor parezca confundir la programación orientada a objetos con el almacenamiento de objetos
      Según la explicación de GCP, el almacenamiento de objetos es una arquitectura que divide datos no estructurados en objetos y los guarda en un entorno de datos estructuralmente plano
      https://cloud.google.com/learn/what-is-object-storage
      Es decir, lo central son datos no estructurados, una organización plana y operaciones de lectura y escritura sobre elementos completos
  • S3 no es un archivo, y mucho menos un sistema de archivos
    Lo que se espera de la abstracción de archivo es mutabilidad: debe ser posible editar partes de un archivo, ampliarlo, reducirlo y leer y escribir en offsets arbitrarios.
    Después de tomar un archivo, no debería ser necesario volver a subir hasta la raíz o a un concepto superior, pero S3 solo ofrece objetos inmutables sobre una lista mutable; para modificarlos, hay que copiarlos y volver a subirlos.
    La abstracción original de archivo consiste en encontrar sectores del disco y presentarlos al cliente como si fueran un búfer continuo; S3 resuelve otro problema.
    Mucha gente malinterpreta la buena idea de UNIX de que “todo es un archivo” como si significara que todo debe verse como un búfer virtual continuo.
    El punto realmente central es que existe un nodo hoja básico —sea un archivo u otro objeto que el sistema quiera mostrarle al proceso—, que todo, incluidos los directorios, puede listarse en directorios, y que hay un árbol recursivo.
    Lo que hace a un sistema de archivos no es el tipo de un nodo hoja en particular, sino el directorio.
    Agregar nuevos tipos de hojas, como sockets o framebuffers, es casi trivial y no daña esta idea, pero agregar otros tipos de contenedores, como listas, complica la estructura del sistema de archivos y rompe su coherencia conceptual.
    S3 no hace esas cosas, y está bien.
    Solo queremos guardar ahí cosas que no encajan en una base de datos y esperar que no sufran bit rot mientras no las miramos.
    Creo que el deseo de hacer que S3 parezca un sistema de archivos viene de que los clientes malinterpretan aquello en lo que S3 es bueno, y de que la gestión de producto aceptó esa confusión en vez de frenarla.

    • Estoy de acuerdo en que S3 no es un sistema de archivos.
      Una analogía más adecuada es la de un dispositivo de almacenamiento por bloques, aunque sería un dispositivo de bloques muy extraño, con tamaños de bloque arbitrarios y claves asociables.
      Un sistema de archivos es una abstracción montada encima de un dispositivo de almacenamiento por bloques, así que un “sistema de archivos S3” también debería ser una abstracción que use S3 como almacenamiento de bloques subyacente.
    • Me pregunto cómo encajan los sistemas de archivos de solo lectura con esta definición.
  • Un sistema de archivos es una abstracción construida sobre un dispositivo de bloques.
    Un dispositivo de bloques ofrece un enorme arreglo de bytes y permite leer/escribir por bloques, por ejemplo: “escribe estos 300 bytes en la posición 273041”.
    El propio dispositivo de bloques también es una abstracción construida sobre hardware real, de modo que “escribe estos 300 bytes” en realidad termina traduciéndose en acciones como “mueve la aguja del plato 2 a la posición 6”.
    S3 no es más que otra abstracción construida sobre almacenamiento bruto, y es estrictamente un almacén clave-objeto plano.
    Si necesitas funciones de sistema de archivos, impleméntalas en la app o usa un sistema de archivos.
    Si solo necesitas append, puedes rastrear una cadena de anexos en una base de datos y guardar los chunks en S3; si no encaja, usa otra cosa.
    Si necesitas copiar, puedes crear en la base de datos una nueva referencia al mismo objeto; si no encaja, usa otra cosa.
    S3 le funciona bien a mucha gente, así que no hay que intentar convertirlo en otra cosa.
    También habría que dejar de intentar cambiar el significado de términos ya establecidos en el campo: un sistema de archivos es un concepto explicado en los libros de texto, y S3 nunca afirmó ser un sistema de archivos.
    Estudiar un poco de diseño de sistemas operativos realmente ayuda, y además es divertido.

  • Hubo una discusión comparando la API object_store de Apache Arrow con Apache OpenDAL en https://github.com/apache/arrow-rs/issues/3888
    Apache OpenDAL es una biblioteca que ofrece una API similar a un sistema de archivos sobre varios backends, incluidos S3 y varios almacenamientos en la nube.
    Algunos sistemas de bases de datos, como GreptimeDB y Databend, usan OpenDAL como un mejor SDK de S3 para acceder a datos en almacenamiento en la nube.
    También existen Alluxio y JuiceFS como otras soluciones para administrar una interfaz similar a un sistema de archivos sobre S3, pero, a diferencia de Apache OpenDAL, requieren un despliegue separado y un servicio interno dedicado de metadatos.

    • No estoy muy seguro de si Alluxio podría reemplazarse por OpenDAL como capa de caché local para TrinoDB.
  • Al hablar de S3, también vale la pena mencionar Backblaze B2.
    Me gusta mucho porque cuesta tres veces menos que S3, y no tengo relación con Backblaze.

    • Backblaze B2 es barato, pero si lo usas en producción hay cosas que deberías incluir en el costo.
      Hay una ventana de mantenimiento semanal de 2 horas, de 11:30 a 13:30 PST; normalmente no hay downtime, pero a veces ocurre una caída total justo en medio del horario laboral de EE. UU.
      Cuando la tasa de errores subía a un nivel inutilizable, tenía que abrir un ticket de soporte; en los últimos años me pasó aproximadamente una vez al año.
      Soporte solo hace montones de preguntas, como si no tuviera logs de errores ni visibilidad de su lado, y no investiga bien el problema.
      También hay falsos éxitos, en los que responde que la subida fue exitosa, pero en realidad queda guardada en el sistema de B2 con 0 bytes, así que hay que verificar obligatoriamente las subidas incluso con código de éxito.
      Cuando aparecen vulnerabilidades de alta severidad, como la CVE de Log4j2, también pueden darse interrupciones largas, por ejemplo de 10 horas.
      El precio es excelente, pero no es un producto directamente comparable con servicios de almacenamiento en la nube más maduros.
    • En servicios alternativos, el punto clave siempre es que los datos son tan seguros como confiable sea esa empresa.
      Dicho eso, creo que se puede compensar en cierta medida con dos capas de backups externos.
    • B2 estuvo bien, pero no tanto como para usarlo pagando también el costo de direcciones IPv4.
      Es absurdo que, aunque se publicite como una solución multicloud, la situación en la que hay cargos por gateways NAT e IPv4 por todos lados prácticamente elimine la posibilidad de adoptarlo.
      Como mi uso era de muchas lecturas y pocas escrituras, podía ahorrar dinero incluso pagando el ancho de banda de B2, pero no si tenía que pasar por un gateway NAT64 o pagar una tarifa por hora para acceder a B2.
  • Es un buen artículo, y habría sido útil leerlo antes de empezar el recorrido de montar almacenamiento en la nube como FUSE con rclone mount.
    Tras varias iteraciones, rclone terminó con una capa VFS que adapta almacenamientos como S3, Google Cloud Storage, Azure Blob, OpenStack Swift y Oracle Object Storage a una capa de sistema de archivos parecida a POSIX, y el código real de rclone mount es una capa delgada encima de eso.
    La capa VFS tiene varios niveles de compatibilidad; en off solo hace caché de directorios.
    En este modo, como dice el artículo, no se puede leer y escribir el mismo archivo al mismo tiempo, no se puede escribir en medio de un archivo, y los archivos solo se pueden escribir de forma secuencial.
    Sorprendentemente, aun con esas restricciones, bastantes cosas funcionan bien.
    El siguiente nivel, writes, soporta la mayoría de las funciones POSIX que las apps quieren, como leer y escribir el mismo archivo al mismo tiempo y escribir en medio de un archivo, pero tiene el costo de crear una copia local del archivo y subirla de forma asíncrona cuando se cierra.
    La documentación de los modos de caché de VFS refleja bien las restricciones del artículo: https://rclone.org/commands/rclone_mount/#vfs-file-caching
    Básicamente, en S3 tampoco hay directorios reales, así que no se puede tener un directorio sin archivos, ni metadatos válidos como la hora de modificación de un directorio.
    Se pueden crear marcadores de directorio, archivos de 0 bytes que terminan en /, y muchas herramientas, incluido rclone, los soportan.
    Normalmente no tener directorios vacíos no es un gran problema, porque la capa VFS los simula y la mayoría de las apps pronto escriben algo dentro.
    Al final, convertir algo que se ve como S3 en algo que se ve como un sistema de archivos POSIX implica bastante trabajo, y detrás de comportamientos como renombrar archivos abiertos y casos límite complicados hay muchos trucos.
    Los comandos de bajo nivel move/sync/copy de rclone no hacen ese procesamiento y usan la API de S3 casi tal cual.
    Si pudiera cambiar una cosa de la API de S3, me gustaría que hubiera una opción para leer también los metadatos al listar.
    rclone guarda la hora de modificación de los archivos en los metadatos del objeto, pero no hay forma de leerlos en masa, así que tiene que hacer HEAD por cada objeto.
    O también estaría bien poder establecer el Last-Modified del objeto al subirlo.

    • Creo que quizá se podría rodear el problema guardando los metadatos en el propio nombre de la clave.
      El límite de longitud de clave es 1024, así que la cantidad de metadatos que se puede guardar es limitada, pero incluso considerando la ruta del archivo, es bastante holgado.
      Se podría usar un separador inválido en rutas normalizadas, como //, y dejar algo como /path/to/file.txt//mtime=1710066090.
      Todavía se podría traer el “directorio” por prefijo, y traer el archivo directamente usando // como si fuera un prefijo.
      Pero este formato probablemente dañaría mucho la compatibilidad con otro software.
    • Estoy de acuerdo en que sería bueno tener una opción para incluir metadatos en el listado.
      En MinIO agregaron un parámetro “secreto” metadata=true que incluye metadatos y tags en el listado cuando se tienen los permisos adecuados.
      Como es una extensión, no se puede usar de forma confiable, pero rclone podría intentarlo siempre y usarlo si está disponible.
      También se pueden usar archivos de 0 bytes que terminan en /, pero los propios prefijos compartidos del listado también pueden considerarse directorios.
      Eso trae la ventaja y desventaja de que los directorios no tienen estado y no pueden existir si no hay objetos dentro.
      Poder establecer Last-Modified al subir reduciría las restricciones del cliente, aunque también tiene ventajas que se base en la hora del servidor.
      En la replicación o el espejado del lado del cliente hay que lidiar con las mismas restricciones.
      Personalmente, mi mayor queja es que no existe un HeadObjectVersions que devuelva la información de versiones de un solo objeto.
      ListObjectVersions no puede saber si un prefijo dado es realmente un prefijo o una clave de objeto, así que siempre termina siendo una operación sobre todo el clúster.
      AWS agregó hace poco GetObjectAttributes, pero no incluyó ahí la información de versiones, que habría encajado muy bien.
  • El “Simple” de S3 no significa “no profundo”, sino que usa la menor cantidad de piezas necesarias para cumplir los requisitos.
    Si se necesita un almacenamiento de objetos distribuido, centralizado, replicado, de alta disponibilidad, alta durabilidad, alto ancho de banda, baja latencia, consistencia fuerte, síncrono y escalable, además de una API HTTP REST, creo que es difícil hacerlo más simple que S3.
    AWS S3 ha sumado muchas funciones durante mucho tiempo, pero el comportamiento básico se mantiene igual.

    • En los términos que usa el artículo, “las piezas mínimas necesarias” es justamente lo que significa profundo.
      Según 『A Philosophy of Software Design』 de Ousterhout, simple significa no complejo, y “Simple Made Easy” de Rich Hickey va en la misma línea.
      En cambio, “profundo” significa ofrecer internamente muchas funciones complejas mediante una interfaz pequeña, así que a S3 le queda mejor esa expresión que “simple”.
      No es lo mismo que simple en el sentido de que S3 no tenga gran cosa.
      https://www.infoq.com/presentations/Simple-Made-Easy/
    • Siguiendo la expresión del artículo, también se podría decir que la simplicidad casi implica profundidad y una interfaz estrecha.