Menengah7 menit baca

Item singleton di DynamoDB

Item singleton adalah satu baris dengan key tetap yang di-hardcode yang menahan state untuk seluruh aplikasi Anda — bukan satu record per pengguna atau per order, melainkan satu record, titik. Feature flag, blob config, kill-switch global: jenis yang akan disimpan app relasional di tabel settings satu-baris.

Dari SQL, Anda akan meraih tabel config dengan id = 1 dan SELECT * FROM config. Di DynamoDB Anda melakukan hal yang sama dengan partition key yang di-hardcode — dan karena Anda selalu tahu key itu, Anda membacanya dengan GetItem, bukan Query atau Scan.

Apa itu item singleton di DynamoDB?

Item singleton adalah satu baris DynamoDB di bawah key tetap yang di-hardcode yang menahan state global untuk seluruh aplikasi — feature flag, blob config, versi sistem — alih-alih satu record per pengguna atau order. Karena Anda selalu tahu key-nya, Anda membacanya dengan GetItem dan meng-updatenya dengan plus condition expression.

  • Singleton adalah satu item dengan key konstan. Anda hardcode PK/SK di kode (mis. CONFIG#GLOBAL) alih-alih men-template id pengguna atau order.
  • Baca dengan GetItem, jangan pernah Scan. Anda selalu tahu key lengkap, jadi point read punya biaya datar dan prediktabel (paling banyak 1 RCU untuk item kecil) — tanpa filter, tanpa jalan-jalan tabel.
  • Itu menurut definisi. Setiap request bisa menyentuh partisi yang sama, jadi cache-lah dan jaga item tetap kecil; jangan jadikan bottleneck write.
  • Mutasi dengan aman memakai update + condition expression, bukan read-modify-write di app — di situlah race lost-update hidup.

Kenali polanya

Anda punya state global ketika data tidak di-scope ke satu entity. Beberapa tanda:

  • Flag yang sama untuk semua orang (signup_enabled = false).
  • Blob tunable yang dibaca app saat boot (rate limit, kuota default).
  • Counter atau nomor versi untuk seluruh sistem, bukan per-baris.

Apa pun yang di-scope ke pengguna, tenant, atau order bukan singleton — itu item biasa yang di-key oleh id entity itu. Singleton adalah iris global sisa yang tidak punya tempat lain untuk hidup.

Beri key konstan

Seluruh pola bergantung pada satu keputusan. Key adalah literal, bukan template. Untuk item feature-flag global di single-table yang overloaded, pilih prefix tetap dan nilai tetap:

PKSKattributes
SETTINGS#APPFLAGS#V1signup_enabled, maintenance_mode, ai_search_enabled

PK = "SETTINGS#APP" dan SK = "FLAGS#V1" dipanggang ke dalam kode. Tidak ada id pengguna, tidak ada id tenant — aplikasi meminta tepat item ini setiap kali. Prediktabilitas itu intinya: key yang diketahui adalah GetItem, dan GetItem adalah baca termurah dan paling konsisten yang ditawarkan DynamoDB.

Suffix V1 disengaja. Jika bentuk schema flag berubah nanti, Anda menulis item FLAGS#V2 dan memindahkan pembaca, alih-alih memutasi yang live in place. Mem-versi key singleton membeli seam migrasi yang bersih.

Baca dengan GetItem

Karena key sepenuhnya diketahui, Anda tidak pernah Query dan tidak pernah Scan untuk singleton. Scan membaca seluruh tabel dan memfilter di klien — footgun Scan klasik — dan berlebihan absurd untuk mengambil satu baris yang bisa Anda alamatkan langsung.

GetItem terhadap SETTINGS#APP / FLAGS#V1 mengembalikan flag dalam satu baca strongly- atau eventually-consistent. Pada on-demand di us-east-1, AWS menagih GetItem item ≤ 4 KB sebagai 0.5 RCU eventually-consistent atau 1 RCU strongly-consistent (docs capacity baca/tulis AWS). Jaga singleton tetap kecil dan biaya itu tetap datar selamanya — menggembungkan blob config ke blok 4 KB kedua menggandakan baca yang ditagih.

Di path baca, saat app boot atau request datang, Anda GetItem key tetap, Anda cache hasilnya. Alurnya:

yatidakApp / requestGetItem PK=SETTINGS#APPSK=FLAGS#V1Item ditemukan?Pakai flag, cache lokalJatuh ke default aman

Key tetap mengubah lookup global menjadi satu point read dengan path default bawaan.

Perhatikan cabang tidak: singleton yang hilang tidak boleh membuat Anda crash. Default ke nilai aman (feature off, maintenance on) agar celah first-deploy atau key buruk gagal tertutup, bukan terbuka.

Update tanpa race

Jebakannya adalah meng-update singleton dengan read-modify-write di app: Anda GetItem flag, membalik satu di memori, lalu PutItem seluruhnya kembali. Dua writer concurrent sama-sama membaca item lama dan Put kedua menghancurkan perubahan yang pertama. Lost update.

Dua fitur DynamoDB membunuh race tanpa locking di sisi app:

  • memutasi satu atribut di server, meninggalkan sisanya utuh. Tidak perlu me-Put ulang seluruh item.
  • membuat write berhasil hanya jika item masih terlihat seperti yang Anda harapkan, jadi write basi ditolak dengan ConditionalCheckFailedException (docs condition expression AWS).

Untuk membalik satu flag, target hanya atribut itu dengan SET dan jaga dengan bump versi agar writer concurrent tidak saling injak:

# UpdateItem
Key                  PK=SETTINGS#APP  SK=FLAGS#V1
UpdateExpression     SET signup_enabled = :on, schema_version = :next
ConditionExpression  schema_version = :current

Jika dua writer race, cek schema_version = :current yang kedua gagal dan ia retry terhadap nilai segar. Anda bisa menyiapkan nama, nilai, dan bentuk ekspresi tepat ini di DynamoDB Expression Builder sebelum memasangnya ke kode. Untuk melihat operator lebih dalam, lihat panduan idiom update-expression.

Perhatikan hot key

Singleton, menurut konstruksi, adalah hot key — setiap bagian app Anda mungkin membaca partisi yang sama. Itu baik untuk baca jika Anda cache, tetapi itu satu-satunya risiko nyata pola ini.

  • Cache agresif. Baca flag sekali per proses (atau setiap N detik), bukan di setiap request. Nilai singleton adalah yang termurah untuk di-memoize.
  • Jangan jadikan hot spot write. Flag yang di-toggle admin beberapa kali sehari bukan apa-apa. Singleton yang Anda increment di setiap request adalah bottleneck throughput partisi — itu masalah counter, bukan singleton.
  • Jaga tetap kecil. Biaya baca berskala dengan ukuran item dalam blok 4 KB. Blob config yang gembung membuat setiap boot lebih mahal dari yang perlu.

Jika Anda benar-benar butuh counter global write-tinggi, singleton adalah bentuk yang salah — shard lintas N item dan jumlahkan saat baca. Itu pola berbeda.

Singleton vs item per-entity

Garisnya sederhana: ke apa data di-scope.

Item singletonItem per-entity
KeyKonstanta hardcode (SETTINGS#APP)Template dengan id (USER#42)
BerapaTepat satuSatu per pengguna / order / tenant
Baca tipikalGetItem pada key yang diketahuiGetItem atau Query by entity
ScopeSeluruh aplikasiSatu entity
Pakai untukFlag global, config, versi sistemProfil, order, apa pun per-id

Jika Anda ingin dua singleton jenis yang sama, Anda tidak punya singleton — Anda punya item per-entity dan entity-nya adalah yang lupa Anda key-kan (config per-tenant, misalnya).

Jebakan dan langkah selanjutnya

  • Jangan Scan untuk menemukannya. Anda tahu key-nya; alamatkan langsung.
  • Jangan read-modify-write. Pakai update + condition expression.
  • Jangan biarkan hilang diam-diam. Default ke nilai aman pada cache miss.
  • Jangan overload dengan write frekuensi tinggi. Itu pekerjaan counter yang di-shard.

Singleton hidup nyaman di dalam single-table design — itu hanya satu item collection lagi dengan key tetap di samping baris entity Anda.

Coba DynoTable untuk menjelajah tabel Anda, menemukan baris singleton lewat key tetapnya, dan mengedit flag dengan tangan sambil Anda membangun path write.

Diperbarui