Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Uploads Multipart no AWS S3 — Como Evitar Custos Ocultos de Uploads Não Finalizados

By Avi KeinanJun 18, 20215 min read

Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.

Ao enviar um arquivo maior que 5Mb para um bucket do AWS S3, o AWS SDK/CLI divide o upload automaticamente em várias requisições HTTP PUT. É mais eficiente, permite retomar uploads e — se uma das partes falhar — ela é reenviada sem interromper o progresso.

Não deixe sobras depois dos seus uploads para o AWS S3

Mas existe uma armadilha em potencial nos uploads multipart:

Se o upload for interrompido antes do objeto ser totalmente enviado, você é cobrado pelas partes já enviadas até excluí-las.

Resultado: você pode ter um aumento oculto nos custos de armazenamento, que não fica evidente de imediato.

Continue lendo para descobrir como identificar as partes enviadas e como reduzir custos quando há uploads multipart não finalizados.

Imagem do post do Jeff Barr

Como encontrar partes de objetos enviadas no Console do AWS S3?

Aqui vai a parte interessante: você não consegue ver esses objetos no Console do AWS S3.

Para fins deste artigo, criei um bucket S3 e iniciei o upload de um arquivo de 100Gb. Interrompi o processo depois de enviar 40Gb.

Ao acessar o Console do S3, vi que havia 0 objetos no bucket e que o console não exibia os 40Gb que já tinham sido enviados (multipart).

Em seguida, cliquei na aba Metrics e vi que o tamanho do bucket era de 40Gb.

Pode levar várias horas até as métricas atualizadas aparecerem.

Ou seja, mesmo sem conseguir ver o objeto no console porque o upload não foi finalizado, você continua sendo cobrado pelas partes que já foram enviadas.

Como isso é tratado no mundo real?

Conversei com vários colegas de diferentes empresas que operam contas AWS com uso mensal considerável de S3.

A maioria tinha entre +100Mb e +10Tb de uploads multipart não finalizados. O consenso geral foi: quanto maior o uso de S3 e mais antiga a conta, mais objetos incompletos existem.

Calculando o tamanho das partes de um único objeto multipart

Primeiro, no AWS CLI, liste os objetos multipart atuais com o seguinte comando:

aws s3api list-multipart-uploads --bucket <bucket-name>

Isso retorna uma lista de todos os objetos incompletos com múltiplas partes:

Depois, liste todas as partes do upload multipart com o comando list-parts, usando o valor de "UploadId":

aws s3api list-parts --upload-id 5IBStnpJl6REH... --bucket <bucket-name> --key example.exe

Em seguida, some o tamanho (em bytes) de todas as partes enviadas e converta o resultado para Gb usando o JQ (processador JSON de linha de comando):

jq '.Parts | map(.Size/1024/1024/1024) | add'

Para excluir manualmente um objeto de upload multipart, execute:

aws s3api abort-multipart-upload --bucket <bucket-name> --key example.exe --upload-id 5IBStnpJl6REH...

Como parar de ser cobrado por uploads multipart não finalizados?

Configurando no nível do bucket, você pode criar uma lifecycle rule (regra de ciclo de vida) que exclui automaticamente os objetos multipart incompletos depois de alguns dias.

"Uma configuração de ciclo de vida do S3 é um conjunto de regras que define ações que o Amazon S3 aplica a um grupo de objetos." ( documentação da AWS).

Veja duas soluções:

  • Uma solução manual para buckets já existentes; e
  • Uma solução automática para a criação de novos buckets.

Excluindo uploads multipart em buckets existentes

Nesta solução, você criará uma regra de ciclo de vida para remover objetos multipart antigos em um bucket existente.

Atenção: tenha cuidado ao definir uma lifecycle rule. Um erro de definição pode excluir objetos existentes no seu bucket.

Primeiro, abra o console do AWS S3, selecione o bucket desejado e vá até a aba Management.

Em Lifecycle rules, clique em Create lifecycle rule.

Em seguida, dê um nome à lifecycle rule e defina o escopo da regra para todos os objetos do bucket.

Marque a caixa " I acknowledge that this rule will apply to all objects in the bucket".

Depois, vá até Lifecycle rule actions e marque a caixa " Delete expired delete markers or incomplete multipart upload".

Marque a caixa " Delete incomplete multipart uploads" e defina o Number of days conforme sua necessidade (na minha opinião, três dias são suficientes para concluir uploads pendentes).

Depois de concluir as etapas acima, os arquivos multipart que foram enviados serão excluídos — mas não na hora (vai levar um tempinho).

Dois pontos importantes:

  • Operações de exclusão são gratuitas.
  • Depois de definir a lifecycle rule, você não é mais cobrado pelos dados que serão excluídos.

Criando uma lifecycle rule para novos buckets

Nesta solução, você criará uma lifecycle rule que será aplicada automaticamente sempre que um novo bucket for criado.

A solução usa um script simples de automação em Lambda, acionado toda vez que um novo bucket é criado. Essa função Lambda implementa uma lifecycle rule para excluir todos os objetos multipart com mais de 3 dias.

Observação: como o EventBridge roda apenas na região em que é criado, você precisa implantar a função Lambda em cada região onde opera.

S3 Management Console — Assista ao vídeo

Como implementar essa automação?

  1. Habilite uma trilha do AWS CloudTrail. Depois de configurar a trilha, dá para usar o AWS EventBridge para acionar uma função Lambda.
  2. Crie uma nova função Lambda, com Python 3.8 como Runtime.
  3. Cole o código abaixo (Github gist):

4. Selecione create function.

5. Role até o topo da página, em Trigger selecione 'Add trigger' e, na configuração do gatilho, escolha EventBridge.

Em seguida, crie uma nova regra e dê a ela um nome e uma descrição.

6. Em tipo de regra, escolha Event pattern; nas duas caixas seguintes, escolha Simple Storage Services (S3) e AWS API call via CloudTrail.

Na caixa Detail, em Operation, escolha CreateBucket.

Role para baixo e clique no botão Add.

7. Vá até a aba Basic settings, selecione Edit → IAM role e anexe a policy abaixo.

Essa policy permite que a função Lambda crie uma configuração de ciclo de vida em todos os buckets da conta AWS.

{
    "Version": "2012-10-17",
    "Statement": [\
        {\
            "Sid": "VisualEditor0",\
            "Effect": "Allow",\
            "Action": "s3:PutLifecycleConfiguration",\
            "Resource": "*"\
        }\
    ]
}

8. Crie um bucket para conferir se a função Lambda está funcionando corretamente.

9. Pronto! Agora, toda vez que você criar um novo bucket (na região configurada), a função Lambda criará automaticamente uma lifecycle rule para esse bucket.

Obrigado pela leitura! Para ficar por dentro, acompanhe a gente no DoiT Engineering Blog , no canal da DoiT no LinkedIn e no canal da DoiT no Twitter . Para conferir oportunidades de carreira, acesse https://careers.doit-intl.com .