Mengapa Cassandra merekomendasikan untuk tidak membuat indeks pada kolom kardinalitas tinggi?

10

Dokumentasi Cassandra menyatakan,

Jangan gunakan indeks dalam situasi ini:

  • Pada kolom kardinalitas tinggi karena Anda kemudian meminta volume rekaman yang besar untuk sejumlah kecil hasil. Lihat Masalah menggunakan indeks kolom kardinalitas tinggi di bawah ini.

Ini berlanjut,

Jika Anda membuat indeks pada kolom kardinalitas tinggi, yang memiliki banyak nilai berbeda, kueri di antara bidang akan menimbulkan banyak pencarian untuk hasil yang sangat sedikit. Di meja dengan satu miliar lagu, mencari lagu oleh penulis (nilai yang biasanya unik untuk setiap lagu) alih-alih oleh artis mereka, cenderung sangat tidak efisien. Mungkin akan lebih efisien untuk mempertahankan tabel secara manual sebagai bentuk indeks daripada menggunakan indeks bawaan Cassandra. Untuk kolom yang berisi data unik, kadang-kadang kinerja yang baik untuk menggunakan indeks untuk kenyamanan, selama volume kueri ke tabel yang memiliki kolom yang diindekskan sedang dan tidak di bawah beban konstan.

Tetapi tidak pernah benar-benar menjawab pertanyaan: mengapa itu tidak efisien? Saya tidak tahu apa artinya "mempertahankan tabel secara manual sebagai bentuk indeks". Tapi kemudian itu agak bertentangan dengan "... kadang-kadang kinerja yang baik untuk menggunakan indeks untuk kenyamanan selama volume permintaan moderat ..."

Apakah ini hanya mencoba untuk memberitahu saya untuk menggunakan PK kapan dan di mana saya bisa? Apa inefisiensi? Pemahaman saya adalah bahwa kueri yang akan memukul indeks perlu kueri setiap node dalam cluster, dan kemudian setiap node akan melakukan pencarian dalam indeks lokal dan hasilnya kemudian akan dikumpulkan. Ini belum tentu mahal (setiap pencarian indeks harus cukup murah) kecuali bahwa kita membayar dalam latensi jaringan, karena kita harus menunggu node paling lambat dari banyak. Apakah saya kehilangan sesuatu di sini?

Tetapi jika saya memiliki koleksi yang memiliki barang-barang bajillion yang - pada kesempatan langka - perlu dilihat oleh atribut yang berbeda tetapi hampir unik ... ini adalah penggunaan yang tepat, bukan?

¹Setiap? IDK jika replikasi berarti bahwa ini bisa mengenai 1/3 cluster untuk faktor replikasi 3 atau tidak?

Thanatos
sumber

Jawaban:

6

Dengan indeks Cassandra ( yaitu "indeks sekunder", sebagai lawan dari kunci primer), setiap node harus meng -query data lokalnya sendiri untuk menanggapi permintaan (lihat FAQ indeksex Cassandra sekunder ). Indeks ini juga dibangun menggunakan proses latar belakang . Latar belakang ini berarti bahwa indeks dapat mengembalikan negatif palsu dalam hal hit (atau positif palsu dalam hal kesalahan).

Ini berarti bahwa dalam kolom kardinalitas tinggi, laju perubahan ( yaitu penambahan / penghapusan) dari kolom itu bisa sangat tinggi. Dan dengan demikian jika tingkat perubahan itu lebih cepat daripada memperbarui indeks melalui proses latar belakang, maka menggunakan indeks itu "tidak efisien" (indeks melakukan lebih banyak pekerjaan daripada yang dibutuhkan oleh aplikasi, yang mungkin sering mendapatkan jawaban yang salah) .

Pendekatan yang lebih efisien , dalam hal akurasi kueri , mungkin untuk mempertahankan tabel kedua , bukan indeks sekunder. Tabel, sebagai lawan dari indeks , diperlakukan sama seperti tabel lainnya. Mereka lebih cenderung memberi aplikasi Anda hasil permintaan yang diharapkannya . Kelemahannya adalah bahwa mempertahankan tabel sebagai indeks , versus "indeks sekunder" Cassandra, sekarang menjadi kendala aplikasi ( yaitu kode aplikasi Anda sekarang harus tahu untuk menyisipkan / menghapus baris dari tabel "indeks" itu, dan untuk menjaga kedua tabel tetap sinkron melalui "rekonsiliasi" tingkat aplikasi.

Semoga ini membantu!

Castaglia
sumber
Indeks yang dibangun menggunakan proses latar belakang agak ... jelek. Positif palsu terlihat oleh pengguna, saya kira? (Saya tidak melihat bagaimana hal itu tidak terjadi.) Satu-satunya bagian yang masih saya tanyakan adalah di mana Anda mengatakan, "Ini berarti bahwa dalam kolom kardinalitas tinggi, tingkat perubahan (yaitu penambahan / penghapusan) dari kolom itu dapat cukup tinggi. " - Saya mengerti mengapa tingkat perubahan, sehubungan dengan membangun indeks bg, akan buruk, tapi saya masih tidak melihat apa yang berhubungan dengan kardinalitas tinggi dengannya. (Tentunya, bahkan kolom kardinalitas rendah akan mengalami nasib yang sama, bukan?)
Thanatos
Ya, kolom kardinalitas rendah akan mengalami nasib yang sama. Pemikiranku agak kabur di sana, aku akui. Saya berasumsi bahwa indeks kardinalitas tinggi akan lebih cenderung memiliki tingkat perubahan yang lebih tinggi (sehingga lebih mungkin untuk menunjukkan hasil positif / negatif palsu); itu tingkat perubahan (relatif terhadap proses pengindeksan latar belakang) yang paling relevan, bukan kardinalitas.
Castaglia
2

Beberapa terminologi: Tabel induk adalah tabel di mana indeks dibuat. Tabel indeks sekunder adalah tabel yang dibuat untuk mempertahankan indeks di tabel lain.

Data tabel indeks sekunder disimpan pada simpul yang sama dengan data tabel induk. Cassandra partisi tidak memartisi dan mendistribusikan data tabel indeks. Jadi jika Anda ingin melakukan pencarian pada kolom indeks, semua node dipertanyakan, bukan hanya replika yang berisi data. (simpul koordinator tidak tahu di mana data berada) https://www.datastax.com/dev/blog/cassandra-native-secondary-index-deep-dive

Untuk kolom kardinalitas tinggi seperti ssn atau id unik lainnya, akan ada pemetaan satu-ke-satu dengan kunci utama. Jika Anda membuat indeks pada kolom tersebut, data berada pada jumlah node faktor replikasi, tetapi panggilan pencarian dieksekusi pada semua node. Dalam kasus terbaik, koordinator langsung mengenai titik-titik yang berisi data dan Setelah tingkat konsistensi terpenuhi, Anda mendapatkan hasilnya. Terburuk, jika data yang Anda cari, tidak ada dalam indeks, Anda menunggu sampai semua node merespons untuk menemukan bahwa data tidak ada di sana. Jadi untuk setiap panggilan pencarian pada tabel indeks sekunder, semua node terkena. Bandingkan dengan hanya jumlah faktor replikasi node yang terkena untuk setiap panggilan pencarian, jika tabel adalah tabel C * normal.

Pramod Sivaraju
sumber