Itens Singleton em DynamoDB
Um item singleton é uma única linha com uma chave fixa e codificada que contém estado para todo o seu aplicativo - não um registro por usuário ou por pedido, mas um registro, ponto final. Sinalizadores de recursos, um blob de configuração, um kill switch global: o tipo de coisa que um aplicativo relacional manteria em uma tabela de configurações de uma linha.
Vindo de SQL, você alcançaria uma tabela config com id = 1 e um SELECT * FROM config. Em DynamoDB você faz a mesma coisa com uma partição codificada
chave - e como você sempre conhece essa chave, você a lê com GetItem, não
um Query ou um Scan.
O que é um item singleton em DynamoDB?
Um item singleton é uma única linha DynamoDB armazenada em uma chave fixa e codificada que mantém o estado global para todo o seu aplicativo – sinalizadores de recursos, um blob de configuração, uma versão de todo o sistema – em vez de um registro por usuário ou pedido. Como você sempre conhece a chave, você a lê com GetItem e a atualiza commais expressões de condição.
- Um singleton é um item com uma chave constante. Você codifica
PK/SKem seu código (por exemplo,CONFIG#GLOBAL) em vez de modelar em um usuário ou ID de pedido. - Leia com
GetItem, nuncaScan. Você sempre sabe a tonalidade completa, então um a leitura de ponto tem um custo fixo e previsível (no máximo 1 RCU para um item pequeno) — sem filtro, sem caminhada na mesa. - É umpor definição. Cada solicitação pode tocar na mesma partição, então armazene-o em cache e mantenha o item pequeno; não faça disso um gargalo de gravação.
- Altere-o com segurança com expressões de atualização + condição, não de leitura-modificação-gravação no seu aplicativo - é aí que reside a corrida pela atualização perdida.
Reconheça o padrão
Você tem um estado global quando os dados não têm como escopo nenhuma entidade. Algumas dicas:
- Um sinalizador igual para todos (
signup_enabled = false). - Um blob de ajustes que seu aplicativo lê na inicialização (limites de taxa, cotas padrão).
- Um contador ou número de versão para todo o sistema, não por linha.
Qualquer coisa com escopo para um usuário, inquilino ou pedido não é um singleton — isso é um item comum codificado pelo ID dessa entidade. O singleton é o que sobrou global fatia que não tem mais onde morar.
Dê uma chave constante
Todo o padrão depende de uma decisão. A chave é literal, não um modelo. Para um item de sinalizadores de recursos globais em uma tabela única sobrecarregada, escolha um item fixo prefixo e um valor fixo:
| PK | SK | attributes |
|---|---|---|
| SETTINGS#APP | FLAGS#V1 | signup_enabled, maintenance_mode, ai_search_enabled |
PK = "SETTINGS#APP" e SK = "FLAGS#V1" estão incluídos no código. Não há
ID de usuário, sem ID de locatário — o aplicativo sempre solicita exatamente esse item.
Essa previsibilidade é o ponto: uma chave conhecida é GetItem e GetItem
é a oferta de leitura DynamoDB mais barata e consistente.
O sufixo V1 é deliberado. Se o esquema do sinalizador mudar de forma posteriormente, você escreve
um item FLAGS#V2 e virar os leitores, em vez de transformar o ativo em
lugar. O versionamento da chave singleton proporciona uma migração limpa.
Leia com GetItem
Como a chave é totalmente conhecida, você nunca Query e nunca Scan para um
solteiro. Um Scan lê toda a tabela e filtra do lado do cliente — o clássico
Scan footgun — e é um exagero absurdo para buscar
uma linha que você pode endereçar diretamente.
Um GetItem contra SETTINGS#APP / FLAGS#V1 retorna os sinalizadores em um único
leitura fortemente ou eventualmente consistente. Sob demanda em us-east-1, AWS cobra um
GetItem de um item ≤ 4 KB como 0,5 RCU eventualmente consistente ou 1 RCU
fortemente consistente
(AWS documentos de capacidade de leitura/gravação).
Mantenha o singleton pequeno e esse custo permanecerá fixo para sempre – inchando a configuração
blob em um segundo bloco de 4 KB dobra a leitura cobrada.
No caminho de leitura, quando o aplicativo inicializa ou uma solicitação chega, você GetItem o fixo
chave, você armazena em cache o resultado. O fluxo:
A chave fixa transforma uma pesquisa global em um ponto lido com um caminho padrão integrado.
Observe o branch no: um singleton ausente nunca deve travar você. Padrão para o
valor seguro (recurso desativado, manutenção ativada), portanto, uma lacuna na primeira implantação ou uma falha
chave falha fechada, não aberta.
Atualize-o sem corrida
A armadilha está atualizando um singleton com leitura-modificação-gravação em seu aplicativo: você
GetItem os sinalizadores, coloque um na memória e então PutItem tudo de volta.
Dois escritores simultâneos lêem o item antigo e o segundo Put derrota o
a primeira mudança. Atualização perdida.
Dois recursos DynamoDB acabam com a corrida sem bloqueio do aplicativo:
- altera um atributo no lado do servidor, deixando o resto intocado. Não há necessidade de colocar novamente o item inteiro.
- faça com que a gravação seja bem-sucedida somente se o item ainda parecer
da maneira que você espera, então uma gravação obsoleta é rejeitada com
ConditionalCheckFailedException(AWS documentos de expressão de condição).
Para inverter um sinalizador, direcione apenas esse atributo com um SET e proteja-o com um
aumento de versão para que escritores simultâneos não possam atropelar uns aos outros:
# UpdateItem
Key PK=SETTINGS#APP SK=FLAGS#V1
UpdateExpression SET signup_enabled = :on, schema_version = :next
ConditionExpression schema_version = :current
Se dois escritores competirem, a verificação schema_version = :current falhará
e ele tenta novamente contra o novo valor. Você pode estruturar os nomes, valores e
esta forma exata de expressão no
DynamoDB Expression Builder antes da fiação
em código. Para uma visão mais aprofundada dos operadores, consulte o
idiomas de expressão de atualização.
Cuidado com a tecla de atalho
Um singleton é, por construção, uma tecla de atalho — cada parte do seu aplicativo pode ler a mesma partição. Isso é bom para leituras se você armazenar em cache, mas é o verdadeiro risco do padrão.
- Cache agressivamente. Leia os sinalizadores uma vez por processo (ou por N segundos), não em cada solicitação. O valor do singleton é a coisa mais barata para memorizar.
- Não faça disso um ponto quente de gravação. Um sinalizador alternado por um administrador algumas vezes por dia não é nada. Um singleton que você incrementa em cada solicitação é uma taxa de transferência de partição gargalo - esse é um contra-problema, não um problema único.
- Mantenha-o pequeno. Leia escalas de custos com tamanho de item em blocos de 4 KB. Um inchado O blob de configuração torna cada inicialização mais cara do que o necessário.
Se você realmente precisa de um contador global de alta gravação, o singleton é o errado forma - fragmente-o em N itens e some na leitura. Esse é um padrão diferente.
Singleton vs item por entidade
A linha é simplesmente o escopo dos dados.
| Item único | Item por entidade | |
|---|---|---|
| Chave | Constante codificada (SETTINGS#APP) | Modelado com um id (USER#42) |
| Quantos | Exatamente um | Um por usuário/pedido/inquilino |
| Leitura típica | GetItem na chave conhecida | GetItem ou Query por entidade |
| Escopo | Aplicação completa | Uma única entidade |
| Usar para | Sinalizadores globais, configuração, versão do sistema | Perfis, pedidos, qualquer coisa por ID |
Se você deseja dois singletons do mesmo tipo, você não tem um singleton - você tem um item por entidade e a entidade é aquilo que você esqueceu key by (configuração por locatário, digamos).
Armadilhas e próximos passos
- Não
Scanpara isso. Você conhece a chave; abordá-lo diretamente. - Não leia-modifique-escreva. Use expressões de atualização + condição.
- Não deixe que ele desapareça silenciosamente. Padrão para o valor seguro em uma falha de cache.
- Não sobrecarregue com gravações de alta frequência. Esse é um trabalho de contador fragmentado.
O solteiro vive confortavelmente dentro de um design de mesa única — é apenas mais um item coleção com uma chave fixa ao lado das linhas da sua entidade.
Tente DynoTable para navegar em sua tabela, encontre a linha singleton por seu chave fixa e edite sinalizadores manualmente enquanto constrói o caminho de gravação.