Verificar tabelas 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.
Tópicos
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 Expressões de condição e filtro, operadores e funções no DynamoDB 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:
-
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.
-
-
Construa a nova solicitação de
Scan
com os mesmos parâmetros da anterior. No entanto, desta vez, use o valor deLastEvaluatedKey
da etapa 1 como o parâmetroExclusiveStartKey
na nova solicitação deScan
. -
Execute a nova solicitação de
Scan
. -
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
retornaNextToken
O uso de
aws dynamodb scan --table-name Prices --limit 1
retornaLastEvaluatedKey
.
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 qualquerScanFilter
ser aplicado. Um valor alto deScannedCount
com poucos ou nenhum resultado deCount
indica uma operaçãoScan
ineficiente. Se você não tiver usado um filtro na solicitação,ScannedCount
será o mesmo queCount
. -
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 leitura do DynamoDB.
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 paraSegment
. -
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:
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.