Controlar o conteúdo em cache e invalidar uma atualização

AWSBeginner
Pratique Agora

Introdução

Uma versão pode estar corretamente armazenada no S3 enquanto a distribuição ainda entrega uma cópia anterior. Controle a duração do cache, observe sua reutilização e expiração e invalide apenas o caminho da página atualizada. Preserve o cache de um segundo objeto e a privacidade da origem.

Conclua primeiro o laboratório de distribuição de conteúdo privado do S3. Esta VM independente fornece um novo bucket privado, OAC, distribuição e política correspondente, sem reutilizar recursos de outra VM. Inicialmente o cache está desativado e não há solicitações de usuários nem invalidações. Arquivos preparados permitem concentrar-se no cache. Observe o estado real no AWS View, acima, e execute comandos no Terminal, abaixo. Não é necessário ter conta pessoal da AWS ou domínio público.

Objetivos de certificação

Certificação Tarefa do exame Prática
Solutions Architect – Associate (SAA-C03) Tarefa 3.4 Praticar a distribuição de conteúdo com CloudFront e o efeito da duração do cache nas leituras da origem.

Visão geral do laboratório

Diagrama conceitual: reutilizar uma versão em cache e invalidar seu caminho exato para obter o conteúdo atualizado da origem, mantendo o cache de outro objeto.

Observar a reutilização e a expiração do cache

Nesta etapa, configure uma duração curta para distinguir um acerto de cache de uma nova leitura da origem.

Um cache guarda uma cópia para solicitações posteriores. O TTL é sua validade em segundos. O Cache-Control: max-age do objeto fornece a duração; os TTLs mínimo e máximo da distribuição a limitam, e o padrão é usado quando a origem não especifica uma duração. Usaremos as configurações normais da distribuição, sem criar uma política de cache separada.

Identifique a distribuição preparada. --query seleciona aquela com o comentário do laboratório, e $(...) armazena seu ID ou domínio em uma variável do shell. Mantenha o Terminal aberto. Consulte o bucket de referência independente sem modificá-lo:

cd /home/labex/project
DIST_ID=$(aws cloudfront list-distributions \
  --query "DistributionList.Items[?Comment=='labex-n03:private-content'].Id | [0]" \
  --output text)
DIST_DOMAIN=$(aws cloudfront get-distribution \
  --id "$DIST_ID" \
  --query Distribution.DomainName \
  --output text)
aws s3api list-buckets \
  --query 'Buckets[].Name'

Leia a configuração atual e seu ETag, identificador de versão necessário para uma atualização segura. > grava a saída em um arquivo. sed altera somente os dois atributos TTL inicialmente iguais a zero; o mínimo permanece zero. O novo máximo permite durações maiores depois:

aws cloudfront get-distribution-config \
  --id "$DIST_ID" \
  --query DistributionConfig > current-config.json
ETAG=$(aws cloudfront get-distribution-config \
  --id "$DIST_ID" \
  --query ETag \
  --output text)
sed -e 's/"DefaultTTL": 0/"DefaultTTL": 6/'   -e 's/"MaxTTL": 0/"MaxTTL": 3600/'   current-config.json > cached-config.json
aws cloudfront update-distribution \
  --id "$DIST_ID" \
  --if-match "$ETAG" \
  --distribution-config file://cached-config.json
aws cloudfront wait distribution-deployed \
  --id "$DIST_ID"

Envie a primeira versão preparada com validade de seis segundos. Preserve o tipo de conteúdo text/html:

aws s3api put-object \
  --bucket labex-n03-content \
  --key index.html \
  --body index.html \
  --content-type text/html \
  --cache-control 'max-age=6'

curl --include mostra cabeçalhos e corpo. --resolve direciona o nome real da distribuição ao endpoint desta VM sem mudar o DNS do sistema. Execute as duas solicitações seguidas para que a segunda ocorra antes de seis segundos:

curl --fail --include --noproxy '*'   --resolve "${DIST_DOMAIN}:8082:127.0.0.1"   "http://${DIST_DOMAIN}:8082/index.html"
curl --fail --include --noproxy '*'   --resolve "${DIST_DOMAIN}:8082:127.0.0.1"   "http://${DIST_DOMAIN}:8082/index.html"

A primeira mostra X-Cache: Miss from cloudfront, a segunda Hit from cloudfront, e ambas retornam Release one. Um acerto reutiliza os bytes guardados sem ler novamente a origem. Age mostra a idade da cópia; solicitações imediatas podem mostrar zero segundos.

sleep 7 deixa a cópia de seis segundos expirar antes de uma nova solicitação:

sleep 7
curl --fail --include --noproxy '*'   --resolve "${DIST_DOMAIN}:8082:127.0.0.1"   "http://${DIST_DOMAIN}:8082/index.html"

Espere outra falta no cache com a mesma página. A expiração faz a próxima solicitação consultar novamente a origem; não exclui o objeto S3. O AWS View mostra solicitações reais e a contagem de leituras da origem. Execute a verificação antes de continuar.

Exemplo após a expiração: as solicitações reais mostram falta, acerto e falta no cache, com duas leituras da origem.

Observar uma atualização atrás de uma cópia em cache

Nesta etapa, envie uma versão nova e observe por que o cache existente ainda retorna o conteúdo antigo.

Uma duração maior facilita a observação. Envie novamente a primeira página com max-age=900 e o objeto independente stable.txt com max-age=3600. O máximo de 3600 da distribuição permite ambos os valores:

aws s3api put-object \
  --bucket labex-n03-content \
  --key index.html \
  --body index.html \
  --content-type text/html \
  --cache-control 'max-age=900'
aws s3api put-object \
  --bucket labex-n03-content \
  --key stable.txt \
  --body stable.txt \
  --content-type text/plain \
  --cache-control 'max-age=3600'

Alterar os metadados da origem não muda retroativamente uma resposta armazenada. Espere a cópia de seis segundos expirar e faça solicitações aos dois caminhos para preencher seus caches:

sleep 7
curl --fail --include --noproxy '*'   --resolve "${DIST_DOMAIN}:8082:127.0.0.1"   "http://${DIST_DOMAIN}:8082/index.html"
curl --fail --include --noproxy '*'   --resolve "${DIST_DOMAIN}:8082:127.0.0.1"   "http://${DIST_DOMAIN}:8082/stable.txt"

Ambas apresentam uma falta no cache e leem os objetos atuais da origem. A página agora inclui Cache-Control: max-age=900. Conclua as próximas duas etapas dentro desses quinze minutos.

O arquivo preparado release-two.html contém a página modificada. Envie-o usando a mesma chave de objeto, preservando tipo e duração. Leia o objeto com a CLI autenticada do S3 em origin-release.html para conferir seus bytes reais:

cat release-two.html
aws s3api put-object \
  --bucket labex-n03-content \
  --key index.html \
  --body release-two.html \
  --content-type text/html \
  --cache-control 'max-age=900'
aws s3api get-object \
  --bucket labex-n03-content \
  --key index.html origin-release.html
cat origin-release.html

A origem contém Release two. Solicite o mesmo caminho pela distribuição:

curl --fail --include --noproxy '*'   --resolve "${DIST_DOMAIN}:8082:127.0.0.1"   "http://${DIST_DOMAIN}:8082/index.html"

Espere um acerto com Release one. O envio funcionou, mas a cópia do usuário continua válida segundo seu próprio TTL. Isso é diferente de uma falha de permissão da origem. Execute a verificação da cópia antiga.

Exemplo antes da invalidação: a última solicitação da página acerta no cache; o objeto independente está armazenado e exigiu apenas uma leitura da origem.

Invalidar somente a página atualizada

Nesta etapa, torne a nova versão visível antes da expiração sem descartar o objeto independente.

Uma invalidação remove objetos correspondentes do cache da distribuição. O caminho é aquele solicitado pelo usuário, começando com /, não um nome de bucket nem um arquivo local. Use exatamente /index.html; /* também descartaria desnecessariamente o outro objeto.

Crie a solicitação. O atalho --paths da CLI fornece o lote, e a consulta guarda seu ID gerado em uma variável:

INVALIDATION_ID=$(aws cloudfront create-invalidation \
  --distribution-id "$DIST_ID" \
  --paths '/index.html' \
  --query Invalidation.Id \
  --output text)
aws cloudfront wait invalidation-completed \
  --distribution-id "$DIST_ID" \
  --id "$INVALIDATION_ID"
aws cloudfront get-invalidation \
  --distribution-id "$DIST_ID" \
  --id "$INVALIDATION_ID" \
  --query 'Invalidation.{Status:Status,Paths:InvalidationBatch.Paths.Items}'

Confirme Completed e /index.html. Um lote concluído não comprova sozinho os bytes recebidos pelo usuário. Solicite a página duas vezes para verificar o conteúdo novo e sua reutilização:

curl --fail --include --noproxy '*'   --resolve "${DIST_DOMAIN}:8082:127.0.0.1"   "http://${DIST_DOMAIN}:8082/index.html"
curl --fail --include --noproxy '*'   --resolve "${DIST_DOMAIN}:8082:127.0.0.1"   "http://${DIST_DOMAIN}:8082/index.html"

Espere uma falta no cache com Release two, seguida de um acerto com a mesma página nova. A primeira consulta obtém os bytes atuais da origem; a segunda reutiliza a nova cópia.

Solicite o objeto independente e repita o teste anônimo direto na origem:

curl --fail --include --noproxy '*'   --resolve "${DIST_DOMAIN}:8082:127.0.0.1"   "http://${DIST_DOMAIN}:8082/stable.txt"
curl --noproxy '*' --output /dev/null   --write-out 'Anonymous origin: HTTP %{http_code}\n'   http://127.0.0.1:5000/labex-n03-content/index.html

stable.txt deve continuar acertando no cache, com o conteúdo original e sem outra leitura da origem. O acesso anônimo ao S3 deve continuar retornando HTTP 403. Invalidar muda o cache, não as permissões da origem. Execute a verificação da atualização direcionada.

Exemplo após invalidar o caminho exato: falta e acerto para a página; stable.txt continua acertando, com apenas uma leitura da origem.

Remover somente seus recursos de distribuição

Nesta etapa, desative e exclua primeiro a distribuição, depois o OAC e o conteúdo S3. Preserve o bucket de referência.

CloudFront usa ETag como token de versão da configuração. Obtenha a configuração e o ETag atuais; não invente o token.

Antes de excluir a distribuição, leia seu ID de OAC. Essa variável preserva o controle exato a remover:

OAC_ID=$(aws cloudfront get-distribution-config \
  --id "$DIST_ID" \
  --query 'DistributionConfig.Origins.Items[0].OriginAccessControlId' \
  --output text)

Agora salve a configuração atual e obtenha seu ETag:

aws cloudfront get-distribution-config \
  --id "$DIST_ID" \
  --query DistributionConfig \
  --output json > distribution-current.json
DIST_ETAG=$(aws cloudfront get-distribution-config \
  --id "$DIST_ID" \
  --query ETag \
  --output text)

Na configuração atual deste laboratório, Enabled da distribuição é o único atributo desse nome com valor true. Esta substituição normal com sed cria uma cópia desativada preservando as configurações da origem:

sed 's/"Enabled": true/"Enabled": false/' distribution-current.json > distribution-disabled.json
aws cloudfront update-distribution \
  --id "$DIST_ID" \
  --if-match "$DIST_ETAG" \
  --distribution-config file://distribution-disabled.json

Espere a configuração desativada ser implantada. A propagação na AWS pode levar tempo; este laboratório não mede o atraso de implantação mundial:

aws cloudfront wait distribution-deployed \
  --id "$DIST_ID"

A atualização muda o ETag. Leia o token mais recente antes de excluir a distribuição desativada:

DIST_ETAG=$(aws cloudfront get-distribution-config \
  --id "$DIST_ID" \
  --query ETag \
  --output text)
aws cloudfront delete-distribution \
  --id "$DIST_ID" \
  --if-match "$DIST_ETAG"

Exclua o OAC com seu próprio ETag. O ID da distribuição e o do OAC identificam recursos diferentes:

OAC_ETAG=$(aws cloudfront get-origin-access-control \
  --id "$OAC_ID" \
  --query ETag \
  --output text)
aws cloudfront delete-origin-access-control \
  --id "$OAC_ID" \
  --if-match "$OAC_ETAG"

Exclua somente os dois objetos do laboratório e seu bucket:

aws s3api delete-object \
  --bucket labex-n03-content \
  --key index.html
aws s3api delete-object \
  --bucket labex-n03-content \
  --key stable.txt
aws s3api delete-bucket \
  --bucket labex-n03-content
aws s3api list-buckets \
  --query 'Buckets[].Name'

O bucket de referência deve permanecer e o bucket de conteúdo deve estar ausente. O AWS View deve mostrar nenhuma distribuição de conteúdo e somente o objeto de referência. Execute a verificação da limpeza. Uma solicitação de API que falhou não prova a exclusão.

Exemplo após a limpeza: apenas a referência independente permanece; o histórico de solicitações e leituras da origem continua visível.

Resumo

Você configurou limites TTL e Cache-Control, observou que um acerto não acrescenta leituras da origem e deixou uma cópia curta expirar. Comprovou que enviar uma versão nova à origem não substitui uma cópia do usuário ainda válida. A invalidação do caminho exato obteve a nova página, preservando o outro cache e a origem privada. Depois removeu somente seus recursos. Em publicações frequentes, nomes de objetos com versão também permitem selecionar conteúdo novo; aqui você praticou a atualização de um caminho existente.