Amazon DVA-C02: Amazon DynamoDB e Design NoSQL — Guia de estudos
Faz parte do AWS Developer Associate DVA-C02 — Guia de estudos. Pratique com respostas verificadas no centro de exames da Amazon, ou faça testes cronometrados no ExamRoll.io.
Modelagem de dados e padrões de acesso
O design no DynamoDB começa com os padrões de acesso: toda consulta deve mapear para uma chave primária, um índice secundário global (GSI) ou um índice secundário local (LSI); o design da tabela é orientado pela forma como a aplicação lê e escreve itens, e não por como um esquema relacional seria estruturado. Escolha uma chave de partição de alta cardinalidade para evitar partições quentes e use uma chave primária composta (chave de partição + chave de classificação) quando precisar de consultas de intervalo; as operações de Query exigem igualdade na chave de partição e uma KeyConditionExpression opcional na chave de classificação. Para os SDKs, prefira as abstrações do DynamoDB Document: use o DynamoDBDocumentClient com o AWS SDK for JavaScript v3 (o marshall/unmarshall é feito para você) ou o DynamoDB Enhanced Client em Java para mapear objetos para atributos. Implemente padrões de tabela única somente quando os padrões de leitura compartilharem chaves e você puder codificar os tipos de item por meio de um atributo de tipo; use GSIs esparsos para expor caminhos de acesso secundários, escrevendo atributos apenas nos itens que precisam deles. Uma armadilha comum é o uso excessivo do Scan: escanear tabelas grandes é caro e paginado (LastEvaluatedKey); prefira o Query com ProjectionExpression para reduzir o uso de RCU. Para escritas condicionais, use UpdateItem com ConditionExpression ou TransactWriteItems para atomicidade de múltiplos itens; trate a ConditionalCheckFailedException e aplique recuo com jitter.
Índices, consultas e padrões transacionais
Índices secundários locais são criados apenas na criação da tabela, compartilham a mesma chave de partição da tabela base e consomem a capacidade de leitura da tabela para consultas, enquanto os GSIs podem ser adicionados após a criação da tabela, têm capacidade independente ou faturamento sob demanda e permitem chaves de partição diferentes. As chamadas de Query usam KeyConditionExpression e ExpressionAttributeNames/Values; as expressões de projeção reduzem a transferência de dados. Os GSIs são eventualmente consistentes por padrão e incorrem em um custo de escrita adicional, pois cada escrita na tabela base que projeta atributos indexados cria escritas correspondentes no GSI — planeje as WCUs adequadamente e monitore o ConsumedWriteCapacityUnits para o índice. Para consistência forte, use GetItem ou Query com ConsistentRead=true na tabela base (GSIs não suportam leituras fortemente consistentes). As transações (TransactWriteItems e TransactGetItems) garantem atomicidade em até 25 itens ou 4 MB de carga útil; use ReturnValuesOnConditionCheckFailure para inspecionar falhas. BatchWriteItem e BatchGetItem são limitados a 25 e 100 itens, respectivamente, e não são transacionais; o código deve tratar UnprocessedItems tentando novamente com recuo exponencial. Uma armadilha frequente é esquecer o custo e as implicações de consistência eventual dos GSIs ao migrar joins relacionais para índices.
Modos de capacidade, ajuste de performance e solução de problemas
Decida entre a capacidade provisionada e a sob demanda com base na previsibilidade: a provisionada com Auto Scaling (Application Auto Scaling para DynamoDB) dá controle sobre RCU/WCU e custo para cargas de trabalho estáveis, enquanto a sob demanda simplifica o tráfego em rajadas sem planejamento de capacidade, mas com um preço por solicitação mais alto. Habilite o Auto Scaling com uma utilização alvo e múltiplas políticas de escalonamento; monitore as métricas do CloudWatch como ConsumedReadCapacityUnits, ConsumedWriteCapacityUnits, ThrottledRequests, SuccessfulRequestLatency, SystemErrors e ConditionalCheckFailedRequests para detectar hotspots e throttling. Use a capacidade adaptativa para mitigar o throttling de chave única, mas evite depender dela — projete para uma distribuição uniforme de chaves. Para cargas de trabalho com uso intensivo de leitura, considere o DAX para leituras de microssegundos ou cache com o Amazon ElastiCache; para uso intensivo de escrita, use write sharding (prefixos ou buckets) para distribuir as escritas entre as partições. Solucione problemas inspecionando a ProvisionedThroughputExceededException e implementando recuo exponencial com jitter nos clientes SDK, habilite o CloudWatch Contributor Insights para encontrar chaves quentes e use o Parallel Scan para análises grandes e pontuais com workers segmentados. Lembre-se dos limites de tamanho do item (400 KB) e que itens grandes aumentam o consumo de RCUs/WCUs; divida blobs grandes no S3 com os metadados no DynamoDB quando necessário.
Streams, integrações, backups e melhores práticas operacionais
O DynamoDB Streams captura alterações em nível de item (INSERT, MODIFY, REMOVE) em ordem por chave de partição e se integra diretamente com o Lambda por meio de um mapeamento de fonte de eventos (configure o startingPosition como TRIM_HORIZON ou LATEST, defina o batchSize e o maximumBatchingWindowInSeconds, e ajuste o bisectBatchOnError e o maximumRetryAttempts). Para um processamento robusto, use o Lambda com uma Dead-Letter Queue (SQS ou SNS) ou roteie os registros do stream para o Kinesis ou Kinesis Data Firehose para análise. Habilite o Time To Live (TTL) para a expiração automática de itens; observe que as exclusões por TTL são processadas eventualmente e não devem ser usadas para garantir consistência imediata. Use o Point-in-Time Recovery (PITR) e backups sob demanda para recuperação de desastres; para disponibilidade multirregional, use Global Tables para replicar alterações entre regiões. Aplique funções IAM com privilégio mínimo aos serviços e conceda apenas as ações necessárias, como dynamodb:Query, dynamodb:PutItem, dynamodb:UpdateItem, dynamodb:GetItem, dynamodb:DescribeStream e dynamodb:ListStreams, para as funções Lambda. Armadilhas operacionais comuns incluem a falta de lógica de nova tentativa/backoff nos consumidores, planejamento inadequado da capacidade do GSI e a falha em monitorar o IteratorAge dos Streams para detecção de atraso (lag); instrumente com CloudWatch Logs e X-Ray para rastrear a latência de ponta a ponta.
Problema Prático: Cenário de Caso de Uso
Cenário: A AcmeMedia mantém um catálogo de metadados em uma única tabela DynamoDB em us-east-1 contendo dezenas de milhões de itens. Um pipeline de processamento de imagens recém-lançado precisa de uma consulta de baixa latência por photographerId e um intervalo de uploadTimestamp, e os consumidores Lambda subsequentes devem processar as alterações de forma confiável.
Desafio: Adicionar um caminho de consulta eficiente para photographerId + intervalo de timestamp sem redesenhar a tabela, garantir que os processos Lambda subsequentes processem os registros do stream com semântica de pelo menos uma vez (at-least-once) e evitar partições quentes (hot partitions) para fotógrafos prolíficos.
Abordagem Recomendada:
- Crie um GSI chamado photographer-gsi com a chave de partição photographerId e a chave de classificação uploadTimestamp; use a API UpdateTable ou o console para adicionar o GSI e especificar o faturamento ProvisionedThroughput ou On-Demand via UpdateTable e configurar o monitoramento do IndexStatus.
- Ao escrever itens, inclua os atributos photographerId e uploadTimestamp para que a projeção do índice seja esparsa; escolha ProjectionType=INCLUDE com os atributos que não são chave necessários para as consultas, a fim de reduzir os custos de armazenamento e escrita.
- Configure o DynamoDB Streams como ENABLED na tabela e crie um mapeamento de fonte de eventos Lambda com startingPosition=TRIM_HORIZON, batchSize ajustado (ex: 100), bisectBatchOnError=true, maximumRetryAttempts=2 e defina uma fila SQS como um Destino de Dead-Letter na configuração da função Lambda.
- Implemente novas tentativas do cliente SDK com jitter (use a estratégia de nova tentativa integrada do AWS SDK) e aplique write sharding se um único photographerId ainda causar throttling (prefixe o photographerId com N buckets na escrita e remova o prefixo no lado do cliente na leitura).
Justificativa: Adicionar um GSI expõe o padrão de acesso necessário sem alterar a chave primária base; projetar apenas os atributos necessários reduz o custo de escrita do GSI. Streams + Lambda com DLQ e controles de nova tentativa fornecem um processamento confiável de pelo menos uma vez (at-least-once), enquanto o sharding protege contra partições quentes resultantes de tráfego de alta cardinalidade.
← Amazon API Gateway e Integração de Aplicações · Todos os domínios · CloudFormation e Infraestrutura como Código (SAM →
Pratique estas questões → · Prática cronometrada no ExamRoll.io →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
Passe no seu exame →