Cloud & Infraestrutura

DynamoDB Avançado: Streams, Transactions e DAX Cache na Prática

8 min de leitura

DynamoDB Avançado: Streams, Transactions e DAX Cache na Prática

DynamoDB Streams: Capturando Mudanças em Tempo Real DynamoDB Streams permite capturar modificações (insert, update, delete) em uma tabela e processá-las de forma assíncrona. Cada stream registra a sequência exata de alterações com informações da chave, imagem anterior e nova. Isso é essencial para arquiteturas que precisam sincronizar dados entre sistemas, alimentar data lakes ou disparar notificações em tempo real. Para ativar streams, você configura na tabela o tipo de informação capturada: , , ou . A integração natural com Lambda permite processar registros automaticamente sem gerenciar infraestrutura. Aqui está um exemplo funcional que processa eventos de stream: Configuração de Stream na Tabela Para criar uma tabela com stream ativo via Terraform ou CloudFormation, defina o parâmetro . A melhor prática é usar apenas quando realmente necessário, pois aumenta o custo. Para auditoria simples, é mais econômico. --- DynamoDB Transactions: Garantindo Consistência Multi-Registro Transactions no DynamoDB garantem que múltiplas operações sejam executadas atomicamente: todas bem-sucedidas ou todas revertidas. Isso é crítico

<h2>DynamoDB Streams: Capturando Mudanças em Tempo Real</h2>

<p>DynamoDB Streams permite capturar modificações (insert, update, delete) em uma tabela e processá-las de forma assíncrona. Cada stream registra a sequência exata de alterações com informações da chave, imagem anterior e nova. Isso é essencial para arquiteturas que precisam sincronizar dados entre sistemas, alimentar data lakes ou disparar notificações em tempo real.</p>

<p>Para ativar streams, você configura na tabela o tipo de informação capturada: <code>KEYS_ONLY</code>, <code>NEW_IMAGE</code>, <code>OLD_IMAGE</code> ou <code>NEW_AND_OLD_IMAGES</code>. A integração natural com Lambda permite processar registros automaticamente sem gerenciar infraestrutura. Aqui está um exemplo funcional que processa eventos de stream:</p>

<pre><code class="language-python">import json

import boto3

from datetime import datetime

dynamodb = boto3.resource(&#039;dynamodb&#039;)

table = dynamodb.Table(&#039;usuarios&#039;)

def lambda_handler(event, context):

&quot;&quot;&quot;Processa eventos do DynamoDB Stream&quot;&quot;&quot;

for record in event[&#039;Records&#039;]:

event_name = record[&#039;eventName&#039;] # INSERT, MODIFY, REMOVE

if event_name == &#039;INSERT&#039;:

new_image = record[&#039;dynamodb&#039;][&#039;NewImage&#039;]

user_id = new_image[&#039;userId&#039;][&#039;S&#039;]

email = new_image[&#039;email&#039;][&#039;S&#039;]

print(f&quot;Novo usuário: {user_id} - {email}&quot;)

Aqui você poderia enviar email de boas-vindas via SNS

elif event_name == &#039;MODIFY&#039;:

old_image = record[&#039;dynamodb&#039;][&#039;OldImage&#039;]

new_image = record[&#039;dynamodb&#039;][&#039;NewImage&#039;]

print(f&quot;Alteração detectada: {json.dumps(new_image)}&quot;)

Comparar e registrar mudanças em auditoria

elif event_name == &#039;REMOVE&#039;:

keys = record[&#039;dynamodb&#039;][&#039;Keys&#039;]

print(f&quot;Registro deletado: {keys}&quot;)

return {&#039;statusCode&#039;: 200, &#039;body&#039;: &#039;Processado com sucesso&#039;}</code></pre>

<h3>Configuração de Stream na Tabela</h3>

<p>Para criar uma tabela com stream ativo via Terraform ou CloudFormation, defina o parâmetro <code>StreamSpecification</code>. A melhor prática é usar <code>NEW_AND_OLD_IMAGES</code> apenas quando realmente necessário, pois aumenta o custo. Para auditoria simples, <code>KEYS_ONLY</code> é mais econômico.</p>

<p>---</p>

<h2>DynamoDB Transactions: Garantindo Consistência Multi-Registro</h2>

<p>Transactions no DynamoDB garantem que múltiplas operações sejam executadas atomicamente: todas bem-sucedidas ou todas revertidas. Isso é crítico em cenários como transferência entre contas, atualização de estoque com desconto aplicado ou criação de relacionamentos que não podem ficar inconsistentes.</p>

<p>Existem dois modos: <code>TransactWriteItems</code> (até 25 operações) e <code>TransactGetItems</code> (até 25 leituras). Ao contrário de SQL, não há locks de leitura no DynamoDB — use transações apenas quando escritas precisam ser atômicas. Veja um exemplo prático de transferência de pontos entre dois usuários:</p>

<pre><code class="language-python">import boto3

from botocore.exceptions import ClientError

dynamodb = boto3.client(&#039;dynamodb&#039;)

def transferir_pontos(usuario_origem, usuario_destino, pontos):

&quot;&quot;&quot;

Transfere pontos entre usuários de forma atômica.

Se qualquer operação falhar, ambas são revertidas.

&quot;&quot;&quot;

try:

response = dynamodb.transact_write_items(

TransactItems=[

{

&#039;Update&#039;: {

&#039;TableName&#039;: &#039;usuarios&#039;,

&#039;Key&#039;: {&#039;userId&#039;: {&#039;S&#039;: usuario_origem}},

&#039;UpdateExpression&#039;: &#039;SET pontos = pontos - :pts, atualizadoEm = :agora&#039;,

&#039;ExpressionAttributeValues&#039;: {

&#039;:pts&#039;: {&#039;N&#039;: str(pontos)},

&#039;:agora&#039;: {&#039;S&#039;: datetime.now().isoformat()}

},

&#039;ConditionExpression&#039;: &#039;pontos &gt;= :pts&#039; # Valida antes

}

},

{

&#039;Update&#039;: {

&#039;TableName&#039;: &#039;usuarios&#039;,

&#039;Key&#039;: {&#039;userId&#039;: {&#039;S&#039;: usuario_destino}},

&#039;UpdateExpression&#039;: &#039;SET pontos = pontos + :pts, atualizadoEm = :agora&#039;,

&#039;ExpressionAttributeValues&#039;: {

&#039;:pts&#039;: {&#039;N&#039;: str(pontos)},

&#039;:agora&#039;: {&#039;S&#039;: datetime.now().isoformat()}

}

}

}

]

)

print(&quot;Transferência bem-sucedida&quot;)

return True

except ClientError as e:

if e.response[&#039;Error&#039;][&#039;Code&#039;] == &#039;TransactionCanceledException&#039;:

print(f&quot;Transação cancelada: {e.response[&#039;Error&#039;][&#039;Message&#039;]}&quot;)

Pode ser falta de saldo ou outro erro de validação

return False

from datetime import datetime</code></pre>

<h3>Padrões de Erro e Tratamento</h3>

<p>Exceções de transação requerem retry logic com exponential backoff. A chave é implementar idempotência: sua operação deve produzir o mesmo resultado se executada múltiplas vezes. Inclua um <code>requestId</code> único para detectar duplicatas.</p>

<p>---</p>

<h2>DAX Cache: Acelerando Leituras com Cache em Memória</h2>

<p>DAX (DynamoDB Accelerator) é um cache gerenciado que fica entre sua aplicação e DynamoDB, reduzindo latência de milissegundos para microsegundos e economizando unidades de leitura. É especialmente eficaz para workloads com hot keys (poucos registros acessados repetidamente).</p>

<p>DAX funciona transparentemente: você usa o mesmo SDK do DynamoDB, apenas apontando para o endpoint do cluster DAX. Caches são invalidados automaticamente quando você escreve via DAX, mantendo consistência. Veja como integrar:</p>

<pre><code class="language-python">import amazondax

import boto3

Criar cliente DAX em vez do DynamoDB normal

dax_endpoint = &#039;my-cluster.dax.amazonaws.com&#039;

dax = amazondax.AmazonDaxClient.resource(endpoint_url=f&#039;http://{dax_endpoint}:8111&#039;)

Usar normalmente como uma tabela DynamoDB

table = dax.Table(&#039;usuarios&#039;)

def buscar_usuario_com_cache(user_id):

&quot;&quot;&quot;

Primeira chamada consulta DynamoDB e armazena em cache (TTL padrão 5min).

Chamadas subsequentes vêm do cache sem custo de RCU.

&quot;&quot;&quot;

try:

response = table.get_item(Key={&#039;userId&#039;: user_id})

user = response.get(&#039;Item&#039;)

print(f&quot;Usuário {user_id} recuperado - TTL padrão: 5 minutos&quot;)

return user

except Exception as e:

print(f&quot;Erro ao acessar DAX: {e}&quot;)

Fallback para DynamoDB direto

dynamodb = boto3.resource(&#039;dynamodb&#039;)

return dynamodb.Table(&#039;usuarios&#039;).get_item(Key={&#039;userId&#039;: user_id}).get(&#039;Item&#039;)

Simular carga com acesso repetido

for i in range(100):

usuario = buscar_usuario_com_cache(&#039;user-123&#039;) # Mesmo user a cada iteração</code></pre>

<h3>Quando Usar DAX</h3>

<p>Use DAX quando você tem padrão de leitura repetida ou workload de leitura pesada. <strong>Não</strong> recomendo para aplicações com muitas escritas distintas ou quando dados mudam frequentemente. Custo típico: $0.25/hora para cluster com 3 nós. Analise ROI antes de implementar.</p>

<p>---</p>

<h2>Conclusão</h2>

<p>Dominando esses três pilares você constrói aplicações DynamoDB verdadeiramente resilientes. <strong>Streams</strong> permitem propagação de dados assíncrona sem acoplamento. <strong>Transactions</strong> garantem consistência onde importa: transferências, inventário, estados críticos. <strong>DAX</strong> multiplica performance de leitura quando você tem padrões previsíveis. A combinação desses recursos resolve 95% dos problemas reais em produção.</p>

<p>---</p>

<h2>Referências</h2>

<ul>

<li><a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html" target="_blank" rel="noopener noreferrer">AWS DynamoDB Streams Documentation</a></li>

<li><a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html" target="_blank" rel="noopener noreferrer">DynamoDB Transactions Guide</a></li>

<li><a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DAX.html" target="_blank" rel="noopener noreferrer">DAX Developer Guide</a></li>

<li><a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/best-practices.html" target="_blank" rel="noopener noreferrer">AWS DynamoDB Best Practices</a></li>

<li><a href="https://www.dynamodbbook.com" target="_blank" rel="noopener noreferrer">Designing with DynamoDB - Alex DeBrie</a></li>

</ul>

Comentários

Mais em Cloud & Infraestrutura

Dominando Lambda Avançado: Layers, Extensions, SnapStart e Cold Start em Projetos Reais
Dominando Lambda Avançado: Layers, Extensions, SnapStart e Cold Start em Projetos Reais

Entendendo Lambda Layers: Organização e Reutilização Lambda Layers são pacote...

Amazon Inspector e Trusted Advisor: Vulnerabilidades e Boas Práticas na Prática
Amazon Inspector e Trusted Advisor: Vulnerabilidades e Boas Práticas na Prática

Amazon Inspector: Análise Automatizada de Vulnerabilidades Amazon Inspector é...

O que Todo Dev Deve Saber sobre Systems Manager: Parameter Store, Session Manager e Patch Manager
O que Todo Dev Deve Saber sobre Systems Manager: Parameter Store, Session Manager e Patch Manager

Systems Manager: Uma Visão Prática para Developers O AWS Systems Manager é um...