Perbedaan antara indeks lokal dan global di DynamoDB

128

Saya ingin tahu tentang dua indeks sekunder dan perbedaan di antara mereka. Sulit membayangkan bagaimana ini terlihat. Dan saya pikir, ini akan membantu lebih banyak orang daripada hanya saya.

Michael Czolko
sumber
1
Dijawab dalam FAQ DynamoDB . Cari "Apa perbedaan indeks sekunder global dengan indeks sekunder lokal?"
markdsievers
1
Tidak begitu mudah ditemukan dari FAQ sekarang. Mungkin direorganisasi
binithb

Jawaban:

114

Indeks Sekunder Lokal masih mengandalkan Kunci Hash asli. Ketika Anda menyediakan tabel dengan kisaran hash +, pikirkan LSI sebagai hash + range1, hash + range2 .. hash + range6. Anda mendapatkan 5 atribut rentang lebih untuk ditanyakan. Juga, hanya ada satu throughput yang disediakan.

Global Secondary Indexes mendefinisikan paradigma baru - kunci hash / range yang berbeda per indeks.
Ini memecah penggunaan asli satu kunci hash per tabel. Ini juga mengapa ketika mendefinisikan GSI Anda harus menambahkan throughput yang disediakan per indeks dan membayar untuk itu.

Informasi lebih rinci tentang perbedaan dapat ditemukan dalam pengumuman GSI

Chen Harel
sumber
2
Mungkin ingin menambahkan 1) indeks sekunder, baik LSI atau GSI, tidak ada hubungannya dengan keunikan
user1322092
1
Anda diizinkan memiliki hingga 5 Indeks Sekunder Lokal, itu sebabnya Chen Harel mengatakan "Anda mendapatkan 5 atribut rentang lebih untuk ditanyakan" .
Felipe Alvarez
93

Berikut adalah definisi formal dari dokumentasi:

Global secondary index - indeks dengan hash dan range key yang bisa berbeda dari yang ada di tabel. Indeks sekunder global dianggap "global" karena kueri pada indeks dapat menjangkau semua data dalam sebuah tabel, di semua partisi.

Indeks sekunder lokal - indeks yang memiliki kunci hash yang sama dengan tabel, tetapi kunci rentang yang berbeda. Indeks sekunder lokal adalah "lokal" dalam arti bahwa setiap partisi dari indeks sekunder lokal dibatasi untuk partisi tabel yang memiliki kunci hash yang sama.

Namun, perbedaannya jauh melampaui kemungkinan dalam hal definisi kunci. Temukan di bawah ini beberapa faktor penting yang secara langsung akan berdampak pada biaya dan upaya untuk mempertahankan indeks:

  • Throughput:

Indeks Sekunder Lokal mengkonsumsi throughput dari tabel. Saat Anda query catatan melalui indeks lokal, operasi mengkonsumsi unit kapasitas baca dari tabel. Saat Anda melakukan operasi tulis (buat, perbarui, hapus) dalam tabel yang memiliki indeks lokal, akan ada dua operasi tulis, satu untuk tabel yang lain untuk indeks. Kedua operasi akan mengkonsumsi unit kapasitas tulis dari tabel.

Global Secondary Indexes memiliki throughput yang disediakan sendiri, ketika Anda meminta indeks operasi akan mengkonsumsi kapasitas baca dari indeks, ketika Anda melakukan operasi tulis (buat, perbarui, hapus) dalam tabel yang memiliki indeks global, akan ada dua tulis operasi, satu untuk tabel lain untuk indeks *.

* Ketika mendefinisikan throughput yang disediakan untuk Global Secondary Index, pastikan Anda memberi perhatian khusus pada persyaratan berikut:

Agar tabel menulis berhasil, pengaturan throughput yang disediakan untuk tabel dan semua indeks sekunder globalnya harus memiliki kapasitas menulis yang cukup untuk mengakomodasi penulisan; jika tidak, tulisan di atas meja akan dicekik.

  • Manajemen:

Indeks Sekunder Lokal hanya dapat dibuat saat Anda membuat tabel, tidak ada cara untuk menambahkan Indeks Sekunder Lokal ke tabel yang ada, juga setelah Anda membuat indeks, Anda tidak dapat menghapusnya.

Indeks Sekunder Global dapat dibuat saat Anda membuat tabel dan ditambahkan ke tabel yang ada, menghapus Indeks Sekunder Global yang ada juga diperbolehkan.

  • Baca Konsistensi:

Indeks Sekunder Lokal mendukung konsistensi akhirnya atau kuat, sedangkan, Indeks Sekunder Global hanya mendukung konsistensi akhirnya.

  • Proyeksi:

Indeks Sekunder Lokal memungkinkan pengambilan atribut yang tidak diproyeksikan ke indeks (walaupun dengan biaya tambahan: kinerja dan unit kapasitas yang dikonsumsi). Dengan Global Secondary Index Anda hanya dapat mengambil atribut yang diproyeksikan ke indeks.

Pertimbangan Khusus tentang Keunikan Kunci yang Didefinisikan untuk Indeks Sekunder:

Dalam Indeks Sekunder Lokal, nilai kunci rentang TIDAK perlu unik untuk nilai kunci hash tertentu, hal yang sama berlaku untuk Indeks Sekunder Global, nilai kunci (Hash dan Rentang) TIDAK perlu unik.

Sumber: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html

bsd
sumber
1
" Global Secondary Indexes memiliki throughput yang disediakan sendiri, ketika Anda meminta indeks, operasi akan menggunakan kapasitas baca dari tabel " - Salah. Permintaan atau pemindaian pada indeks sekunder global menggunakan unit kapasitas dari indeks, bukan dari tabel dasar.
ethanxyz_0
1
@bsd Masuk akal untuk menambahkan catatan tentang satu batasan utama yang diterapkan oleh LSI: "Untuk tabel dengan indeks sekunder lokal, ada batas ukuran 10 GB per nilai kunci partisi. Tabel dengan indeks sekunder lokal dapat menyimpan semua jumlah item, selama ukuran total untuk nilai kunci satu partisi tidak melebihi 10 GB. " ( docs.aws.amazon.com/amazondynamodb/latest/developerguide/… )
wvdz
29

Ini adalah kemungkinan pencarian berdasarkan indeks:

  • Oleh Hash
  • Dengan Hash + Range
  • Dengan Hash + Indeks Lokal
  • Menurut indeks Global
  • Dengan indeks Global + Rentang Indeks

Indeks Hash dan Range tabel: Ini adalah indeks biasa dari versi sebelumnya Amazon AWS SDK.

Indeks Global dan Lokal: Ini adalah indeks 'tambahan' yang dibuat di atas meja, di samping indeks hash dan rentang tabel yang ada. Indeks global mirip dengan hash. Indeks rentang berperilaku mirip dengan indeks rentang yang digunakan dengan hash tabel. Dalam model entitas Anda dalam kode Anda, rajin rajin beranotasi dengan cara ini:

  • Untuk indeks global:

    @DynamoDBIndexHashKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
    @DynamoDBAttribute(attributeName = PROPERTY_USER)
    public String getUser() {
        return user;
    }
    
  • Untuk rentang indeks yang terkait dengan indeks global:

    @DynamoDBIndexRangeKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
    @DynamoDBAttribute(attributeName = PROPERTY_TIMESTAMP)
    public String getTimestamp() {
        return timestamp;
    }
    

Selain itu, jika Anda membaca tabel dengan indeks Global, itu harus berupa pembacaan akhirnya (bukan Pembacaan konsisten):

queryExpression.setConsistentRead(false);
Carlos AG
sumber
20

Satu cara untuk mengatakannya adalah ini:

LSI - memungkinkan Anda untuk melakukan kueri pada Hash-Key tunggal sambil menggunakan beberapa atribut berbeda untuk "memfilter" atau membatasi kueri.

GSI - memungkinkan Anda untuk melakukan kueri pada banyak Hash-Keys dalam sebuah tabel, sebagai hasilnya biaya tambahan dalam throughput.

Rincian tipe tabel yang lebih luas dan cara kerjanya, di bawah:

Hanya Hash

Seperti yang mungkin sudah Anda ketahui; Hash-Key dengan sendirinya harus unik karena menulis ke Hash-Key yang sudah ada akan menimpa data yang ada.

Hash + Range

Hash-Key + Range-Key memungkinkan Anda untuk memiliki beberapa Kunci Hash yang sama, selama mereka memiliki tombol rentang yang berbeda. Dalam hal ini, jika Anda menulis ke Hash-Key yang sudah ada, tetapi menggunakan Range-Key yang belum digunakan oleh Hash-Key itu, itu membuat item baru, sedangkan jika item dengan kombinasi Hash + Range yang sama sudah ada, itu menimpa item yang cocok.

Cara lain untuk memikirkan ini adalah seperti file dengan format. Anda dapat memiliki file dengan nama yang sama (hash) dengan yang lain, dalam folder yang sama (tabel), selama format (rentang) mereka berbeda. Demikian juga, Anda dapat memiliki banyak file dengan format yang sama selama namanya berbeda.

LSI

LSI pada dasarnya sama dengan Hash-Key + Range-Key, dan mengikuti aturan yang sama seperti itu, saat membuat item, kecuali bahwa Anda juga harus memberikan nilai untuk LSI, juga; mereka tidak dapat dibiarkan kosong / nol.

Mengatakan LSI adalah "Range-Key 2" tidak sepenuhnya benar karena Anda tidak dapat memiliki (menggunakan file saya dan memformat analogi dari sebelumnya) file bernama: file.format.lsidan file.format.lsi2. Namun, Anda dapat memiliki file.format.lsidan file.format2.lsiatau file.format.lsidan file2.format.lsi.

Pada dasarnya, LSI hanyalah "Filter-key", bukan Range-Key yang sebenarnya; kombinasi nilai Hash dan Rentang dasar Anda masih harus unik sedangkan nilai LSI tidak harus unik sama sekali. Cara yang lebih mudah untuk melihatnya mungkin dengan menganggap LSI sebagai data dalam file. Anda bisa menulis kode yang menemukan semua file dengan nama "PROJECT101", terlepas dari mereka fileFormat, kemudian membaca data di dalamnya untuk menentukan apa yang harus dimasukkan dalam permintaan dan apa yang dihilangkan. Ini pada dasarnya bagaimana LSI bekerja (hanya tanpa biaya tambahan membuka file untuk membaca isinya).

GSI

Untuk GSI, Anda pada dasarnya membuat tabel lain untuk masing-masing GSI, tetapi tanpa kesulitan mempertahankan beberapa tabel terpisah yang mencerminkan data di antara mereka; Inilah sebabnya mengapa mereka membutuhkan lebih banyak throughput.

Jadi untuk GSI, Anda dapat menentukan fileNamesebagai Hash-Key fileFormatdasar Anda , dan sebagai Range-Key dasar Anda. Anda kemudian dapat menentukan GSI yang memiliki Hash-Key fileName2dan Range-Key of fileFormat2. Anda kemudian dapat meminta salah satu fileNameatau fileName2jika Anda suka, tidak seperti LSI di mana Anda hanya dapat meminta fileName.

Keuntungan utama adalah bahwa Anda hanya perlu mempertahankan satu tabel, bukan 2, dan setiap kali Anda menulis ke Hash / Range primer atau Hash / Range GSI, yang lain akan secara otomatis diperbarui juga, jadi Anda tidak bisa "lupa" untuk memperbarui tabel lain seperti yang Anda bisa dengan pengaturan multi-tabel. Juga, tidak ada kemungkinan koneksi yang hilang setelah memperbarui satu dan sebelum memperbarui yang lain, seperti ada dengan pengaturan multi-tabel.

Selain itu, GSI dapat "tumpang tindih" kombinasi Hash / Range dasar. Jadi, jika Anda ingin membuat tabel dengan fileNamedan fileFormatsebagai basis Hash / Range dan filePrioritydan fileNamesebagai GSI Anda, Anda bisa.

Terakhir, kombinasi HSI + Rentang GSI tidak harus unik, sedangkan kombinasi Hash + Rentang dasar harus unik. Ini adalah sesuatu yang tidak mungkin dengan pengaturan tabel ganda / multi, tetapi dengan GSI. Akibatnya, Anda HARUS memberikan nilai untuk basis DAN GSI Hash + Range, saat memperbarui; tidak satupun dari nilai-nilai ini dapat kosong / nol.

DGolberg
sumber
13

Cara lain untuk menjelaskan: LSI membantu Anda melakukan kueri tambahan pada item dengan Kunci Hash yang sama. GSI membantu Anda melakukan pertanyaan serupa pada item "di seberang meja". Sangat bermanfaat.

Jika Anda memiliki tabel profil pengguna: id unik, nama, email. Di sini jika Anda perlu membuat tabel dapat dicari pada nama, email - maka satu-satunya cara adalah membuatnya GSI (LSI tidak akan membantu)

Sony Kadavan
sumber
1

Dokumentasi ini memberikan penjelasan yang cukup bagus:

https://aws.amazon.com/blogs/aws/now-available-global-secondary-indexes-for-amazon-dynamodb/

Saya tidak bisa mengomentari Pertanyaan ini, tetapi yang lebih baik dalam hal kinerja menulis dan membaca:

(Indeks Lokal dengan Table membaca dan menulis throughput 100) atau (Indeks global dengan throughput baca / tulis 50 bersama dengan throughput baca / tulis tabel 50?)

Saya tidak perlu kunci partisi terpisah untuk kasus penggunaan saya, jadi indeks lokal harus cukup untuk fungsi yang diperlukan.

Sindhu
sumber
0

GSI tidak dapat digunakan untuk pembacaan yang konsisten.

LSI dapat digunakan untuk pembacaan yang konsisten tetapi mereka akan membatasi ukuran partisi utama hingga 10GB. Juga LSI hanya dapat dibuat pada pembuatan tabel.

david_adler
sumber