LindormTable mendukung indeks sekunder dalam model Tabular. Fitur ini mengurangi kompleksitas pengembangan aplikasi, memastikan konsistensi data, dan meningkatkan efisiensi penulisan untuk kueri yang tidak menentukan kolom kunci primer dalam kondisinya. Topik ini menjelaskan fitur dasar dan contoh penggunaan indeks sekunder dalam model Tabular Lindorm.
Informasi Latar Belakang
Dalam model Tabular Lindorm, tabel lebar memiliki skema tabel dan tipe kolom yang telah ditentukan sebelumnya. Fitur indeks sekunder native Lindorm telah digunakan di Alibaba Cloud selama bertahun-tahun dan terbukti efektif selama beberapa festival belanja Double 11. Fitur ini ideal untuk pengindeksan global volume data yang besar.
Perbandingan waktu respons (RT) baca dan tulis
Produk
RT untuk penulisan satu baris
RT untuk pembacaan satu baris
RT untuk penulisan batch 100 baris
Lindorm
1.409
0.492
10.447
Open source Phoenix
2.264
2.594
26.224
Hasil menunjukkan bahwa Lindorm memiliki latensi lebih rendah untuk operasi baca dan tulis dalam skenario pengindeksan. RT untuk penulisan satu baris sekitar 62% dari open source Phoenix. RT untuk pembacaan satu baris sekitar 19% dari open source Phoenix. RT untuk penulisan batch 100 baris sekitar 40% dari open source Phoenix.
Perbandingan throughput tulis
Produk
BatchPut
Put
Get
Scan
Lindorm
198174
73214
156372
1283451
Open source Phoenix
56923
33156
25910
224085
Hasil menunjukkan bahwa dalam skenario pengindeksan, throughput Lindorm sekitar 3,5 kali lipat dari open source Phoenix untuk operasi BatchPut, 2,2 kali untuk operasi Put, 6 kali untuk operasi Get, dan 5,7 kali untuk operasi Scan.
Fitur
Indeks sekunder Lindorm memungkinkan Anda membuat beberapa indeks untuk satu tabel. Setiap indeks dipetakan secara fisik ke tabel data yang independen dari tabel utama. Setiap indeks dapat memiliki kebijakan penyimpanan yang berbeda, seperti algoritma kompresi berbeda atau kebijakan pemisahan data panas dan dingin. Saat Anda menulis ke tabel utama, Lindorm secara otomatis memperbarui semua tabel indeks dan memastikan konsistensi data antara tabel utama dan tabel indeks. Saat membaca data, Anda hanya perlu melakukan kueri pada tabel utama. Lindorm secara otomatis memilih indeks yang sesuai—yang bisa jadi tabel utama itu sendiri—berdasarkan kondisi WHERE dan skema. Petunjuk (hint) didukung untuk memengaruhi perilaku pengoptimal. Fitur dasar indeks sekunder Lindorm adalah sebagai berikut.
Dukungan untuk beberapa indeks pada satu tabel utama.
Dukungan untuk indeks gabungan yang menggunakan satu atau beberapa kolom.
Indeks redundan didukung. Indeks redundan penuh secara otomatis mereplikasi kolom baru dari tabel utama.
Pengoptimalan kueri: Secara otomatis memilih indeks berdasarkan klausa WHERE. Mendukung hint untuk memengaruhi pilihan pengoptimal.
Online Schema Change: Perubahan indeks tidak memengaruhi operasi baca dan tulis normal pada tabel utama. Anda dapat menambah, menghapus, atau memperbarui indeks kapan saja.
Dukungan untuk Time to Live (TTL): Tabel indeks secara otomatis mewarisi pengaturan TTL dari tabel utama. Data di tabel utama dan tabel indeks kedaluwarsa secara bersamaan.
Dukungan untuk kolom dinamis: Anda dapat menulis dan menyertakan kolom dinamis dalam indeks.
Dukungan untuk versi data kustom: Data secara otomatis ditulis dengan timestamp kustom yang ditentukan.
Prasyarat
Server: Instans Lindorm.
Klien: Untuk informasi selengkapnya, lihat Gunakan LindormTable dengan Lindorm SQL.
Lindorm-cli: Untuk informasi selengkapnya, lihat Hubungkan ke dan gunakan LindormTable dengan Lindorm-cli.
Istilah
Konsistensi kuat: Ini mengacu pada konsistensi data antara tabel utama dan tabel indeksnya. Untuk memenuhi persyaratan konsistensi data, meminimalkan overhead indeks sekunder, dan meningkatkan throughput tulis, indeks sekunder Lindorm memiliki batasan berikut untuk konsistensi kuat.
Isolasi snapshot tidak didukung. Selama penulisan data, visibilitas tidak dijamin. Namun, setelah klien menerima respons sukses, data terlihat baik di tabel utama maupun tabel indeks.
Jika terjadi timeout klien atau error I/O, visibilitas data di tabel utama dan tabel indeks tidak dijamin. Namun, data di kedua tabel tersebut pada akhirnya akan konsisten.
Opsi mutabilitas: Jika tabel utama memiliki satu indeks, operasi tulis melibatkan empat langkah: membaca data dari tabel utama, menghapus data lama dari indeks, menulis data ke indeks, dan menulis data ke tabel utama. Proses ini secara signifikan meningkatkan biaya pemeliharaan indeks. Namun, amplifikasi tulis tidak terjadi di semua skenario. Misalnya, dalam skenario logging, data hanya dimasukkan dan tidak diperbarui. Dalam kasus ini, tidak ada data lama di tabel indeks, sehingga sistem hanya perlu menulis ke indeks dan tabel utama. Untuk alasan ini, Lindorm memperkenalkan konsep mutabilitas. Mutabilitas mengklasifikasikan pola penulisan untuk tabel utama dan mengorganisasi data indeks sesuai dengan itu. Hal ini meminimalkan biaya pengorganisasian indeks untuk berbagai kebutuhan. Tabel berikut menjelaskan tipe mutabilitas. Anda harus mengatur atribut Mutability menggunakan parameter Table_Options saat membuat atau memodifikasi tabel. Untuk informasi selengkapnya, lihat Sintaks CREATE TABLE.
Klasifikasi mutabilitas
Batasan
Biaya
Deskripsi
Tidak ada indeks
Tidak ada.
1
Jika tidak ada indeks, sistem menulis langsung ke tabel utama. Ini adalah operasi tunggal.
IMMUTABLEData ditulis per baris. Data tidak dapat diperbarui atau dihapus.
2
Menulis ke tabel utama dan tabel indeks. Tipe ini memiliki biaya terendah dan performa terbaik di semua skenario.
PentingAnda harus memastikan bahwa tidak ada data yang diperbarui atau dihapus. Tipe ini tidak disarankan.
IMMUTABLE_ROWSData ditulis dan dihapus per baris. Data tidak dapat diperbarui.
2 hingga 3
Untuk penulisan normal: menulis ke tabel utama dan tabel indeks. Dalam skenario penghapusan, diperlukan pembacaan tambahan dari tabel utama. Performanya berada tepat di bawah IMMUTABLE.
PentingAnda harus memastikan bahwa tidak ada data yang diperbarui. Tipe ini tidak disarankan.
MUTABLE_LATEST(Direkomendasikan)Data dapat diperbarui dan dihapus. Anda tidak dapat menulis data dengan timestamp kustom.
4
Membaca dari tabel utama, menghapus dari indeks, menulis ke indeks, dan menulis ke tabel utama.
PentingUntuk instans dengan versi mesin database 2.7.9 atau lebih baru, atribut ini adalah atribut default. Jika versinya lebih lama dari 2.7.9, kami menyarankan Anda mengatur atribut ini secara manual ke
MUTABLE_LATEST.MUTABLE_ALLTidak ada batasan. Anda dapat menggunakan timestamp kustom untuk menulis data.
4
Membaca dari tabel utama, menghapus dari indeks, menulis ke indeks, dan menulis ke tabel utama.
MUTABLE_UDTTidak ada batasan. Anda dapat menggunakan timestamp kustom untuk menulis data.
4
Membaca dari tabel utama, menghapus dari indeks, menulis ke indeks, dan menulis ke tabel utama.
CatatanAtribut ini merupakan versi teroptimalkan dari MUTABLE_ALL dan memberikan performa lebih baik. Versi mesin database harus 2.6.7 atau lebih baru.
Atribut yang direkomendasikan adalah
MUTABLE_LATEST. Atribut ini memberikan performa lebih baik tetapi tidak mengizinkan penulisan data dengan timestamp tertentu. Untuk instans dengan versi mesin database 2.7.9 atau lebih baru,MUTABLE_LATESTadalah atribut default. Jika instans Anda menggunakan versi mesin database lebih lama dari 2.7.9, Anda harus mengatur atribut ini secara manual keMUTABLE_LATEST.Untuk menulis data dengan timestamp kustom, kami menyarankan Anda mengubah atribut menjadi
MUTABLE_UDT. Ini memerlukan versi mesin database 2.6.7 atau lebih baru. Untuk catatan penggunaan, lihat poin 4 dan 5 dalam catatan berikut.CatatanTipe
IMMUTABLEdanIMMUTABLE_ROWStidak melibatkan pembaruan data. Artinya tidak terjadi amplifikasi tulis, dan biaya diminimalkan. Tipe ini cocok untuk skenario penulisan throughput tinggi, seperti logging dan pemantauan. Jika Anda mengatur tipe keIMMUTABLEatauIMMUTABLE_ROWStetapi tetap melakukan pembaruan data, server tidak melaporkan error. Namun, hal ini dapat menyebabkan konsistensi data antara tabel utama dan tabel indeks menjadi tidak sinkron.Tipe
IMMUTABLEtidak melibatkan penghapusan. Hal ini memungkinkan Anda memanfaatkan sepenuhnya penerapan multi-IDC Lindorm untuk mencapai akses data aktif-aktif.Memilih salah satu dari dua tipe
IMMUTABLEdapat secara efektif mengurangi latensi tulis dan meningkatkan throughput keseluruhan dalam skenario pengindeksan. Jika skenario bisnis Anda tidak memenuhi persyaratanIMMUTABLE, Anda dapat menggunakan redundansi data untuk menyesuaikannya ke skenarioIMMUTABLE.Atribut Mutability berlaku saat Anda membuat tabel indeks. Untuk versi mesin database 2.7.9 dan lebih baru, nilai default-nya adalah
MUTABLE_LATEST. Atribut ini tidak mendukung penulisan data dengan timestamp tertentu. Oleh karena itu, rencanakan atribut ini sejak awal berdasarkan kebutuhan Anda untuk menulis data dengan timestamp kustom.Jika Anda menggunakan timestamp kustom untuk menulis data tetapi tidak mengatur atribut Mutability ke
MUTABLE_UDTatauMUTABLE_ALLsebelum membuat indeks, layanan akan langsung terpengaruh dan error dilaporkan setelah indeks dibuat. Untuk solusi, lihat FAQ.
Perbarui indeks dengan timestamp kustom: Lindorm mendukung penulisan data dengan timestamp kustom. Anda dapat memperbarui data pada timestamp apa pun, dan sistem memastikan hanya data dengan timestamp terbaru yang berlaku. Fitur timestamp kustom penting untuk mengontrol TTL data dan menangani skenario out-of-order serta idempoten. Fitur ini banyak digunakan di HBase. Lindorm mendukung timestamp tingkat kolom dan memungkinkan penulisan data ke tabel utama dengan timestamp kustom. Namun, dalam sistem NoSQL yang mendukung indeks sekunder dan timestamp, dukungan untuk memperbarui indeks dengan timestamp kustom jarang ditemukan. Hal ini karena penulisan out-of-order menyulitkan pemeliharaan pembaruan dan penghapusan indeks secara efektif. Indeks sekunder global Lindorm mengatasi masalah ini dengan mendukung pembaruan tingkat kolom menggunakan timestamp kustom. Berikut adalah dua skenario bisnis yang menggunakan timestamp kustom.
Impor konkuren dan operasi real-time: Dalam skenario yang memerlukan pembaruan real-time dan impor data historis, Anda dapat menggunakan waktu saat ini untuk pembaruan real-time dan waktu seperti 23:59:59 hari sebelumnya untuk impor data historis. Dengan cara ini, data yang tidak diperbarui pada hari tersebut dapat diperbarui oleh operasi impor, sedangkan data yang sudah diperbarui tidak akan ditimpa oleh impor.
Proses pesan yang tertunda: Sistem bisnis menggunakan pesan untuk memicu serangkaian logika pemrosesan. Saat terjadi penumpukan pesan, sistem dapat melewati pesan yang tertunda dan langsung memproses pesan saat ini. Kemudian, sistem dapat memproses tugas yang tertunda tersebut di kemudian hari. Atau, jika terdapat masalah pada logika bisnis, sistem dapat melewati beberapa pesan untuk menghindari masalah tersebut dan memproses ulang setelah logika bisnis diperbaiki. Dalam kasus ini, bisnis dapat menggunakan timestamp pesan itu sendiri untuk menulis data. Hal ini memastikan hubungan overwrite yang benar antara pesan yang tertunda dan pesan normal.
Indeks cakupan penuh: Untuk menghindari pemindaian tabel utama setelah pemindaian indeks, Anda biasanya menyertakan beberapa kolom tabel utama dalam tabel indeks. Ini dikenal sebagai indeks cakupan. Indeks cakupan penuh adalah solusi redundansi umum. Lindorm mendukung tiga mode redundansi yang menyederhanakan implementasi indeks cakupan penuh ketika skema tabel utama berubah atau dalam skenario kolom dinamis.
Sertakan kolom tertentu: Secara eksplisit tentukan kolom mana dari tabel utama yang akan disertakan.
Sertakan semua kolom dalam skema tabel utama: Saat Anda memerlukan indeks cakupan penuh, Anda tidak perlu secara eksplisit menambahkan setiap kolom dari tabel utama dalam pernyataan CREATE INDEX. Sebagai gantinya, Anda dapat menggunakan konstanta yang merepresentasikan semua kolom. Saat kolom baru ditambahkan ke tabel utama, tabel indeks cakupan penuh secara otomatis menyertakan kolom baru ini. Anda tidak perlu melakukan pengindeksan ulang. Anda juga tidak perlu khawatir bahwa kueri pada kolom baru akan menyebabkan pemindaian tabel utama.
Sertakan kolom dinamis: Lindorm mendukung skema tetap dan skema longgar (kolom dinamis). Dengan mode redundansi DYNAMIC, tabel indeks dapat secara otomatis menyertakan semua kolom dinamis dari tabel utama. Tabel indeks juga akan menyertakan semua kolom dari skema tabel utama.
Buat indeks sekunder (CREATE INDEX)
Setelah membuat tabel utama Lindorm, Anda dapat membuat indeks sekunder untuk kolom-kolom dalam tabel tersebut. Contoh berikut menunjukkan cara membuat indeks sekunder.
-- Buat tabel utama.
CREATE TABLE test (
p1 VARCHAR NOT NULL,
p2 INTEGER NOT NULL,
c1 BIGINT,
c2 DOUBLE,
c3 VARCHAR,
c5 GEOMETRY(POINT),
PRIMARY KEY(p1, p2)
) WITH (CONSISTENCY = 'strong', MUTABILITY='MUTABLE_LATEST');
-- Buat indeks sekunder pada kolom c3 dan sertakan semua kolom.
CREATE INDEX idx1 ON test(c3 desc) WITH (INDEX_COVERED_TYPE ='COVERED_ALL_COLUMNS_IN_SCHEMA');
-- Kueri data dari tabel indeks. Karena indeks dibuat pada kolom c3, kueri akan mengenai tabel indeks saat c3 ditentukan.
SELECT * FROM test WHERE c3 = 'data'; Anda dapat membuat indeks secara sinkron atau asinkron. Jika jumlah data historis kecil, Anda dapat membuat indeks secara sinkron. Jika tidak, buatlah secara asinkron. Untuk informasi selengkapnya tentang sintaks, lihat CREATE INDEX.
Saat Anda menambahkan indeks baru ke tabel yang sudah berisi data, perintah CREATE INDEX juga menyinkronkan data historis dari tabel utama ke tabel indeks. Jika tabel utama berukuran besar, CREATE INDEX dapat memakan waktu sangat lama. Tugas sinkronisasi data dijalankan di server. Menghentikan proses Lindorm Shell tidak memengaruhi tugas sinkronisasi data.
Pembuatan indeks memerlukan pencarian data, yang menghasilkan operasi baca. Jika Anda mengaktifkan fitur pemisahan data panas dan dingin untuk instans Anda, Anda harus memantau pengendalian aliran penyimpanan dingin (penyimpanan cloud teroptimalkan). Jika operasi baca pada penyimpanan dingin dikendalikan alirannya, efisiensi pembuatan indeks akan langsung terpengaruh, yang dapat menyebabkan tekanan balik pada operasi tulis.
Lihat indeks sekunder (SHOW INDEX)
Anda dapat menggunakan Lindorm SQL untuk melihat status indeks sekunder yang telah dibuat. Contoh berikut menunjukkan cara melihat indeks sekunder.
SHOW INDEX FROM test;Contoh ini menampilkan nama indeks dan tipe indeks yang dibuat untuk tabel utama test.
Ubah status indeks sekunder (ALTER INDEX)
Setelah membuat indeks sekunder, jika tabel utama berisi data historis, Anda harus membangun ulang indeks secara manual. Untuk informasi selengkapnya tentang sintaks, lihat BUILD INDEX. Jika tabel utama tidak memiliki data historis, Anda dapat menggunakan sintaks ALTER INDEX untuk mengubah status tabel indeks sekunder. Contoh berikut menunjukkan cara mengubah status indeks sekunder:
ALTER INDEX IF EXISTS idx1 ON test ACTIVE;
ALTER INDEX idx1 ON test DISABLED;Saat status indeks sekunder adalah DISABLED, mengubahnya langsung ke ACTIVE menyebabkan kehilangan data. Oleh karena itu, Anda harus melakukan operasi rebuild sebelum mengubah status.
Hapus indeks sekunder (DROP INDEX)
Contoh berikut menunjukkan cara menghapus indeks sekunder dari tabel utama.
DROP INDEX IF EXISTS idx1 ON test;Anda memerlukan izin Trash untuk menghapus indeks.
Pengoptimalan kueri
Lindorm memilih indeks sekunder berdasarkan kebijakan Rule Based Optimization (RBO). Sistem mencocokkan awalan (prefix) tabel indeks berdasarkan kondisi kueri dan memilih tabel indeks dengan prefix yang paling panjang sebagai indeks untuk kueri tersebut. Contoh berikut membantu Anda memahami proses ini lebih baik.
-- Tabel utama dan tabel indeks adalah sebagai berikut:
CREATE TABLE dt (rowkey varchar, c1 varchar, c2 varchar, c3 varchar, c4 varchar, c5 varchar, PRIMARY KEY(rowkey));
CREATE INDEX idx1 ON dt (c1);
CREATE INDEX idx2 ON dt(c2,c3,c4);
CREATE INDEX idx3 ON dt(c3) INCLUDE(c1,c2,c4);
CREATE INDEX idx4 ON dt(c5 desc) WITH (INDEX_COVERED_TYPE ='COVERED_ALL_COLUMNS_IN_SCHEMA');
-- Pengoptimalan kueri adalah sebagai berikut:
SELECT rowkey FROM dt WHERE c1 = 'a';
SELECT rowkey FROM dt WHERE c2 = 'b' AND c4 = 'd';
SELECT * FROM dt WHERE c2 = 'b' AND c3 >= 'c' AND c3 < 'f';
SELECT * FROM dt WHERE c5 = 'c';Pernyataan
SELECT rowkey FROM dt WHERE c1 = 'a';memilih tabel indeksidx1.Pernyataan
SELECT rowkey FROM dt WHERE c2 = 'b' AND c4 = 'd';memilih tabel indeksidx2, menemukan semua baris yang memenuhi kondisic2=b, lalu menyaring hasilnya baris demi baris berdasarkan kondisic4=d. Meskipun c4 merupakan salah satu kolom indeks, kueri tidak dapat mencocokkan prefixidx2karena klausaWHEREtidak menyertakan kolomc3.Pernyataan
SELECT * FROM dt WHERE c2 = 'b' AND c3 >= 'c' AND c3 < 'f';memilih tabel indeks `idx2`. Karena kueri menggunakan `SELECT *` dan tabel indeks tidak menyertakan semua kolom tabel utama, diperlukan pemindaian tabel utama setelah indeks dikueri. Saat tabel utama dipindai, kunci baris (rowkey) yang dicari mungkin tersebar di seluruh tabel, yang dapat menghasilkan beberapa panggilan prosedur remote (RPC). Semakin besar volume data yang dipindai, semakin lama waktu respons (RT)-nya.Pernyataan
SELECT * FROM dt WHERE c5 = 'c';memilih tabel indeksidx4. Karenaidx4adalah indeks redundan penuh, kueriselect *tidak perlu mengakses tabel utama.
Batasan
Anda dapat membuat indeks dengan nama yang sama untuk tabel utama yang berbeda. Misalnya, Anda dapat membuat indeks bernama Idx1 untuk tabel dt dan tabel foo. Namun, Anda tidak dapat membuat indeks dengan nama yang sama untuk tabel utama yang sama.
Anda hanya dapat membuat indeks untuk tabel yang menyimpan data versi tunggal. Anda tidak dapat membuat indeks untuk tabel multi-versi.
Indeks sekunder tidak mendukung TTL tingkat sel (cell-level TTL).
Jika Anda membuat indeks untuk tabel utama yang memiliki TTL tingkat tabel, Anda tidak dapat mengatur TTL terpisah untuk tabel indeks. Tabel indeks secara otomatis mewarisi TTL dari tabel utama.
Sebuah indeks dapat berisi maksimal tiga kolom indeks.
Panjang total kolom indeks dan kunci primer tabel utama tidak boleh melebihi 30 KB. Kami menyarankan agar Anda tidak menggunakan kolom yang lebih besar dari 100 byte sebagai kolom indeks.
Anda dapat membuat maksimal lima tabel indeks untuk satu tabel utama. Terlalu banyak indeks dapat menyebabkan biaya penyimpanan tinggi dan latensi tulis yang panjang.
Satu kueri hanya dapat mengenai satu indeks. Kueri penggabungan indeks tidak didukung.
Saat membuat indeks, data dari tabel utama disinkronkan ke indeks. Membuat indeks untuk tabel dengan volume data besar dapat menyebabkan perintah CREATE INDEX memakan waktu lama.
Indeks sekunder tidak mendukung fitur increment batch.
Pengurutan indeks sekunder yang dikenai kueri berbeda dari pengurutan tabel utama.
Anda hanya dapat membuat indeks sekunder untuk data yang ditulis menggunakan SQL atau API. Anda tidak dapat membuat indeks sekunder untuk data yang diimpor ke Lindorm menggunakan BulkLoad.
FAQ
Mengapa terjadi error User-Defined-Timestamp(UDT) is not supported by table in MUTABLE_LATEST mode?
Error ini terjadi karena Anda menggunakan timestamp kustom untuk menulis data tetapi tidak mengatur atribut Mutability ke MUTABLE_UDT (direkomendasikan) atau MUTABLE_ALL sebelum membuat indeks.
Kami menyarankan Anda menghapus indeks dari tabel utama, mengubah nilai atribut Mutability ke MUTABLE_UDT, lalu membuat indeks baru.
Berhati-hatilah jika bisnis Anda memiliki permintaan baca yang mencocokkan indeks ini.
Untuk masalah lain terkait indeks, Anda dapat menghubungi dukungan teknis Lindorm melalui DingTalk atau mengajukan tiket. Untuk informasi selengkapnya, lihat Dukungan teknis.