LindormTable mendukung secondary indexes dalam model Tabular. Fitur ini mengurangi kompleksitas pengembangan aplikasi, menjamin konsistensi data, dan meningkatkan efisiensi penulisan saat kueri tidak menentukan kolom kunci primer dalam kondisinya. Topik ini menjelaskan fitur inti secondary indexes dalam model Tabular Lindorm serta menyediakan contoh penggunaannya.
Informasi latar belakang
Dalam model Tabular Lindorm, tabel lebar Lindorm memiliki skema tabel yang telah ditentukan sebelumnya dengan tipe data kolom tetap. Fitur secondary index native Lindorm telah diterapkan di Alibaba Cloud selama bertahun-tahun dan kinerjanya telah divalidasi berulang kali selama Festival Belanja Double 11. Fitur ini ideal untuk pengindeksan global pada set data berskala besar.
Perbandingan waktu respons (RT) baca dan tulis
Produk
Single-row write RT
RT baca satu baris
RT tulis batch 100 baris
Lindorm
1.409
0.492
10.447
Open source Phoenix
2.264
2.594
26.224
Hasil menunjukkan bahwa Lindorm mencapai RT lebih rendah dibandingkan open source Phoenix dalam skenario pengindeksan. RT untuk tulis satu baris kira-kira 62% dari RT open source Phoenix. RT untuk baca satu baris kira-kira 19% dari RT open source Phoenix. RT untuk tulis batch 100 baris kira-kira 40% dari RT 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 melebihi open source Phoenix sekitar 3,5 kali untuk operasi BatchPut, 2,2 kali untuk operasi Put, 6 kali untuk operasi Get, dan 5,7 kali untuk operasi Scan.
Fitur
Secondary indexes Lindorm memungkinkan Anda membuat beberapa indeks untuk satu tabel. Setiap indeks dipetakan ke tabel data fisik independen yang terpisah dari tabel utama. Indeks dapat memiliki properti berbeda, seperti kebijakan penyimpanan yang menggunakan algoritma kompresi berbeda atau strategi pemisahan data panas dan dingin. Saat Anda menulis data ke tabel utama, Lindorm secara otomatis memperbarui semua tabel indeks terkait dan menjaga konsistensi data di antara mereka. Saat Anda melakukan kueri data, Anda hanya perlu mengkueri tabel utama. Lindorm secara otomatis memilih indeks paling sesuai—termasuk tabel utama—berdasarkan klausa WHERE dan skema. Anda juga dapat menggunakan petunjuk (hint) untuk memengaruhi pilihan pengoptimal. Fitur utama meliputi hal-hal berikut.
Mendukung pembuatan beberapa indeks untuk satu tabel utama.
Mendukung indeks gabungan yang dibangun di atas satu atau beberapa kolom.
Mendukung indeks cakupan. Indeks cakupan penuh secara otomatis menyertakan kolom baru yang ditambahkan ke tabel utama.
Pengoptimalan kueri: Secara otomatis memilih indeks berdasarkan klausa WHERE. Mendukung petunjuk untuk memengaruhi pilihan pengoptimal.
Online Schema Change: Modifikasi indeks tidak memengaruhi operasi baca atau tulis normal pada tabel utama. Anda dapat menambah, menghapus, atau memperbarui indeks kapan saja.
Mendukung Time to Live (TTL): Tabel indeks mewarisi pengaturan TTL dari tabel utama. Data di tabel utama dan tabel indeks kedaluwarsa secara bersamaan.
Kolom dinamis: Mendukung penulisan ke kolom dinamis dan kolom dinamis redundan.
Mendukung versi data kustom: Menulis data dengan timestamp yang ditentukan pengguna.
Persyaratan
Server: Instans Lindorm.
Klien: Untuk informasi selengkapnya, lihat Menggunakan Mesin LindormTable dengan SQL Tabel Lebar Lindorm.
Klien Lindorm-cli: Untuk informasi selengkapnya, lihat Terhubung ke dan gunakan LindormTable dengan Lindorm-cli.
Istilah
Konsistensi kuat: Mengacu pada konsistensi data antara tabel utama dan tabel indeksnya. Untuk memenuhi persyaratan konsistensi data sekaligus meminimalkan overhead secondary index dan memaksimalkan throughput tulis, secondary indexes Lindorm memberlakukan batasan berikut terhadap konsistensi kuat.
Isolasi snapshot tidak didukung. Saat data sedang ditulis, data tersebut mungkin belum tersedia untuk kueri. Setelah sistem mengembalikan respons sukses ke klien, data menjadi terlihat baik di tabel utama maupun tabel indeks.
Jika terjadi timeout klien atau error I/O, data mungkin tidak muncul di tabel utama atau tabel indeks. Namun, konsistensi akhir antara tabel utama dan tabel indeks dijamin.
Opsi mutabilitas: Jika tabel utama memiliki satu indeks, operasi tulis melibatkan empat langkah: membaca tabel utama, menghapus data lama dari indeks, menulis ke indeks, dan menulis ke tabel utama. Proses ini secara signifikan meningkatkan biaya pemeliharaan indeks. Namun, amplifikasi tulis tidak terjadi dalam semua skenario. Misalnya, dalam skenario logging, data hanya dimasukkan dan tidak pernah diperbarui. Dalam kasus tersebut, tabel indeks tidak berisi data lama, sehingga sistem hanya menulis ke indeks dan tabel utama. Untuk mengatasi hal ini, Lindorm memperkenalkan mutabilitas. Mutabilitas mengklasifikasikan pola penulisan tabel utama dan mengorganisasi data indeks sesuai untuk meminimalkan biaya pengorganisasian indeks pada berbagai kasus penggunaan. Tabel berikut menjelaskan klasifikasi mutabilitas. Atur properti mutabilitas menggunakan parameter Table_Options saat Anda membuat atau memodifikasi tabel. Untuk informasi selengkapnya, lihat Sintaks CREATE TABLE.
Klasifikasi mutabilitas
Batasan
Biaya operasi
Deskripsi operasi
Tidak ada indeks
Tidak ada.
1
Jika tidak ada indeks, sistem menulis langsung ke tabel utama. Ini adalah operasi tunggal.
IMMUTABLEMenulis data per baris. Data tidak dapat diperbarui atau dihapus.
2
Menulis ke tabel utama dan tabel indeks. Ini memiliki biaya terendah dan kinerja terbaik di antara semua skenario.
PentingPastikan tidak ada data yang diperbarui atau dihapus. Tipe ini tidak disarankan.
IMMUTABLE_ROWSMenulis dan menghapus data 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. Kinerjanya hanya kalah dari IMMUTABLE.
PentingPastikan tidak ada data yang diperbarui. Tipe ini tidak disarankan.
MUTABLE_LATEST(Direkomendasikan)Data dapat diperbarui dan dihapus. Anda tidak dapat menulis data menggunakan timestamp kustom.
4
Membaca dari tabel utama, menghapus dari indeks, menulis ke indeks, dan menulis ke tabel utama.
PentingUntuk instans dengan LindormTable 2.7.9 atau yang lebih baru, ini adalah properti default. Jika versi instans Anda lebih lama dari 2.7.9, atur properti ke
MUTABLE_LATEST.MUTABLE_ALLTidak ada batasan. Anda dapat menulis data menggunakan timestamp kustom.
4
Membaca dari tabel utama, menghapus dari indeks, menulis ke indeks, dan menulis ke tabel utama.
MUTABLE_UDTTidak ada batasan. Anda dapat menulis data menggunakan timestamp kustom.
4
Membaca dari tabel utama, menghapus dari indeks, menulis ke indeks, dan menulis ke tabel utama.
CatatanProperti ini merupakan versi yang dioptimalkan dari MUTABLE_ALL dan memberikan kinerja lebih baik. Memerlukan LindormTable 2.6.7 atau yang lebih baru.
Pengaturan yang direkomendasikan adalah
MUTABLE_LATEST. Ini memberikan kinerja lebih baik tetapi tidak mendukung penulisan data dengan timestamp tertentu. Untuk instans yang menjalankan LindormTable 2.7.9 atau yang lebih baru,MUTABLE_LATESTadalah properti default. Jika instans Anda menggunakan versi LindormTable yang lebih lama dari 2.7.9, atur properti keMUTABLE_LATEST.Untuk menulis data dengan timestamp kustom, ubah properti ke
MUTABLE_UDT. Ini memerlukan LindormTable 2.6.7 atau yang lebih baru. Untuk catatan penggunaan, lihat poin empat dan lima dalam catatan berikut.CatatanTipe
IMMUTABLEdanIMMUTABLE_ROWStidak melibatkan pembaruan data, sehingga tidak terjadi amplifikasi tulis dan biayanya paling rendah. Tipe ini cocok untuk skenario tulis throughput tinggi, seperti logging dan pemantauan. Jika Anda mengatur properti keIMMUTABLEatauIMMUTABLE_ROWStetapi tetap melakukan pembaruan data, sisi server tidak akan melaporkan error, tetapi hal ini dapat menyebabkan konsistensi data antara tabel data utama dan tabel indeks menjadi tidak sinkron.Tipe
IMMUTABLEtidak melibatkan penghapusan, sehingga Anda dapat sepenuhnya memanfaatkan penerapan multi-IDC Lindorm untuk mencapai akses data aktif-aktif.Memilih properti
IMMUTABLEsecara efektif mengurangi latensi tulis dan meningkatkan throughput keseluruhan dalam skenario pengindeksan. Dalam praktiknya, jika workload Anda tidak sesuai dengan skenarioIMMUTABLE, Anda dapat menggunakan redundansi data untuk menyesuaikannya ke skenarioIMMUTABLE.Properti mutabilitas berlaku saat tabel indeks dibuat. Untuk LindormTable 2.7.9 atau yang lebih baru, nilai default-nya adalah
MUTABLE_LATEST. Properti ini tidak mendukung penulisan data dengan timestamp tertentu. Oleh karena itu, rencanakan properti ini terlebih dahulu berdasarkan kebutuhan Anda untuk menulis data menggunakan timestamp kustom.Jika Anda menggunakan timestamp kustom untuk menulis data tetapi tidak mengatur properti mutabilitas ke
MUTABLE_UDTatauMUTABLE_ALLsebelum membuat indeks, layanan akan langsung terpengaruh dan terjadi error setelah indeks dibuat. Untuk solusinya, lihat FAQ.
Memperbarui indeks dengan timestamp kustom: Lindorm mendukung penulisan data dengan timestamp kustom. Anda dapat memperbarui data pada timestamp apa pun, dan sistem hanya menerapkan data dengan timestamp terbesar. Fitur ini sangat penting untuk mengontrol TTL data dan menangani skenario out-of-order atau idempoten. Fitur ini banyak digunakan di HBase. Lindorm mendukung timestamp tingkat kolom, dan tabel utama mendukung penulisan data dengan timestamp kustom. Namun, di antara sistem NoSQL yang mendukung secondary indexes dan timestamp, hanya sedikit yang mendukung pembaruan indeks dengan timestamp kustom. Hal ini karena penulisan timestamp out-of-order menyulitkan pemeliharaan pembaruan dan penghapusan data indeks secara andal. Secondary indexes global Lindorm menyelesaikan masalah ini dan mendukung pembaruan timestamp kustom tingkat kolom. Berikut adalah dua skenario bisnis nyata yang menggunakan timestamp kustom.
Impor konkuren dan pembaruan real-time: Dalam skenario yang memerlukan pembaruan real-time dan impor data historis, gunakan waktu saat ini untuk pembaruan real-time dan waktu seperti pukul 23:59:59 hari sebelumnya untuk impor historis. Hal ini memastikan bahwa data yang belum diperbarui pada hari ini dapat diperbarui oleh impor, sementara data yang sudah diperbarui tetap tidak terpengaruh.
Menangkap pesan yang tertunda: Sistem bisnis menggunakan pesan untuk memicu logika pemrosesan. Saat pesan menumpuk, sistem dapat melewati pesan yang tertunda dan langsung memproses pesan saat ini. Kemudian, sistem dapat menangkap kembali tugas-tugas yang tertunda sebelumnya. Atau, jika bug memengaruhi logika bisnis, sistem dapat melewati pesan bermasalah dan memproses ulang setelah perbaikan. Dalam kasus tersebut, bisnis dapat menggunakan timestamp masing-masing pesan untuk menulis data. Hal ini memastikan perilaku overwrite yang benar antara pesan yang ditangkap kembali dan pesan normal.
Indeks cakupan penuh: Untuk menghindari pencarian ke tabel utama setelah mengkueri indeks, Anda biasanya menyertakan beberapa kolom tabel utama dalam tabel indeks. Ini dikenal sebagai indeks cakupan. Indeks cakupan penuh adalah strategi redundansi umum. Lindorm mendukung tiga mode redundansi, memungkinkan implementasi mudah indeks cakupan penuh—bahkan ketika skema tabel utama berubah atau mencakup kolom dinamis.
Kolom untuk redundansi: Pilih kolom dari (tabel utama) yang akan direplikasi.
Sertakan semua kolom dalam skema tabel utama: Saat Anda memerlukan indeks cakupan penuh, Anda tidak perlu secara eksplisit mencantumkan setiap kolom tabel utama dalam pernyataan CREATE INDEX. Sebagai gantinya, gunakan konstanta untuk menunjukkan penyertaan semua kolom. Saat kolom baru ditambahkan ke tabel utama, tabel indeks cakupan penuh secara otomatis menyertakannya tanpa memerlukan pengindeksan ulang. Anda juga tidak perlu khawatir tentang pencarian ke tabel utama saat mengkueri kolom baru tersebut.
Sertakan kolom dinamis: Lindorm mendukung skema tetap dan skema longgar (kolom dinamis). Dengan mode redundansi DYNAMIC, tabel indeks secara otomatis menyertakan semua kolom dinamis dari tabel utama, bersama dengan semua kolom yang didefinisikan dalam skema tabel utama.
Buat secondary index (CREATE INDEX)
Setelah membuat tabel utama Lindorm, Anda dapat membuat secondary index pada kolom-kolomnya. Contoh berikut menunjukkan cara membuat secondary index.
-- 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 secondary index pada kolom c3 dan sertakan semua kolom
CREATE INDEX idx1 ON test(c3 desc) WITH (INDEX_COVERED_TYPE ='COVERED_ALL_COLUMNS_IN_SCHEMA');
-- Kueri berdasarkan tabel indeks. Karena indeks dibangun pada c3, menentukan c3 dalam kueri akan mengenai tabel indeks.
SELECT * FROM test WHERE c3 = 'data'; Anda dapat membuat indeks secara sinkron atau asinkron. Gunakan metode sinkron jika tabel utama tidak berisi banyak data historis. Jika tidak, gunakan metode asinkron. Untuk informasi selengkapnya tentang sintaks, lihat CREATE INDEX.
Saat Anda menambahkan indeks baru ke tabel yang sudah berisi data, perintah CREATE INDEX menyinkronkan data historis dari tabel utama ke tabel indeks. Jika tabel utama berukuran besar, perintah CREATE INDEX memerlukan waktu lama untuk dieksekusi. Tugas sinkronisasi data berjalan di sisi server. Menghentikan proses Lindorm Shell tidak memengaruhi tugas sinkronisasi data.
Pembuatan indeks memerlukan pencarian data, yang menghasilkan operasi baca. Jika fitur pemisahan data panas dan dingin diaktifkan untuk instans Anda, pantau pembatasan laju penyimpanan dingin (penyimpanan cloud yang dioptimalkan). Pembatasan laju pada operasi baca penyimpanan dingin secara langsung memengaruhi efisiensi pembuatan indeks dan dapat menyebabkan tekanan balik pada operasi tulis.
Lihat secondary indexes (SHOW INDEX)
Anda dapat menggunakan SQL Lindorm untuk melihat status secondary index yang telah dibuat. Contoh berikut menunjukkan cara melihat secondary index.
SHOW INDEX FROM test;Contoh ini menampilkan nama indeks dan tipe indeks yang dibuat di bawah tabel utama test.
Ubah status secondary index (ALTER INDEX)
Setelah membuat secondary index, jika tabel utama berisi data historis, Anda harus menjalankan operasi Rebuild secara manual pada indeks tersebut. 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 secara langsung. Contoh berikut menunjukkan cara mengubah status secondary index:
ALTER INDEX IF EXISTS idx1 ON test ACTIVE;
ALTER INDEX idx1 ON test DISABLED;Saat status secondary index adalah DISABLED, mengubahnya langsung ke ACTIVE menyebabkan kehilangan data. Oleh karena itu, jalankan operasi Rebuild sebelum mengubah status.
Hapus secondary index (DROP INDEX)
Gunakan contoh berikut untuk menghapus secondary index dari tabel utama yang sesuai.
DROP INDEX IF EXISTS idx1 ON test;Anda memerlukan izin Trash untuk menghapus indeks.
Pengoptimalan kueri
Lindorm memilih secondary index menggunakan Rule Based Optimization (RBO). Sistem mencocokkan awalan tabel indeks dengan kondisi kueri dan memilih tabel indeks dengan tingkat kecocokan tertinggi. Contoh berikut membantu menjelaskan proses ini.
-- 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. Sistem mengambil semua baris yang sesuai denganc2=blalu menyaringnya baris demi baris denganc4=d. Meskipun c4 adalah kolom indeks, awalanidx2tidak dapat dicocokkan karena kolomc3tidak ada dalam kondisiWHERE.Pernyataan
SELECT * FROM dt WHERE c2 = 'b' AND c3 >= 'c' AND c3 < 'f';memilih tabel indeks idx2. Karena ini adalah kueri SELECT * dan tabel indeks tidak berisi semua kolom tabel utama, sistem harus melakukan pencarian ke tabel utama setelah mengkueri indeks. Selama pencarian tersebut, Rowkey mungkin tersebar di seluruh tabel utama, berpotensi mengonsumsi beberapa RPC. Set hasil yang lebih besar meningkatkan RT.Pernyataan
SELECT * FROM dt WHERE c5 = 'c';memilih tabel indeksidx4.idx4adalah indeks cakupan penuh, sehinggaSELECT *tidak memerlukan pencarian ke 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, setiap indeks yang dibuat untuk tabel utama yang sama harus memiliki nama unik.
Anda hanya dapat membuat indeks untuk tabel yang menyimpan satu versi data. Tabel multi-versi tidak mendukung indeks.
Secondary indexes tidak mendukung TTL tingkat sel.
Jika Anda membuat indeks untuk tabel utama dengan TTL tingkat tabel, Anda tidak dapat mengatur TTL terpisah untuk tabel indeks. Tabel indeks secara otomatis mewarisi TTL dari tabel utama.
Untuk LindormTable 2.8.6 atau yang lebih baru, indeks dapat berisi hingga delapan kolom indeks. Untuk versi sebelumnya, indeks dapat berisi hingga tiga kolom indeks.
Panjang gabungan kolom indeks dan kunci primer tabel utama tidak boleh melebihi 30 KB. Hindari menggunakan kolom yang lebih besar dari 100 byte sebagai kolom indeks.
Untuk LindormTable 2.8.6 atau yang lebih baru, Anda dapat membuat hingga 10 indeks untuk satu tabel utama. Untuk versi sebelumnya, Anda dapat membuat hingga lima indeks. Terlalu banyak indeks meningkatkan biaya penyimpanan dan memperpanjang waktu tulis.
Satu kueri hanya dapat menggunakan satu indeks. Kueri penggabungan indeks tidak didukung.
Saat Anda membuat indeks, data dari tabel utama disinkronkan ke indeks. Membuat indeks untuk tabel dengan volume data besar dapat menyebabkan perintah CREATE INDEX berjalan lama.
Secondary indexes tidak mendukung fitur peningkatan batch.
Urutan pengurutan secondary index yang digunakan dalam kueri berbeda dari urutan pengurutan tabel utama.
Anda hanya dapat membangun secondary indexes untuk data yang ditulis menggunakan SQL atau API. Anda tidak dapat membangun secondary indexes 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 menulis data dengan timestamp kustom tetapi tidak mengatur properti mutabilitas ke MUTABLE_UDT (direkomendasikan) atau MUTABLE_ALL sebelum membuat indeks.
Hapus indeks tabel utama, ubah properti mutabilitas ke MUTABLE_UDT, lalu buat indeks baru.
Jika bisnis Anda memiliki permintaan baca yang mengenai indeks ini, hapus dengan hati-hati.
Untuk masalah lain terkait indeks, bergabunglah dengan grup Lindorm di DingTalk atau kirimkan tiket. Untuk informasi selengkapnya, lihat Dukungan teknis.