Intermediário8 min de leitura

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/SK em seu código (por exemplo, CONFIG#GLOBAL) em vez de modelar em um usuário ou ID de pedido.
  • Leia com GetItem, nunca Scan. 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:

PKSKattributes
SETTINGS#APPFLAGS#V1signup_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:

simnoAplicativo/solicitaçãoGetItemPK=CONFIGURAÇÕES#APPSK=BANDEIRAS#V1Item found?Usar sinalizadores, armazenar emcache localmenteVoltar aos padrões seguros

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 únicoItem por entidade
ChaveConstante codificada (SETTINGS#APP)Modelado com um id (USER#42)
QuantosExatamente umUm por usuário/pedido/inquilino
Leitura típicaGetItem na chave conhecidaGetItem ou Query por entidade
EscopoAplicação completaUma única entidade
Usar paraSinalizadores globais, configuração, versão do sistemaPerfis, 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 Scan para 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.

Atualizado