Menengah5 menit baca

Penghitung Atom DynamoDB: Cara Kerja ADD, dan Kapan Tidak

Penghitung atom adalah atribut numerik yang Anda gunakan dengan satu atribut Panggilan UpdateItem — tidak ada baca dulu, tidak ada lomba baca-modifikasi-tulis. DynamoDB berlaku setiap kenaikan dalam urutan kedatangan dan tidak pernah membiarkan dua penulis saling mengalahkan menghitung.

Apa itu penghitung atom DynamoDB?

Penghitung atom DynamoDB adalah atribut numerik yang Anda tambahkan dengan satu panggilan UpdateItem menggunakan ekspresi pembaruan ADD (atau SET x = x + :n). DynamoDB membaca, menambahkan, dan menulis nilai di sisi server, sehingga penulis secara bersamaan membuat serialisasi tanpa kehilangan pembaruan — namun ini tidak idempoten, jadi panggilan yang dicoba ulang akan bertambah dua kali.

  • Gunakan ADD (atau SET x = x + :n) untuk menambah satu panggilan. DynamoDB berbunyi, menambahkan, dan menulis di sisi server — pemanggil secara bersamaan membuat serial, tidak ada pembaruan yang hilang.
  • Tidak perlu dibaca dulu. Berasal dari SQL Anda akan SELECT lalu UPDATE; di sini kamu lewati pembacaan seluruhnya dan operasi masih aman dalam konkurensi.
  • Penghitung atom bukan idempoten. Percobaan ulang peningkatan UpdateItem lagi. Jika Anda tidak dapat menoleransi penghitungan berlebih atau kurang, gunakan .
  • ADD pada atribut yang hilang dimulai dari 0, jadi kenaikan pertama saja berhasil — tidak diperlukan penulisan awal.

Masalah dengan baca-modifikasi-tulis

Katakanlah Anda melacak penayangan pada suatu video. Naluri naif, langsung dari SQL, adalah: GetItem, tambahkan satu di aplikasi Anda, PutItem total baru kembali.

Dua penonton menekan tombol play sekaligus. Keduanya membaca views = 41. Keduanya menulis 42. kamu menghitung satu tampilan, bukan dua. Itu adalah pembaruan yang hilang — konkurensi klasik footgun, dan itu tidak muncul sampai Anda memiliki lalu lintas.

Di SQL Anda akan menghindarinya dengan UPDATE videos SET views = views + 1, mendorong aritmatika ke dalam database. DynamoDB memiliki gerakan yang sama, dan itu keseluruhan titik penghitung atom.

Peningkatan dalam satu panggilan

Buat model item statistik per video. Kunci partisi VID#<id>, kunci pengurutan STATS#TOTAL, dengan play_count numerik:

PKSKplay_count
"VID#9f3a""STATS#TOTAL"41

Untuk mendaftarkan permainan, kirimkan satu UpdateItem dengan klausa ADD:

# UpdateItem
Key               PK = "VID#9f3a", SK = "STATS#TOTAL"
UpdateExpression  ADD play_count :one
Values            :one = 1

DynamoDB membaca play_count, menambahkan 1, dan menulis hasilnya di dalam satu operasi sisi server. Tidak ada peluang bagi penulis lain untuk menyelinap masuk. Sepuluh pemutaran bersamaan menghasilkan +10, setiap saat — itulah yang "atomic" belikan untuk Anda.

Anda dapat membuat dan menyalin ekspresi persis ini — nama, nilai, dan keempatnya jenis klausa — dengan Pembuat Ekspresi DynamoDB.

ADD berfungsi bahkan ketika play_count belum ada: DynamoDB menangani yang hilang atribut numerik sebagai 0, jadi pemutaran pertama membuatnya di 1. Tidak ada benih terpisah menulis. ([AWS: Menggunakan ekspresi pembaruan] [perbarui])

TAMBAHKAN vs SET+: pilih salah satu

Dua ekspresi melakukan aritmatika yang sama. AWS merekomendasikan SET untuk penggunaan umum karena dibuat dengan tindakan SET lainnya dan dibaca lebih eksplisit. ([AWS: Menggunakan ekspresi pembaruan][upd])

ADD play_count :oneSET play_count = play_count + :one
Atribut hilangMembuatnya, mulai dari 0Kesalahan — memerlukan if_not_exists
Tipe dataAngka dan set sajaNomor (dan lainnya) melalui SET
Gabungkan dengan SETKlausul terpisahSatu klausa SET, dipisahkan koma
Panduan AWSBaik untuk counterStandar yang disarankan

Jika atributnya mungkin tidak ada dan Anda menginginkan SET, jagalah: SET play_count = if_not_exists(play_count, :zero) + :one. Dengan ADD Anda lewati itu - itu diunggulkan dari 0 secara gratis.

Tuliskan biaya setiap kenaikan

Sesuai permintaan di us-east-1, setiap UpdateItem dengan ADD ditagih 1 WCU per KB ukuran barang setelah ditulis (dibulatkan ke atas). Baris statistik 900 byte biaya 1 WCU per permainan yang didaftarkan; sepuluh permainan serentak masih mendarat sebagai 10 WCU total, tidak satu pun. Membagikan penghitung ke seluruh partisi akan memindahkan batas throughput tanpa mengubah perhitungan WCU per item. Ukur baris dengan kalkulator ukuran item dan laju saluran panas jalur di kalkulator harga.

Lakukan di DynoTable

Buka item statistik untuk memeriksa penghitung langsung, lalu gulung penghitung pecahan dengan SUM dan GROUP BY di SQL Workbench untuk melihat total semuanya baris STATS#TOTAL#0..N. Untuk menyusun kenaikan itu sendiri, gunakan web DynamoDB Expression Builder untuk membuat Ekspresi ADD UpdateItem, nama dan nilai disertakan.

Perangkapnya: penghitung tidak idempoten

Penghitung atom bertambah setiap kali UpdateItem dijalankan. (AWS: Bekerja dengan item)

Bayangkan kegagalan jaringan: Anda mengirim kenaikan, koneksi turun sebelum tanggapannya kembali, dan Anda tidak tahu apakah tanggapan itu berhasil. Anda mencoba lagi. Jika panggilan pertama did berhasil, kini Anda telah menghitung permainan itu dua kali.

Untuk penayangan video, tidak apa-apa — beberapa penghitungan ganda dalam sejuta pemutaran tidak ada salahnya siapa pun, dan AWS menyebut kasus "lacak pengunjung" ini sebagai penggunaan kanonik penghitung atom. (AWS: Bekerja dengan item)

Tidak baik untuk apa pun yang harus tepat: inventaris yang dapat Anda jual secara berlebihan, kredit yang dapat Anda belanjakan dua kali lipat, saldo yang dapat Anda rusak. Di sana, raih a pembaruan bersyarat.

Saat Anda membutuhkan ketepatan: pembaruan bersyarat

Pembaruan bersyarat adalah idempoten jika Anda mengkondisikan atribut yang sama dengan Anda berubah. Tambahkan play_count ke 42, namun hanya jika saat ini 41:

# UpdateItem
Key                  PK = "VID#9f3a", SK = "STATS#TOTAL"
UpdateExpression     SET play_count = :next
ConditionExpression  play_count = :current
Values               :next = 42, :current = 41

Sekarang percobaan ulang aman: jika penulisan pertama telah memindahkan play_count ke 42, maka kondisi play_count = 41 gagal untuk kedua kalinya dan tidak ada perubahan. (AWS: Bekerja dengan item)

Biayanya adalah konkurensi. Dua penulis berlomba dengan kondisi yang sama berarti yang satu menang dan seseorang mendapat ConditionalCheckFailedException untuk mencoba lagi — Anda telah menukarnya throughput penghitung tanpa syarat untuk kebenaran. Tepatnya, bantah counter itu perdagangan yang tepat. Untuk jumlah penayangan, itu berlebihan.

Jebakan

  • Satu . Satu baris penghitung adalah satu kunci partisi. Sebuah video viral memalu VID#9f3a / STATS#TOTAL dapat mencapai batas maksimum penulisan per partisi. Pecahkan: sebarkan penulisan ke STATS#TOTAL#0..N dan jumlahkan saat dibaca.
  • Tidak ada penambahan batch. BatchWriteItem hanya dapat dimasukkan/dihapus — tidak dapat dijalankan . Penghitung melewati UpdateItem, satu item per panggilan. Jika Anda harus menabrak beberapa penghitung secara atom, TransactWriteItems menjalankan tindakan Pembaruan hingga 100 item dalam satu permintaan, di kira-kira dua kali lipat biaya penulisan.
  • ADD hanya berupa angka dan set. Tidak akan menyentuh string atau boolean; itu SET. Lihat Tipe data DynamoDB untuk selengkapnya model atribut.

Langkah selanjutnya

Penghitung atom adalah pola penulisan; bagaimana Anda membaca mengumpulkan kembali adalah sebuah pemodelan pertanyaan — lihat desain meja tunggal untuk menyimpan item statistik di samping induknya, dan Query vs Scan jadi menggulung penghitung pecahan tetap menjadi Query.

Draf dan salin penambahannya ke dalam Pembuat Ekspresi DynamoDB, lalu coba DynoTable untuk menjalankan pembaruan atom pada tabel Anda sendiri dan perhatikan hitungannya bergerak.

Diperbarui