Trabalhar com verificações no DynamoDB - Amazon DynamoDB

Trabalhar com verificações no DynamoDB

Uma operação Scan no Amazon DynamoDB lê cada item de uma tabela ou de um índice secundário. Por padrão, uma operação Scan retorna todos os atributos de dados de cada item na tabela ou índice. Você pode usar o parâmetro ProjectionExpression para que a operação Scan retorne apenas alguns dos atributos, em vez de todos eles.

Scan sempre retorna um conjunto de resultados. Se não forem encontrados itens correspondentes, o conjunto de resultados estará vazio.

Uma única solicitação de Scan pode recuperar um máximo de 1 MB de dados. Opcionalmente, o DynamoDB pode aplicar uma expressão de filtro a esses dados, restringindo os resultados antes que eles sejam retornados ao usuário.

Expressões de filtro para verificação

Se você precisar refinar ainda mais os resultados de Scan, existe a opção de utilizar uma expressão de filtro. Uma expressão de filtro determina quais itens dos resultados de Scan devem ser retornados para você. Todos os outros resultados serão descartados.

Uma expressão de filtro é aplicada depois que uma operação Scan é concluída, mas antes que os resultados sejam retornados. Portanto, uma operação Scan consome a mesma quantidade de capacidade de leitura, independentemente de uma expressão de filtro estar presente.

Uma operação Scan pode recuperar um máximo de 1 MB de dados. Esse limite se aplica antes de a expressão de filtro ser avaliada.

Com Scan, você pode especificar quaisquer atributos em uma expressão de filtro, incluindo atributos de chave de partição ou de chave de classificação.

A sintaxe de uma expressão de filtro é idêntica à de uma expressão de condição. As expressões de filtro podem usar os mesmos comparadores, funções e operadores lógicos que uma expressão de condição. Consulte Referência de operador de comparação e função para obter mais informações sobre operadores lógicos.

exemplo

O exemplo da AWS Command Line Interface (AWS CLI) a seguir verifica a tabela Thread e retorna apenas os itens que foram publicados pela última vez por um usuário específico.

aws dynamodb scan \ --table-name Thread \ --filter-expression "LastPostedBy = :name" \ --expression-attribute-values '{":name":{"S":"User A"}}'

Limitar o número de itens no conjunto de resultados

A operação Scan permite que você limite o número de itens retornados no resultado. Para fazer isso, defina o parâmetro Limit como o número máximo de itens que você deseja que a operação Scan retorne, antes da avaliação da expressão de filtro.

Por exemplo, suponha que você execute a operação Scan em uma tabela, com um valor de Limit igual a 6 e sem uma expressão de filtro. O resultado Scan contém os primeiros seis itens da tabela.

Agora suponha que você adicione uma expressão de filtro à operação Scan. Nesse caso, o DynamoDB aplicará a expressão de filtro aos seis itens que foram retornados e descarta os que não correspondem. O resultado final de Scan contém 6 itens ou menos, dependendo do número de itens que foram filtrados.

Paginar resultados

O DynamoDB pagina os resultados das operações Scan. Com a paginação, os resultados de Scan são divididos em "páginas" de dados com 1 MB de tamanho (ou menos). Uma aplicação pode processar a primeira página de resultados e, em seguida, a segunda página, e assim por diante.

Uma única operação Scan retorna apenas um conjunto de resultados que estão dentro do limite de tamanho de 1 MB.

Para determinar se há mais resultados e para recuperá-los em uma página por vez, as aplicações devem fazer o seguinte:

  1. Examine o resultado de Scan de baixo nível:

    • Se o resultado contiver um elemento LastEvaluatedKey, prossiga para a etapa 2.

    • Se não houver um LastEvaluatedKey no resultado, não haverá mais itens a serem recuperados.

  2. Construa a nova solicitação de Scan com os mesmos parâmetros da anterior. No entanto, desta vez, use o valor de LastEvaluatedKey da etapa 1 como o parâmetro ExclusiveStartKey na nova solicitação de Scan.

  3. Execute a nova solicitação de Scan.

  4. Vá para a etapa 1.

Em outras palavras, o valor LastEvaluatedKey de uma resposta de Scan deve ser usado como ExclusiveStartKey da próxima solicitação de Scan. Se não houver um elemento LastEvaluatedKey em uma resposta de Scan, você terá recuperado a página de resultados final. (A ausência de LastEvaluatedKey é a única forma de você saber que chegou ao fim do conjunto de resultados.)

Você pode usar a AWS CLI para visualizar esse comportamento. A AWS CLI envia repetidamente solicitações Scan de baixo nível ao DynamoDB até que LastEvaluatedKey não esteja mais presente nos resultados. Considere o seguinte exemplo da AWS CLI que verifica toda a tabela Movies, mas retorna apenas os filmes de um determinado gênero.

aws dynamodb scan \ --table-name Movies \ --projection-expression "title" \ --filter-expression 'contains(info.genres,:gen)' \ --expression-attribute-values '{":gen":{"S":"Sci-Fi"}}' \ --page-size 100 \ --debug

Normalmente, a AWS CLI lida com a paginação automaticamente. No entanto, neste exemplo, o parâmetro --page-size da AWS CLI limita o número de itens por página. O parâmetro de --debug imprime as informações de baixo nível sobre solicitações e respostas.

nota

Os resultados da paginação também serão diferentes com base nos parâmetros de entrada que você passar.

  • O uso de aws dynamodb scan --table-name Prices --max-items 1 retorna NextToken

  • O uso de aws dynamodb scan --table-name Prices --limit 1 retorna LastEvaluatedKey.

Também esteja ciente de que usar--starting-token, em especial, requer o valor NextToken.

Se você executar o exemplo, a primeira resposta do DynamoDB será semelhante ao seguinte:

2017-07-07 12:19:14,389 - MainThread - botocore.parsers - DEBUG - Response body: b'{"Count":7,"Items":[{"title":{"S":"Monster on the Campus"}},{"title":{"S":"+1"}}, {"title":{"S":"100 Degrees Below Zero"}},{"title":{"S":"About Time"}},{"title":{"S":"After Earth"}}, {"title":{"S":"Age of Dinosaurs"}},{"title":{"S":"Cloudy with a Chance of Meatballs 2"}}], "LastEvaluatedKey":{"year":{"N":"2013"},"title":{"S":"Curse of Chucky"}},"ScannedCount":100}'

O LastEvaluatedKey na resposta indica que nem todos os itens foram recuperados. A AWS CLI emite outra solicitação de Scan para o DynamoDB. Essa solicitação e o padrão de resposta continuam, até a resposta final.

2017-07-07 12:19:17,830 - MainThread - botocore.parsers - DEBUG - Response body: b'{"Count":1,"Items":[{"title":{"S":"WarGames"}}],"ScannedCount":6}'

A ausência de LastEvaluatedKey indica que não há mais itens a serem recuperados.

nota

Os AWS SDKs lidam com as respostas de baixo nível do DynamoDB (incluindo a presença ou a ausência de LastEvaluatedKey) e fornecem várias abstrações para paginar os resultados de Scan Por exemplo, a interface do documento SDK para Java fornece o suporte a java.util.Iterator para que você possa abordar um resultado de cada vez.

Para obter exemplos de código em várias linguagens de programação, consulte o Guia de conceitos básicos do Amazon DynamoDB e a documentação do AWS SDK para sua linguagem.

Contar os itens nos resultados

Além dos itens que correspondem aos seus critérios, a resposta de Scan contém os elementos a seguir:

  • ScannedCount: o número de itens avaliados antes de qualquer ScanFilter ser aplicado. Um valor alto de ScannedCount com poucos ou nenhum resultado de Count indica uma operação Scan ineficiente. Se você não tiver usado um filtro na solicitação, ScannedCount será o mesmo que Count.

  • Count: o número de itens que permaneceram depois que uma expressão de filtro (se alguma) foi aplicada.

nota

Se você não usar uma expressão de filtro, ScannedCount e Count terão o mesmo valor.

Se o tamanho do conjunto de resultados de Scan for maior que 1 MB, ScannedCount e Count representarão apenas uma contagem parcial do total de itens. Você precisa executar várias operações Scan para recuperar todos os resultados (consulte Paginar resultados).

Cada resposta de Scan contém os valores de ScannedCount e de Count dos itens que foram processados pela solicitação de Scan específica. Para obter os totais gerais de todas as solicitações de Scan, você pode manter um total em execução de ScannedCount e de Count.

Unidades de capacidade consumidas por verificação

Você pode executar Scan em qualquer tabela ou índice secundário. As operações Scan consomem unidades de capacidade de leitura da seguinte forma.

Se você executar uma operação Scan... O DynamoDB consumirá unidades de capacidade de leitura de...
Tabela A capacidade de leitura provisionada da tabela.
Índice secundário global A capacidade de leitura provisionada do índice.
Índice secundário local A capacidade de leitura provisionada da tabela-base.

Por padrão, uma operação Scan não retorna quaisquer dados sobre quanta capacidade de leitura ela consome. Entretanto, você pode especificar o parâmetro ReturnConsumedCapacity em uma solicitação de Scan para obter essas informações. A seguir estão as configurações válidas de ReturnConsumedCapacity:

  • NONE: nenhum dado de capacidade consumida é retornado. (Esse é o padrão.)

  • TOTAL: a resposta inclui o número agregado de unidades de capacidade de leitura consumidas.

  • INDEXES: a resposta mostra o número agregado de unidades de capacidade de leitura consumidas, junto com a capacidade consumida para cada tabela e índice acessados.

O DynamoDB calcula o número de unidades de capacidade de leitura consumidas com base na quantidade e no tamanho desses itens, não na quantidade de dados exibidos para uma aplicação. Por esse motivo, o número de unidades de capacidade consumidas será o mesmo, independentemente de você solicitar todos os atributos (o comportamento padrão) ou apenas alguns deles (usando uma expressão de projeção). O número também é o mesmo, independentemente de você usar ou não uma expressão de filtro. Scan consome uma unidade de capacidade mínima de leitura para realizar uma leitura altamente consistente por segundo ou duas leituras finais consistentes por segundo para um item de até 4 KB. Se você precisar ler um item com mais de 4 KB, o DynamoDB precisará de unidades de solicitação de leitura adicionais. Tabelas vazias e tabelas muito grandes que têm uma quantidade esparsa de chaves de partição podem ter algumas RCUs adicionais cobradas além da quantidade de dados verificados. Isso cobre o custo de atender à solicitação Scan, mesmo que não existam dados.

Consistência de leitura para verificação

Uma operação Scan executa leituras finais consistentes, por padrão. Isso significa que os resultados de Scan talvez não reflitam as alterações causadas pelas operações PutItem ou UpdateItem concluídas recentemente. Para ter mais informações, consulte Consistência de leituras.

Se você precisar de leituras altamente consistentes, como a hora em que a operação Scan começa, defina o parâmetro ConsistentRead como true na solicitação de Scan. Isso garante que todas as operações de gravação que foram concluídas antes de Scan ter começado sejam incluídas na resposta de Scan.

Pode ser útil configurar ConsistentRead como true no backup da tabela ou em cenários de replicação, juntamente com o Amazon DynamoDB Streams. Primeiro, você usa Scan com ConsistentRead definida como true para obter uma cópia consistente dos dados na tabela. Durante a operação Scan, o DynamoDB Streams registra qualquer atividade de gravação adicional que ocorra na tabela. Após a conclusão de Scan, você pode aplicar a atividade de gravação do fluxo à tabela.

nota

Uma operação Scan com ConsistentRead definida como true consome duas vezes mais unidades de capacidade de leitura, em comparação com deixar ConsistentRead com seu valor padrão (false).

Verificar em paralelo

Por padrão, a operação Scan processa os dados sequencialmente. O Amazon DynamoDB retorna os dados para a aplicação em incrementos de 1 MB, e uma aplicação realiza operações Scan adicionais para recuperar os próximos 1 MB de dados.

Quanto maior a tabela ou índice que está sendo verificado, mais tempo a operação Scan levará para ser concluída. Além disso, uma operação Scan sequencial talvez nem sempre consiga utilizar totalmente a capacidade de throughput de leitura provisionada: embora o DynamoDB distribua os dados de uma tabela grande entre várias partições físicas, uma operação Scan pode ler apenas uma partição de cada vez. Por esse motivo, o throughput de uma operação Scan é restrita pelo throughput máximo de uma única partição.

Para solucionar esses problemas, a operação Scan pode dividir logicamente uma tabela ou um índice secundário em vários segmentos, com vários operadores da aplicação verificando os segmentos em paralelo. Cada operador pode ser um thread (em linguagens de programação que aceitam multithreading) ou um processo do sistema operacional. Para executar uma verificação em paralelo, cada operador emite sua própria solicitação de Scan com os seguintes parâmetros:

  • Segment: um segmento a ser verificado por um determinado operador. Cada operador deve usar um valor diferente para Segment.

  • TotalSegments: o número total de segmentos para a verificação em paralelo. Esse valor deve ser o mesmo que o número de operadores que sua aplicação usará.

O diagrama a seguir mostra como uma aplicação multithread executa uma operação Scan em paralelo com três níveis de paralelismo:

Uma aplicação multithread que executa uma verificação paralela, dividindo uma tabela em três segmentos.

Neste diagrama, a aplicação gera três threads e atribui um número a cada thread. (Segmentos são baseados em zero, portanto, o primeiro número é sempre 0.) Cada thread emite uma solicitação de Scan, configurando Segment como seu número designado e TotalSegments como 3. Cada thread verifica seu segmento designado, recuperando 1 MB de dados por vez, e retorna os dados para o thread principal da aplicação.

Os valores para Segment e TotalSegments aplicam-se a solicitações de Scan individuais, e você pode usar valores diferentes a qualquer momento. Talvez você precise experimentar com esses valores, e o número de operadores que usa, até que seu aplicativo atinja a melhor performance.

nota

Uma operação Scan em paralelo com um grande número de operadores pode facilmente consumir todo o throughput provisionado da tabela ou índice que está sendo verificado. É melhor evitar tais verificações, se a tabela ou índice também incorrer em uso intensivo de atividades de leitura ou de gravação de outras aplicações.

Para controlar a quantidade de dados retornados por solicitação, use o parâmetro Limit. Isso pode ajudar a evitar situações em que um operador consome todo o throughput provisionado, às custas de todos os outros operadores.