Model konsistensi DAX dan DynamoDB - Amazon DynamoDB

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Model konsistensi DAX dan DynamoDB

Amazon DynamoDB Accelerator (DAX) adalah layanan caching write-through yang dirancang untuk menyederhanakan proses menambahkan cache ke tabel DynamoDB. Karena DAX beroperasi secara terpisah dari DynamoDB, penting bahwa Anda harus memahami konsistensi model DAX dan DynamoDB untuk memastikan bahwa aplikasi Anda berfungsi seperti yang Anda harapkan.

Dalam banyak kasus penggunaan, cara aplikasi Anda menggunakan DAX mempengaruhi konsistensi data dalam klaster DAX, dan konsistensi data antara DAX dan DynamoDB.

Konsistensi di antara node cluster DAX

Untuk mencapai ketersediaan tinggi untuk aplikasi Anda, kami sarankan Anda menyediakan klaster DAX Anda dengan setidaknya tiga simpul. Kemudian tempatkan simpul tersebut di beberapa Availability Zone dalam Wilayah.

Ketika klaster DAX Anda sedang dijalankan, klaster itu mereplikasi data di antara semua simpul dalam klaster (dengan asumsi bahwa Anda menetapkan lebih dari satu simpul). Pertimbangkan sebuah aplikasi yang melakukan UpdateItem dengan berhasil menggunakan DAX. Tindakan ini menyebabkan cache item di simpul primer untuk dimodifikasi dengan nilai baru. Nilai itu kemudian direplikasi ke semua simpul lain dalam klaster. Replikasi ini akhirnya konsisten dan biasanya membutuhkan waktu kurang dari satu detik untuk menyelesaikan.

Dalam skenario ini, mungkin untuk dua klien dalam membaca kunci yang sama dari klaster DAX yang sama tetapi menerima nilai yang berbeda, tergantung pada simpul yang diakses setiap klien. Simpul semua konsisten ketika update telah sepenuhnya direplikasi di seluruh semua simpul dalam klaster. (Perilaku ini mirip dengan sifat konsisten DynamoDB.)

Jika Anda sedang membangun sebuah aplikasi yang menggunakan DAX, aplikasi itu harus dirancang sehingga dapat mentolerir data konsisten.

perilaku cache item DAX

Setiap klaster DAX memiliki dua cache yang berbeda, cache item dan cache kueri. Untuk informasi selengkapnya, lihat DAX: Cara kerjanya.

Bagian ini membahas implikasi konsistensi dari pembacaan dari dan menulis ke cache item DAX.

Konsistensi Pembacaan

Dengan DynamoDB, operasi GetItem melakukan bacaan akhir konsisten secara default. Misalkan Anda menggunakan UpdateItem dengan klien DynamoDB. Jika Anda kemudian mencoba untuk membaca item yang sama segera setelah itu, Anda mungkin melihat data yang muncul sebelum pembaruan. Hal ini disebabkan penundaan propagasi di semua lokasi penyimpanan DynamoDB. Konsistensi biasanya tercapai dalam hitungan detik. Jadi jika Anda mencoba kembali membaca, Anda mungkin akan melihat item yang diperbarui.

Saat Anda menggunakan GetItem dengan klien DAX, operasi (dalam kasus ini, bacaan akhir konsisten) berjalan seperti yang ditunjukkan berikut ini.


                    Diagram alur kerja menunjukkan langkah-langkah bernomor untuk memperbarui item.
  1. Klien DAX mengeluarkan permintaan GetItem. DAX mencoba untuk membaca item yang diminta dari cache item. Jika item dalam cache (cache hit), DAX mengembalikannya ke aplikasi.

  2. Jika item tidak tersedia (cache miss), DAX melakukan operasi GetItem konsisten terhadap DynamoDB.

  3. DynamoDB mengembalikan item yang diminta, dan DAX menyimpannya dalam cache item.

  4. DAX mengembalikan item ke aplikasi.

  5. (Tidak ditampilkan) Jika klaster DAX berisi lebih dari satu simpul, item direplikasi ke semua simpul lain dalam klaster.

Item tetap dalam cache item DAX, tunduk pada pengaturan Waktu untuk Tayang (TTL) dan algoritme yang paling baru-baru ini digunakan (LRU) untuk cache. Untuk informasi selengkapnya, lihat DAX: Cara kerjanya.

Namun, selama periode ini, DAX tidak membaca ulang item dari DynamoDB. Jika orang lain memperbarui item menggunakan klien DynamoDB, melewati DAX seluruhnya, permintaan GetItem menggunakan klien DAX menghasilkan hasil yang berbeda dari permintaan GetItem menggunakan klien DynamoDB. Dalam skenario ini, DAX dan DynamoDB memegang nilai-nilai yang tidak konsisten untuk bukti kunci yang sama sampai TTL untuk DAX item kedaluwarsa.

Jika aplikasi memodifikasi data dalam tabel DynamoDB dasar, melewati DAX, aplikasi perlu mengantisipasi dan mentolerir inkonsistensi data yang mungkin terjadi.

catatan

Selain itu GetItem, klien DAX juga mendukung permintaan BatchGetItem. BatchGetItem pada dasarnya adalah pembungkus sekitar satu permintaan atau lebih GetItem, sehingga DAX memperlakukan masing-masing sebagai operasi GetItem individu.

Konsistensi Penulisan

DAX adalah cache write-through, yang menyederhanakan proses penjagaan cache item DAX agar konsisten dengan tabel DynamoDB dasar.

Klien DAX mendukung operasi API penulisan yang sama seperti DynamoDB (PutItem, UpdateItem, DeleteItem, BatchWriteItem, dan TransactWriteItems). Ketika Anda menggunakan operasi ini dengan klien DAX, item diubah dalam DAX dan DynamoDB. DAX memperbarui item dalam cache item, terlepas dari nilai TTL untuk item ini.

Misalnya, anggaplah Anda membuat permintaan GetItem dari klien DAX untuk membaca item dari tabel ProductCatalog. (Kunci partisinya adalah Id, dan tidak ada kunci lain seperti itu.) Anda mengambil item yang Id adalah 101. Nilai QuantityOnHand untuk item itu adalah 42. DAX menyimpan item dalam cache item dengan TTL tertentu. Untuk contoh ini, TTL diasumsikan 10 menit. Lalu, 3 menit kemudian, aplikasi lain menggunakan klien DAX untuk memperbarui item yang sama sehingga nilai QuantityOnHand sekarang adalah 41. Dengan asumsi bahwa item tidak diperbarui lagi, pembacaan item yang sama berikutnya dalam 10 menit berikutnya akan mengembalikan nilai cache untuk QuantityOnHand (41).

Cara DAX Memproses Penulisan

DAX ditujukan untuk aplikasi yang memerlukan pembacaan performa tinggi. Sebagai cache write-through, DAX melewati penulisan Anda melalui DynamoDB secara serentak, kemudian secara otomatis dan secara tidak langsung mereplikasi pembaruan hasil untuk cache item Anda di semua simpul dalam klaster. Anda tidak perlu mengelola logika pembatalan cache karena DAX menanganinya untuk Anda.

DAX mendukung operasi penulisan berikut: PutItem, UpdateItem, DeleteItem, BatchWriteItem, dan TransactWriteItems.

Ketika Anda mengirim permintaan PutItem, UpdateItem, DeleteItem, atau BatchWriteItem untuk DAX, hal berikut akan terjadi:

  • DAX mengirimkan permintaan ke DynamoDB.

  • DynamoDB membalas DAX, mengkonfirmasikan bahwa penulisan berhasil.

  • DAX menulis item ke cache item.

  • DAX mengembalikan status berhasil ke peminta.

Ketika Anda mengirim permintaan TransactWriteItems ke DAX, hal berikut akan terjadi:

  • DAX mengirimkan permintaan ke DynamoDB.

  • DynamoDB membalas DAX, mengkonfirmasi bahwa transaksi selesai.

  • DAX mengembalikan status berhasil ke peminta.

  • Di latar belakang, DAX membuat permintaan TransactGetItems untuk setiap item dalam permintaan TransactWriteItems untuk menyimpan item dalam cache item. TransactGetItems digunakan untuk memastikan isolasi yang dapat diserialisasi.

Jika penulisan ke DynamoDB gagal dengan alasan apapun, termasuk throttling, item tidak di-cache di DAX. Pengecualian untuk kegagalan disampaikan ke peminta. Hal ini memastikan bahwa data tidak ditulis ke cache DAX kecuali ditulis terlebih dahulu dengan berhasil ke DynamoDB.

catatan

Setiap penulisan ke DAX akan mengubah status cache item. Namun, menulis ke cache item tidak mempengaruhi cache kueri. (cache item DAX dan cache kueri melayani tujuan yang berbeda, dan beroperasi secara independen dari satu sama lain.)

perilaku cache kueri DAX

DAX meng-cache hasil dari Query dan Scan permintaan dalam cache kueri. Namun, hasil ini tidak mempengaruhi cache item sama sekali. Saat aplikasi Anda meminta Query atau Scan dengan DAX, set hasil disimpan dalam cache kueri, tidak dalam cache item. Anda tidak dapat melakukan "pemanasan" cache item dengan melakukan operasi Scan karena cache item dan cache kueri entitas adalah terpisah.

Konsistensi query-update-query

Pembaruan untuk cache item, atau tabel DynamoDB dasar, tidak membatalkan atau merubah hasil yang disimpan dalam cache kueri.

Sebagai gambaran, pertimbangkan skenario berikut: Aplikasi bekerja dengan tabel DocumentRevisions, yang memiliki DocId sebagai kunci partisi dan RevisionNumber sebagai kunci.

  1. Klien meminta Query untuk DocId 101, untuk semua item yang RevisionNumber lebih besar dari atau sama dengan 5. DAX menyimpan set hasil dalam cache kueri dan mengembalikan set hasil untuk pengguna.

  2. Klien mengeluarkan permintaan PutItem untuk DocId 101 dengan RevisionNumber nilai 20.

  3. Klien mengeluarkan Query yang sama seperti yang dijelaskan pada langkah 1 (DocId 101 dan RevisionNumber >= 5).

Dalam skenario ini, set hasil yang di-cache untuk Query dikeluarkan pada langkah 3 adalah identik dengan hasil yang ditetapkan yang di-cache di langkah 1. Alasannya adalah bahwa DAX tidak membatalkan Query atau Scan set hasil berdasarkan pembaruan untuk masing-masing item. Operasi PutItem dari langkah 2 hanya tercermin dalam cache kueri DAX ketika TTL untuk Query kedaluwarsa.

Aplikasi Anda harus mempertimbangkan nilai TTL untuk cache kueri dan berapa lama aplikasi Anda dapat mentolerir hasil yang tidak konsisten antara cache kueri dan cache item.

Bacaan yang sangat konsisten dan transaksional

Untuk melakukan GetItem, BatchGetItem, Query, atau permintaan Scan yang sangat konsisten, Anda perlu mengatur parameter ConsistentRead agar tepat. DAX melewati pembacaan yang sangat konsisten ke DynamoDB. Ketika menerima respon dari DynamoDB, DAX mengembalikan hasil ke klien, tetapi bukan meng-cache hasil. DAX tidak dapat menyediakan pembacaan yang sangat konsisten dengan sendirinya karena itu tidak digabungkan dengan erat ke DynamoDB. Untuk alasan ini, setiap pembacaan berikutnya dari DAX pembacaannya harus konsisten. Dan setiap pembacaannya berikutnya akan sangat konsisten untuk melewati DynamoDB.

DAX menangani permintaan TransactGetItems dengan cara yang sama dalam menangani pembacaan yang sangat konsisten. DAX melewati semua permintaan TransactGetItems ke DynamoDB. Ketika menerima respon dari DynamoDB, DAX mengembalikan hasil ke klien, tetapi bukan meng-cache hasil.

Caching negatif

DAX mendukung entri cache negatif baik di cache item dan di cache kueri. Entri cache negatif terjadi ketika DAX tidak dapat menemukan item yang diminta dalam tabel DynamoDB dasar. Alih-alih menghasilkan kesalahan, DAX meng-cache hasil kosong dan mengembalikan hasil ke pengguna.

Sebagai contoh, misalkan aplikasi mengirimkan permintaan GetItem ke klaster DAX, dan tidak ada item yang cocok dalam cache item DAX. Hal ini menyebabkan DAX membaca item yang sesuai dari tabel DynamoDB dasar. Jika item tidak ada di DynamoDB, DAX menyimpan item kosong dalam cache item dan mengembalikan item kosong ke aplikasi. Sekarang anggaplah bahwa aplikasi mengirimkan permintaan GetItem lain untuk item yang sama. DAX menemukan item kosong dalam cache item dan mengembalikannya segera ke aplikasi. DAX tidak berunding dengan DynamoDB sama sekali.

Entri cache negatif tetap ada di cache item DAX sampai TTL itemnya kedaluwarsa, LRU-lah yang dipanggil, atau item diubah menggunakan PutItem, UpdateItem, atau DeleteItem.

Cache kueri DAX menangani hasil cache negatif dengan cara yang sama. Jika aplikasi melakukan Query atau Scan, dan cache kueri DAX tidak berisi hasil cache, DAX mengirimkan permintaan ke DynamoDB. Jika tidak ada item yang cocok dalam set hasil, DAX menyimpan set hasil kosong di cache kueri dan mengembalikan set hasil kosong ke aplikasi. Permintaan Query atau Scan selanjutnya menghasilkan set hasil (kosong) yang sama, hingga TTL untuk hasil tersebut kedaluwarsa.

Strategi untuk Penulis

Perilaku write-through DAX sesuai untuk banyak pola aplikasi. Namun, ada beberapa pola aplikasi di mana model write-through mungkin tidak sesuai.

Untuk aplikasi yang sensitif terhadap latensi, menulis melalui DAX menimbulkan lompatan jaringan tambahan. Jadi menulis ke DAX adalah sedikit lebih lambat dibanding menulis langsung ke DynamoDB. Jika aplikasi Anda sensitif untuk menulis latensi, Anda dapat mengurangi latensi dengan menulis langsung ke DynamoDB sebagai gantinya. Untuk informasi selengkapnya, lihatĀ Write-Around.

Untuk aplikasi write-intensive (seperti yang melakukan pembebanan data massal), Anda mungkin tidak ingin menulis semua data melalui DAX karena hanya sebagian kecil dari data yang pernah dibaca oleh aplikasi. Ketika Anda menulis sejumlah besar data melalui DAX, maka DAX harus memanggil algoritme LRU untuk membuat ruang di cache untuk item baru untuk dibaca. Hal ini mengurangi efektivitas DAX sebagai cache pembacaan.

Ketika Anda menulis item ke DAX, status cache item diubah untuk mengakomodasi item baru. (Misalnya, DAX mungkin perlu mengeluarkan data lama dari cache item untuk memberi ruang bagi item baru.) Item baru tetap dalam cache item, tunduk pada algoritme LRU cache dan pengaturan TTL untuk cache. Selama item tetap dalam cache item, DAX tidak membaca ulang item dari DynamoDB.

Tulis-semua (write-through)

Cache item DAX menerapkan kebijakan write-through. Untuk informasi selengkapnya, lihat Cara DAX Memproses Penulisan.

Ketika Anda menulis item, DAX memastikan bahwa item cache disinkronkan dengan item yang ada di DynamoDB. Ini sangat membantu untuk aplikasi yang perlu membaca ulang item segera setelah menulisnya. Namun, jika aplikasi lain menulis langsung ke tabel DynamoDB, item dalam cache item DAX tidak lagi sinkron dengan DynamoDB.

Untuk menggambarkan, pertimbangkan dua pengguna (Alice dan Bob), yang bekerja dengan tabel ProductCatalog. Alice mengakses tabel menggunakan DAX, tapi Bob melewati DAX dan mengakses tabel langsung di DynamoDB.


                    Diagram alur kerja menunjukkan langkah-langkah bernomor untuk memberi tahu cara pengguna Alice dan Bob mengakses tabel menggunakan DAX dan DynamoDB.
  1. Alice memperbarui item di tabel ProductCatalog. DAX meneruskan permintaan untuk DynamoDB, dan pembaruan berhasil. DAX kemudian menulis item ke cache item dan mengembalikan respon yang berhasil ke Alice. Sejak saat itu, sampai item tersebut akhirnya dihapus dari cache, setiap pengguna yang membaca item dari DAX akan melihat item dengan pembaruan Alice.

  2. Beberapa waktu kemudian, Bob memperbarui item ProductCatalog yang sama yang telah ditulis Alice. Namun, Bob memperbarui item langsung di DynamoDB. DAX tidak secara otomatis menyegarkan item cache dalam menanggapi pembaruan melalui DynamoDB. Oleh karena itu, pengguna DAX tidak melihat pembaruan Bob.

  3. Alice membaca item dari DAX lagi. Item ada di cache item, jadi DAX mengembalikannya ke Alice tanpa mengakses tabel DynamoDB.

Dalam skenario ini, Alice dan Bob melihat representasi yang berbeda dari item ProductCatalog yang sama. Hal ini terjadi sampai DAX menghapus item dari cache item, atau sampai pengguna lain memperbarui item yang sama lagi menggunakan DAX.

Write-Around

Jika aplikasi Anda perlu menulis data dalam jumlah besar (seperti beban data massal), mungkin masuk akal untuk melewati DAX dan menulis data langsung ke DynamoDB. Strategi seperti write-around mengurangi latensi penulisan. Namun, cache item tidak tetap sinkron dengan data di DynamoDB.

Jika Anda memutuskan untuk menggunakan strategi write-around, ingat bahwa DAX mengisi cache item setiap kali aplikasi menggunakan klien DAX untuk membaca data. Hal ini dapat menguntungkan dalam beberapa kasus karena memastikan bahwa hanya data yang paling sering dibaca cache (sebagai lawan dari data yang paling sering ditulis).

Sebagai contoh, pertimbangkan pengguna (Charlie) yang ingin bekerja dengan tabel yang berbeda, tabel GameScores, menggunakan DAX. Kunci partisi untuk GameScores adalah UserId, sehingga semua skor Charlie akan memiliki UserId yang sama.


                    Diagram alur kerja menunjukkan langkah-langkah bernomor untuk memberi tahu  Charlie cara menggunakan tabel DynamoDB menggunakan DAX.
  1. Charlie ingin mengambil semua skornya, sehingga ia mengirimkan Query ke DAX. Dengan asumsi bahwa permintaan ini belum dikeluarkan sebelumnya, DAX meneruskan kueri untuk DynamoDB untuk diproses. Itu akan menyimpan hasil dalam cache kueri DAX, dan kemudian mengembalikan hasil ke Charlie. Set hasil tetap tersedia dalam cache kueri sampai dihapus.

  2. Sekarang anggaplah bahwa Charlie memainkan game Meteor Blasters dan mencapai skor tinggi. Charlie mengirim permintaan UpdateItem ke DynamoDB, memodifikasi item dalam tabel GameScores.

  3. Akhirnya, Charlie memutuskan untuk menjalankan kembali Query sebelumnya untuk mengambil semua data dari GameScores. Charlie tidak melihat skor tinggi untuk Meteor Blasters di daftar hasil. Hal ini karena hasil kueri berasal dari cache kueri, bukan cache item. Kedua cache independen satu sama lain, sehingga perubahan dalam satu cache tidak mempengaruhi cache lainnya.

DAX tidak menyegarkan set hasil dalam cache kueri dengan data terbaru dari DynamoDB. Setiap set hasil yang ditetapkan dalam cache kueri saat ini sebagai waktu yang Query atau operasi Scan yang dilakukan. Jadi, hasil Query Charlie tidak mencerminkan operasi PutItem. Hal ini terjadi sampai DAX menghapus set hasil dari cache kueri.