2 pontos por GN⁺ 2024-03-11 | 1 comentários | Compartilhar no WhatsApp
  • O Amazon S3 é uma tecnologia inicial de nuvem lançada em 2006; é forte para armazenamento de arquivos, mas não é um sistema de arquivos que substitui diretamente a API de arquivos do Unix
  • A API de arquivos do Unix se parece mais com um módulo profundo que esconde buffering, page cache, permissões e escalonamento de IO atrás de uma interface estreita como open, read, write, seek e close
  • O S3 parece simples, centrado em GetObject e PutObject, mas só permite leitura parcial via Range e não suporta sobrescrita parcial
  • Bancos de dados como Postgres, SQLite, MySQL, MongoDB e Elasticsearch dependem de sobrescrita em nível de página, então subir um arquivo do SQLite ou DuckDB diretamente para o S3 dificilmente funciona bem fora de datasets pequenos
  • Alta largura de banda de leitura e escrita e baixa carga operacional são pontos fortes do S3, mas é preciso considerar junto limitações como ausência de rename/move, listagem lenta, API apenas em XML e falta de ambiente local de testes

O S3 armazena arquivos, mas não é um sistema de arquivos

  • O S3 é uma tecnologia inicial de nuvem lançada em 2006 e, seguindo a terminologia da época, foi chamado de “object store”
  • Na prática, ele é amplamente usado como armazenamento de arquivos, mas entendê-lo como algo como “Amazon Cloud Filesystem” é apenas parcialmente correto
  • Ele armazena arquivos muito bem, mas não consegue substituir diretamente o comportamento e as expectativas de um sistema de arquivos tradicional

A API de arquivos do Unix e os módulos profundos

  • O núcleo da API de arquivos do Unix pode ser resumido nestas cinco chamadas
    • open(filepath): abre o arquivo
    • file.read(size=100): lê a partir da posição atual e avança a posição
    • file.write("hello, world"): escreve na posição atual e avança a posição
    • file.seek(94): move a posição para um byte específico
    • file.close(): fecha o arquivo
  • Essas chamadas representam a parte central do conjunto real de system calls e ficam próximas do mínimo necessário para ler e escrever arquivos
  • Como muita coisa acontece por trás dessa interface estreita, a API de arquivos do Unix pode ser vista como um módulo profundo (deep module)
    • buffering e page cache
    • tratamento de fragmentação
    • gerenciamento de permissões
    • escalonamento de IO
    • até recursos como wear-levelling em cartões SD beneficiam o usuário sem que ele precise se preocupar diretamente com isso

Módulos rasos, YAML e ORM

  • Um módulo raso tem uma superfície de API relativamente grande em comparação com o volume de trabalho que ele realmente faz
  • Hoje, um dos indícios para reconhecer módulos rasos é quando a interface é YAML
    • YAML parece uma linguagem de marcação, mas na prática costuma ser usado como uma sintaxe reutilizável sobre a qual quase qualquer semântica pode ser colocada
    • Na área de DevOps, YAML muitas vezes funciona como uma “linguagem de programação”
    • Se uma mini linguagem em YAML oferece estruturas de repetição, há chance de ela ser Turing completa
  • Módulos rasos nem sempre são ruins
    • Um ORM SQL é, em essência, uma abstração vazante, e é difícil usá-lo sem entender SQL
    • Em alguns casos, um módulo raso pode ser a melhor forma possível
  • Em condições iguais, um módulo mais profundo é melhor

A API do S3 é simples, mas diferente da API de arquivos

  • A API de arquivos do Unix se consolidou no começo dos anos 1970 e, por compatibilidade, a interface foi mantida enquanto a implementação interna mudou várias vezes
  • O Amazon S3 não reimplementa a API de sistema de arquivos do Unix
  • As operações básicas do S3 só correspondem parcialmente à API de arquivos do Unix
    • GetObject(Bucket, Key, Range=None): lê o objeto inteiro ou parte dele
    • PutObject(Bucket, Key): grava o objeto inteiro
  • Há o conceito adicional de bucket, mas olhando a proporção entre interface e funcionalidade, dá para dizer que o S3 é mais simples que a API de arquivos do Unix
  • A diferença decisiva é a ausência de sobrescrita parcial
    • O argumento Range de GetObject permite ler apenas parte de um objeto
    • Não é possível sobrescrever apenas uma parte do objeto
    • A sobrescrita precisa ser feita no arquivo inteiro
  • Por causa dessa diferença, o S3 se encaixa bem apenas em parte dos casos de uso tradicionais de arquivos

Bancos de dados são difíceis de portar diretamente para o S3

  • Vários bancos de dados armazenam dados em arquivos sobre um sistema de arquivos
    • O Postgres mantém de 2 a 3 arquivos por tabela, além de vários arquivos de administração
    • O SQLite é conhecido por armazenar todos os dados em um único arquivo
    • MySQL, MongoDB e Elasticsearch também armazenam dados em arquivos
  • O problema é que os bancos de dados em geral dependem de sobrescrita parcial em nível de página
    • Os dados normalmente são armazenados em páginas como 4 KB ou 8 KB
    • Um arquivo heap pode conter milhares de páginas
    • As páginas são parcialmente sobrescritas para gravar os dados necessários
  • Se um banco SQLite ficar no S3, cada escrita exigirá reescrever o arquivo inteiro do banco de dados
  • O S3 consegue lidar rapidamente com escritas grandes, mas, fora os datasets mais pequenos, a estratégia de sobrescrever o arquivo inteiro toda vez é difícil de sustentar
  • Reescrever o arquivo do banco a cada operação também dificulta aproveitar a integridade transacional implementada pelo autor do banco de dados
  • No S3, a última escrita vence

O que o S3 faz bem e o que não faz

  • O ponto forte do S3 é que a largura de banda de leitura e escrita é muito alta
    • Não é difícil encontrar relatos online de mais de 10 GB/s de leitura ou escrita no S3
    • Já houve caso de operações de escrita no S3 saturarem a rede do escritório de um cliente do setor financeiro
  • Além da ausência de sobrescrita parcial, há outras limitações em relação a um sistema de arquivos
  • O S3 não tem operação de rename ou move
    • A mudança de nome é feita com CopyObject seguido de DeleteObject
    • CopyObject leva tempo linear proporcional ao tamanho do arquivo
    • Reverter uma grande quantidade de arquivos escritos no lugar errado pode ser muito lento
  • A listagem de arquivos é lenta
    • A largura de banda de leitura e escrita é muito alta, mas listar os itens armazenados é bem mais lento
    • Pode ser até mais lento que um sistema de arquivos local lento
  • Em compensação, a carga operacional é menor do que em um sistema de arquivos
    • Basta definir o nome do bucket e da key, e o restante fica com a nuvem
    • Isso reduz a carga de tarefas repetitivas como backup, replicação off-site e provisionamento
    • O provisionamento vale não só para capacidade, mas também para operações de IO

Em interfaces entre organizações, módulos profundos importam ainda mais

  • O fato de o S3 ter sido a primeira API de nuvem realmente popular se conecta com as vantagens de uma API profunda
  • APIs profundas são úteis para esconder complexidade entre módulos de um mesmo sistema e se tornam ainda mais importantes em relações de alto custo, como a interação entre duas empresas
  • A conexão entre sistemas computacionais de empresas diferentes tradicionalmente é chamada de integração e costuma ser tratada quase como sinônimo de dor
  • Softwares corporativos grandes como SAP não são módulos profundos
    • Quase toda a organização precisa entender o SAP
    • É preciso ajustar continuamente as formas de trabalho existentes
    • Projetos de integração com SAP são caros, enormes e têm histórico recorrente de fracasso
  • A complexidade interna do S3 não é necessariamente menor que a de uma instalação de SAP
    • A Amazon chamou o S3 de “Simple Storage Service”, mas a complexidade real do S3 é grande
    • Ela inclui teoria de filas, contenção de IO, sharding e vários problemas que sistemas de arquivos precisam resolver
  • O “simple” do S3 está mais próximo de uma interface profunda do que de simplicidade literal

Exceções que combinam com o S3 e limitações que permanecem

  • Isso não exclui o problema de o S3 ser caro para alguns casos de uso
  • Os conceitos de módulo profundo e módulo raso vêm de A Philosophy of Software Design, de John Ousterhout
  • Há bancos de dados projetados desde o início para usar a API do S3 como camada de armazenamento
    • Snowflake é um exemplo
    • Mas isso exige uma decisão de arquitetura tomada desde o começo, não uma portabilidade transparente
    • O Snowflake, pelo menos até 2016, é um caso de quem tomou essa decisão muito cedo
  • Não são só bancos de dados que sofrem no S3
    • Muitos formatos de arquivo assumem seek barato
    • Arquivos Zip são um exemplo típico de algo que tem desempenho melhor em disco do que no S3

Pontos frustrantes no S3

  • A API do S3 é apenas XML
    • JSON já existia em 2006, mas naquela época o XML ainda dominava
    • É uma pena que a Amazon não tenha lançado uma versão em JSON ao migrar de SOAP para REST
  • A Amazon também parou de manter o schema XSD
    • Um dos principais benefícios de uma API em XML é justamente o schema, mas hoje a documentação padrão é um site
  • A Amazon não oferece um ambiente local de testes
    • Em Python, é comum usar a biblioteca moto para fazer testes mais sérios
    • Mesmo sendo uma ferramenta importante para testar um serviço comercial, o moto é mantido por voluntários
  • O Amazon S3 oferece suporte a checksum, mas isso não vem ativado por padrão
    • A Amazon faz várias afirmações sobre durabilidade
    • Nunca ouvi relatos de um problema real, mas também nunca vi esses argumentos sendo efetivamente testados
  • No passado, o S3 tinha a armadilha da consistência eventual
    • Se você lesse um arquivo, o sobrescrevesse e lesse de novo, ainda poderia ver o conteúdo antigo
    • Isso acontecia ocasionalmente por curtos períodos e causava confusão
    • Outras implementações de S3 não copiaram essa característica, e a Amazon também a corrigiu alguns anos atrás com strong read-after-write consistency

1 comentários

 
GN⁺ 2024-03-11
Opiniões no Hacker News
  • A durabilidade do S3 pode parecer exagerada, mas é confiável, e acho difícil compará-la com sistemas de arquivos tradicionais
    A diferença não está só no software, mas também na infraestrutura física e na cultura de segurança; sinto que o isolamento de zonas de disponibilidade da AWS é melhor que o de outras nuvens
    Quando eu trabalhava no S3, havia muitas comparações de preço com o GCP Blob Storage, mas o Google podia colocar os dados no mesmo prédio, ou em outra sala do mesmo prédio, então não era uma comparação justa com a separação no estilo da AWS
    A organização inteira era extremamente obcecada por integridade de dados, colocava checksums em tudo e se preparava até para grandes eventos como desastres naturais
    Na escala do S3, era possível detectar até bit rot, como inversões aleatórias de bits causadas por raios gama atingindo pratos de discos rígidos; também mediam taxas de falha por fabricante de disco e por época de produção, reduzindo a possibilidade de perda de dados mesmo que um lote específico desse problema
    Chego a dizer que não armazenaria dados importantes em outro lugar; eu mesmo construí o sistema de implantação do S3

    • Fico curioso sobre a experiência em outras empresas de armazenamento
      Essa explicação soa como elogiar a Cinnabon por fazer a própria massa, mas as coisas mencionadas são o que uma empresa de armazenamento normalmente faz
      Colocar checksums em tudo é um recurso básico de muitos sistemas de arquivos, e se até um computador doméstico consegue detectar bit rot e enviar alertas, uma grande empresa de armazenamento obviamente faz isso
      Acompanhar taxas de falha por fabricante de disco também é comum; empresas de armazenamento até publicam relatórios, e mesmo uma organização de TI com 6 pessoas fazia esse controle em planilhas
      Fora da AWS também houve muita gente inteligente trabalhando com armazenamento, muito antes de a AWS existir
    • O isolamento de zonas de disponibilidade da AWS não é melhor que o de todos os fornecedores
      As contas com redundância geográfica da rsync.net existem, por exemplo, em estados ou países diferentes, como armazenamento primário em Fremont e secundário em Denver
      Também não é correto dizer que o S3 consegue detectar bit rot por causa da escala; mesmo rodando ZFS em um servidor pessoal, é possível detectar bit rot muito bem em pequena escala
      [1] sede da he.net
    • Colocar checksums nos dados não é tanto por paranoia; é algo naturalmente necessário porque, para rodar o algoritmo Reed-Solomon, é preciso saber quais blocos estão inutilizáveis
      Se houver eventos de corrupção suficientes, imagino que isso também sirva como sinal para “curar” o sistema movendo blocos de dados individuais para outras máquinas
      No geral, as coisas mencionadas são bastante típicas em sistemas de armazenamento e não são características exclusivas do S3
    • A afirmação de que o Google armazena dados no mesmo prédio não parece verdadeira
      Segundo a documentação do Google Cloud Storage, os dados são replicados em várias zonas, e cada zona é mapeada para clusters diferentes
      https://cloud.google.com/compute/docs/regions-zones/zone-vir...
    • Em vez de “acredite”, eu gostaria de acreditar em resultados de testes
      Fico curioso se existe um terceiro neutro que tenha verificado a durabilidade, a integridade e a consistência do S3 com tanto rigor quanto o Jepsen
      Se alguém comparasse rigorosamente armazenamentos em nuvem compatíveis com S3, talvez problemas assustadores e grandes viessem à tona; ou talvez essa comparação já exista
  • Acho que o realmente útil no S3 é a listagem, mais do que a velocidade de leitura/escrita
    Em buckets sem versionamento ou sem marcadores de exclusão, listar um prefixo específico funciona praticamente em tempo constante, de modo que, mesmo em um bucket com 100 bilhões de objetos, é possível pedir as 1000 chaves em ordem alfabética que vêm depois de uma string arbitrária
    Usar / como delimitador é apenas o padrão; é possível usar qualquer caractere para obter um conjunto de prefixos comuns, e diretórios não existem de fato, apenas parecem ser criados quando necessário
    Graças a essa característica, é possível particionar dados de várias maneiras com base nos identificadores necessários, sem se preocupar com desempenho
    Se a listagem fosse simplesmente lenta, não permitisse consultas por prefixo de arquivo e ficasse mais lenta proporcionalmente ao número de chaves, como em um sistema de arquivos Unix tradicional, o S3 não seria nem um pouco útil

    • Não acho muito convincente
      A capacidade de obter chaves antes e depois de um prefixo é algo básico de índices de banco de dados desde a década de 1970, então não é especialmente impressionante
      Os casos de uso podem ser diferentes, mas muitas vezes a listagem de buckets era lenta a ponto de atrapalhar, e, quando o bucket cresce um pouco, listar as chaves leva mais tempo do que lê-las
      Pelo que me lembro, a listagem ficava abaixo de 1 Mbps, mas não tenho um bucket grande para testar agora
    • A diferença entre uma hierarquia plana de chaves lexicográficas e uma hierarquia de sistema de arquivos aninhada por diretórios fica clara com um exemplo
      Quando há itens de dir1/a/000000 até dir1/a/999999 e existe dir1/b, em um sistema de arquivos realmente hierárquico, ls dir1/ só precisa percorrer e retornar dois itens: "a" e "b"
      Já um armazenamento chave-valor com índice de strings plano e sem tratamento de delimitador precisa passar por 1 milhão de entradas de diretório, de "a/00000" até "a/999999", antes de chegar a "b"
      Por isso, numa hierarquia plana simples, listar o conteúdo de um diretório vira O(todos os filhos recursivos), e não O(filhos diretos), como em um sistema de arquivos real, ficando muito mais lento
      Porém, se você informa ao algoritmo de listagem um caractere delimitador como /, a árvore de prefixos lexicográficos pode pular com eficiência a subárvore no próximo /
      A documentação do Amazon S3 também afirma que o campo CommonPrefixes pula e resume milhões de chaves aninhadas em níveis mais profundos
      https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-...
      Não testei se a implementação real realmente evita a varredura ou apenas reduz os resultados depois de varrer, mas espero que evite
    • Desde o XFS, em 1993, bons sistemas de arquivos UNIX influenciados pelo HPFS implementam diretórios como algum tipo de B-tree
      Por isso, eles não ficam lentos proporcionalmente ao número de entradas, e listagens baseadas em prefixo de arquivo também são muito rápidas
    • Acho que 99% do uso do S3 é buscar objetos por chaves já conhecidas
      Parece estranho tratar a listagem por prefixo como funcionalidade central
    • Não sei se estamos usando a mesma definição de “tempo constante” aqui
      O fato de receber 1000 chaves em uma única chamada de rede não garante nada sobre a complexidade no backend
  • Recentemente, ao mexer em um script de gerenciamento de ativos no S3, fiquei surpreso com a velocidade de listagem
    Um colega disse que seria necessário ter um cache da lista de arquivos e me enviou um cache pré-preenchido; no início achei que não havia como isso ser realmente necessário, mas, ao verificar por conta própria, vi que era diferente
    Há cerca de 100 mil diretórios raiz para ativos individuais, cada um com 5 a 6 diretórios e alguns poucos arquivos; no total, provavelmente há menos de 1 milhão de arquivos, e a profundidade máxima é de cerca de 3 níveis
    Listar esses arquivos recursivamente levou literalmente 15 minutos
    Tentei várias sugestões do Stack Overflow e do ChatGPT para melhorar a velocidade, mas nada deu resultado significativo, e não entendo por que é tão lento
    Não sei por que a Amazon não corrigiu isso; visto de fora, parece que bastaria anexar algumas B-trees a cada bucket
    Se for um problema difícil, o motivo deve ser interessante, então gostaria de ouvir a explicação

    • O S3 é, fundamentalmente, um armazenamento chave-valor
      O fato de ser possível ver objetos como “diretórios” é apenas um filtro por prefixo; não é um sistema de arquivos e não existe o conceito de diretório
    • A expressão “recursivamente” e a explicação longa sobre “diretórios” e “níveis” me preocupam
      A forma mais rápida de listar objetos no S3 não exige recursão alguma: basta listar todos os objetos sob um prefixo
      Se você usa separadores de caminho para fingir que chaves do S3 têm uma estrutura de pastas e itera “pasta por pasta”, fica muito mais lento
      Ao chamar ListObjectsV2, não se deve passar delimiter; se você não usar o recurso de delimitador, “diretórios” e “níveis” não afetam o desempenho
      Para atingir o tempo total desejado, basta dividir uma única operação de listagem em listagens paralelas sobre vários prefixos
    • Uma consequência interessante desse problema é que excluir um bucket S3 não é simples
      Não é possível excluir um bucket que contém objetos, e também não dá para dizer ao S3, de uma vez só, para apagar todos os objetos
      É preciso enviar uma requisição de API de exclusão separada para cada objeto; para isso, também é preciso enviar requisições que listam os objetos de 1000 em 1000, e essas chamadas de listagem levam tempo e também custam dinheiro
      Este texto resume bem a situação: https://cloudcasts.io/article/deleting-an-s3-bucket-costs-mo...
      No fim, a forma mais rápida de se livrar rapidamente de um bucket S3 é excluir a conta AWS à qual esse bucket pertence
    • O motivo pode ser bem mais banal
      Uma única requisição pode listar 10 mil objetos, e para obter os próximos 10 mil é preciso ter o resultado da requisição anterior, então tudo é serial
      Para listar 1 milhão de arquivos, são necessárias 100 requisições consecutivas; mesmo que o tempo de ida e volta seja de apenas 50 ms, só as viagens de rede somam 5 segundos, sem contar o custo de montar a própria lista em uma iteração plana
      O custo de listar 10 mil itens é parecido com o custo de escrita, o que por si só já é relativamente lento, e cada listagem também pode ser um snapshot com consistência forte, o que adicionaria mais custo
      B-trees provavelmente não ajudariam muito, a menos que você estivesse percorrendo diretórios; mesmo nesse caso, o gargalo provavelmente seriam as operações de rede e a API exposta externamente
      No fim das contas, listar arquivos não é um caso de uso tão importante; normalmente, delega-se ao S3 o trabalho desejado por meio de recursos como ciclo de vida de objetos, para que ele processe isso de forma eficiente na camada interna de sistema de arquivos
    • Pensar que há diretórios dentro de um bucket S3 não é um bom modelo
      Tudo são objetos, e a interface web apenas apresenta de forma agradável os prefixos separados por barras
      Cada objeto tem uma chave, e essa chave pode conter barras; se quiser, você pode pensar confortavelmente em cada segmento como um diretório
      Mas, quando você tenta fazer as operações que normalmente faria em diretórios, essa ilusão se desfaz
  • As pessoas que criaram o S3 sabiam que ele não era um sistema de arquivos, e acredito que o nome armazenamento de objetos era uma tentativa de explicar as diferenças apontadas no texto
    Quando se diz que “objetos estavam em alta”, isso se refere a objetos como componentes de software que combinam código executável e estado local, mas os exemplos iniciais do S3 não eram do tipo “serializar um objeto vivo e depois desserializá-lo em outro processo”
    Os exemplos eram todos coisas como ativos estáticos de sites, e, na área de bancos de dados da época, o sentido de objeto também aparecia em expressões como “binary large object” ou “blob”
    O S3 era mais um lugar para armazenar coisas que eram inconvenientes de colocar em um banco de dados, e o fato de a listagem ser lenta explica exatamente essa natureza, já que, no projeto inicial, os casos de uso de lançamento presumiam que o índice de conteúdo estivesse em algum outro lugar

    • O autor parece não saber que “armazenamento de objetos” é um termo de sistemas de armazenamento, sem relação com programação orientada a objetos
      https://en.wikipedia.org/wiki/Object_storage
    • Preocupa-me que o autor pareça estar confundindo programação orientada a objetos com armazenamento de objetos
      Segundo a explicação do GCP, armazenamento de objetos é uma arquitetura que divide dados não estruturados em objetos e os armazena em um ambiente de dados estruturalmente plano
      https://cloud.google.com/learn/what-is-object-storage
      Ou seja, o essencial são dados não estruturados, organização plana e operações de leitura e escrita sobre itens inteiros
  • S3 não é um arquivo, muito menos um sistema de arquivos
    O que se espera da abstração de arquivo é a possibilidade de alteração: editar partes de um arquivo, aumentá-lo, reduzi-lo e ler e escrever em offsets arbitrários
    Depois de obter um arquivo, não deveria ser necessário voltar à raiz ou a um conceito superior; já o S3 apenas oferece objetos imutáveis sobre uma lista mutável, e, para alterar, é preciso copiar e enviar de novo
    A abstração original de arquivo consiste em localizar setores do disco e apresentá-los ao cliente como um buffer contínuo; o S3 resolve outro problema
    Muita gente interpreta mal a boa ideia do UNIX de que “tudo é arquivo”, como se significasse que tudo deve parecer um buffer virtual contínuo
    O ponto realmente central é que há nós-folha básicos, sejam arquivos ou outros objetos que o sistema queira expor a processos, que tudo — incluindo diretórios — pode ser listado em diretórios, e que existe uma árvore recursiva
    O que faz um sistema de arquivos não é o tipo de um nó-folha específico, e sim o diretório
    Adicionar novos tipos de folha, como sockets ou framebuffers, é quase trivial e não prejudica essa ideia; mas adicionar outro tipo de contêiner, como listas, complica a estrutura do sistema de arquivos e quebra a consistência conceitual
    O S3 não faz essas coisas, mas tudo bem
    Ele serve apenas para guardar coisas que não se encaixam em um banco de dados e torcer para que não sofram bit rot enquanto não estão sendo vistas
    Acho que o desejo de transformar o S3 em algo parecido com um sistema de arquivos vem do fato de os clientes entenderem mal aquilo em que o S3 é bom, e de a gestão de produto aceitar esse mal-entendido em vez de bloqueá-lo

    • Concordo que o S3 não é um sistema de arquivos
      Uma analogia mais adequada é um dispositivo de armazenamento em blocos, só que mais próximo de um dispositivo de blocos muito estranho, em que o tamanho dos blocos é arbitrário e eles podem ter chaves
      Como um sistema de arquivos é uma abstração construída sobre um dispositivo de armazenamento em blocos, um “sistema de arquivos S3” também deveria ser uma abstração colocada sobre o S3 tratado como armazenamento de blocos subjacente
    • Fico curioso sobre como sistemas de arquivos somente leitura se encaixam nessa definição
  • Um sistema de arquivos é uma abstração construída sobre um dispositivo de blocos
    Um dispositivo de blocos fornece um enorme array de bytes e permite leitura/escrita em blocos, por exemplo “escreva estes 300 bytes na posição 273041”
    O próprio dispositivo de blocos também é uma abstração construída sobre o hardware real, então “escreva estes 300 bytes” na prática leva a operações como “mova a agulha do prato 2 para a posição 6”
    O S3 é apenas outra abstração construída sobre armazenamento bruto, e é estritamente um armazenamento chave-objeto plano
    Se você precisa de funcionalidades de sistema de arquivos, implemente-as na aplicação ou use um sistema de arquivos
    Se só precisa de append, acompanhe uma cadeia de acréscimos em um banco de dados e armazene os chunks no S3; se não servir, use outra coisa
    Se precisa de cópia, crie uma nova referência para o mesmo objeto no banco de dados; se não servir, use outra coisa
    O S3 funciona bem para muita gente, então não se deve tentar transformá-lo em outra coisa
    Também deveríamos parar de tentar mudar o significado de termos já estabelecidos da área; sistema de arquivos é um conceito explicado em livros-texto, e o S3 nunca afirmou ser um sistema de arquivos
    Estudar um pouco de projeto de sistemas operacionais ajuda muito e também é divertido

  • Houve uma discussão comparando a API object_store do Apache Arrow com a do Apache OpenDAL em https://github.com/apache/arrow-rs/issues/3888
    O Apache OpenDAL é uma biblioteca que fornece uma API semelhante a sistema de arquivos sobre vários backends, incluindo S3 e diversos armazenamentos em nuvem
    Alguns sistemas de banco de dados, como GreptimeDB e Databend, usam o OpenDAL como uma espécie de SDK S3 melhor para acessar dados em armazenamentos em nuvem
    Também existem Alluxio e JuiceFS como outras soluções para gerenciar uma interface semelhante a sistema de arquivos sobre o S3, mas, ao contrário do Apache OpenDAL, elas exigem uma implantação separada e um serviço interno de metadados dedicado

    • Não sei bem se seria possível substituir o Alluxio pelo OpenDAL como camada de cache local para o TrinoDB
  • Ao falar de S3, vale mencionar também o Backblaze B2
    Gosto bastante porque é 3 vezes mais barato que o S3, e não tenho relação com a Backblaze

    • O Backblaze B2 é barato, mas, se for usado em produção, há coisas que precisam entrar na conta
      Há uma janela de manutenção semanal de 2 horas, das 11:30 às 13:30 PST; normalmente não há downtime, mas às vezes ocorre uma falha total bem no meio do horário comercial dos EUA
      Quando a taxa de erros subia a um nível inutilizável, era preciso abrir um ticket de suporte, e isso aconteceu cerca de uma vez por ano nos últimos anos
      O suporte só faz inúmeras perguntas, como se não tivesse logs de erro ou visibilidade do próprio lado, e não investiga o problema adequadamente
      Também há falsos sucessos, em que a resposta diz que o upload foi bem-sucedido, mas na prática ele é salvo no sistema B2 com 0 byte; por isso, é indispensável verificar o upload mesmo com código de sucesso
      Quando aparece uma vulnerabilidade de alta gravidade, como a CVE do Log4j2, também podem ocorrer indisponibilidades longas, como uma interrupção de 10 horas
      O preço é excelente, mas não é um produto diretamente comparável a serviços de armazenamento em nuvem mais maduros
    • Em serviços alternativos, o ponto central é sempre que os dados são seguros apenas na medida em que se pode confiar naquela empresa
      Ainda assim, acho que duas camadas de backup externo conseguem compensar isso em certa medida
    • O B2 era bom, mas não a ponto de valer a pena pagar também pelo custo de endereços IPv4
      É absurdo que, mesmo se promovendo como uma solução multicloud, a situação em que taxas de gateway NAT e de IPv4 aparecem em todos os lugares praticamente inviabilize a adoção
      Como meu uso tinha muitas leituras e poucas escritas, eu conseguiria economizar mesmo pagando a taxa de largura de banda do B2, mas não se tiver que passar por um gateway NAT64 ou pagar por hora para acessar o B2
  • É um bom texto, e teria sido útil lê-lo antes de começar a jornada de montar armazenamento em nuvem via FUSE com rclone mount
    Depois de várias iterações, o rclone ganhou uma camada VFS que adapta armazenamentos como S3, Google Cloud Storage, Azure Blob, OpenStack Swift e Oracle Object Storage a uma camada de sistema de arquivos meio parecida com POSIX, e o código real de rclone mount é uma camada fina em cima disso
    A camada VFS tem vários níveis de compatibilidade; em off, ela só faz cache de diretórios
    Nesse modo, como o texto diz, não dá para ler e escrever o mesmo arquivo ao mesmo tempo, não dá para escrever no meio de um arquivo, e arquivos só podem ser escritos sequencialmente
    Surpreendentemente, mesmo com essas restrições, bastante coisa funciona bem
    O nível seguinte, writes, dá suporte à maioria das funcionalidades POSIX que os apps querem, como ler e escrever o mesmo arquivo ao mesmo tempo e escrever no meio de arquivos, mas ao custo de criar uma cópia local do arquivo e enviá-la de forma assíncrona quando ele é fechado
    A documentação dos modos de cache do VFS reflete bem as limitações do texto: https://rclone.org/commands/rclone_mount/#vfs-file-caching
    Basicamente, no S3 também não existem diretórios de verdade, então não dá para ter um diretório sem arquivos, nem metadados válidos em diretórios, como horário de modificação
    É possível criar um marcador de diretório, um arquivo de 0 byte terminado em /, e muitas ferramentas, incluindo o rclone, dão suporte a isso
    Normalmente não é um grande problema não haver diretórios vazios, porque a camada VFS os simula, e a maioria dos apps logo escreve alguma coisa dentro deles
    No fim, transformar algo que parece S3 em algo que pareça um sistema de arquivos POSIX dá bastante trabalho, e há muita prestidigitação por trás de comportamentos como renomear arquivos abertos e de casos de borda complicados
    Os comandos de baixo nível move/sync/copy do rclone não fazem esse tratamento e usam a API do S3 quase diretamente
    Se eu pudesse mudar uma coisa na API do S3, gostaria que houvesse uma opção para ler também os metadados ao listar objetos
    O rclone armazena o horário de modificação dos arquivos nos metadados dos objetos, mas não há como lê-los em massa, então é preciso fazer um HEAD para cada objeto
    Ou então seria bom poder definir o Last-Modified do objeto no upload

    • Imagino que talvez dê para contornar isso armazenando os metadados no próprio nome da chave
      O limite de comprimento da chave é 1024, então a quantidade de metadados que dá para armazenar é limitada, mas, mesmo considerando o caminho do arquivo, ainda é bastante folgada
      Poderia usar um separador inválido em caminhos normalizados, como //, e deixar algo como /path/to/file.txt//mtime=1710066090
      Ainda daria para buscar o “diretório” por prefixo e buscar o arquivo diretamente usando // como se fosse um prefixo
      Mas esse formato provavelmente prejudicaria muito a compatibilidade com outros softwares
    • Concordo que seria bom ter uma opção para incluir metadados na listagem
      No MinIO, eles adicionaram um parâmetro “secreto” metadata=true que inclui metadados e tags na listagem quando há permissões adequadas
      Por ser uma extensão, não dá para usá-la de forma confiável, mas o rclone poderia sempre tentar e usar quando disponível
      Arquivos de 0 byte terminados em / também são possíveis, mas os próprios prefixos compartilhados da listagem também podem ser vistos como diretórios
      Aí os diretórios não têm estado e têm o prós e contras de não poder existir se não houver objetos dentro deles
      Poder definir Last-Modified no upload reduziria as restrições do cliente, mas também há a vantagem de o horário do servidor ser a referência
      Replicação ou espelhamento do lado do cliente também precisam lidar com as mesmas restrições
      Pessoalmente, minha maior reclamação é não existir um HeadObjectVersions que retorne as informações de versão de um único objeto
      ListObjectVersions não consegue saber se o prefixo fornecido é um prefixo de fato ou uma chave de objeto, então acaba sempre tendo de ser uma operação no cluster inteiro
      A AWS adicionou recentemente GetObjectAttributes, mas não incluiu nele as informações de versão, que teriam se encaixado muito bem ali
  • O “Simple” em S3 não significa “não profundo”, e sim que ele tem o menor número de peças necessário para cumprir os requisitos
    Se você precisa de um armazenamento de objetos distribuído, centralizado, replicado, altamente disponível, altamente durável, de alta largura de banda, baixa latência, consistência forte, síncrono, escalável, com uma API HTTP REST, acho difícil fazer algo mais simples que o S3
    Ao longo de muitos anos, muitos recursos foram adicionados ao AWS S3, mas o funcionamento básico permaneceu o mesmo

    • Na terminologia usada no texto, “o mínimo de peças necessário” é justamente o que significa profundo
      Pelo critério de 『A Philosophy of Software Design』, de Ousterhout, ser simples significa não ser complexo, e “Simple Made Easy”, de Rich Hickey, está na mesma linha
      Já “profundo” significa oferecer internamente muitos recursos complexos por meio de uma interface pequena, então essa expressão combina melhor com o S3 do que “simples”
      É diferente de simplicidade no sentido de que não há muita coisa no S3
      https://www.infoq.com/presentations/Simple-Made-Easy/
    • Seguindo a formulação do texto, também dá para dizer que simplicidade quase implica profundidade e uma interface estreita