All Products
Search
Document Center

Tablestore:Praktik terbaik desain tabel

Last Updated:Jun 18, 2026

Tablestore secara otomatis membagi data ke dalam beberapa partisi berdasarkan rentang kunci partisi. Pemilihan kunci partisi yang buruk dapat menyebabkan hotspot, kesenjangan data, atau bottleneck penskalaan. Rancang tabel berkinerja tinggi dan dapat diskalakan dengan menerapkan praktik terbaik dalam desain kunci primer, desain kolom atribut, dan pemisahan tabel.

Desain kunci primer

Tablestore secara otomatis membagi data ke dalam beberapa partisi berdasarkan rentang kunci partisi (kolom kunci primer pertama) dan mendistribusikannya ke berbagai node layanan. Rancang kunci primer agar distribusi data dan beban akses merata serta menghindari hotspot.

Prinsip desain kunci partisi

Kunci partisi adalah kolom kunci primer pertama dalam tabel data. Tablestore secara otomatis membagi data ke dalam beberapa partisi berdasarkan rentang kunci partisi dan menjadwalkan setiap partisi ke node layanan yang berbeda. Ikuti prinsip-prinsip berikut saat merancang kunci partisi:

  • Pastikan volume data di bawah satu nilai kunci partisi tidak melebihi 10 GB.

  • Pastikan data di bawah nilai kunci partisi yang berbeda bersifat logis independen.

  • Hindari memusatkan beban akses pada rentang kecil nilai kunci partisi yang berurutan.

Catatan

Jika beban kerja rendah (TPS/QPS di bawah 1.000, volume data dalam 10 GB, dan tidak diperkirakan tumbuh signifikan), dampak hotspot minimal dan satu partisi saja dapat menangani beban tersebut. Namun, jangan merancang arsitektur Anda bergantung pada kapasitas partisi tunggal.

Distribusi data

Dalam sistem data terdistribusi, distribusi data yang tidak merata menyebabkan masalah berikut:

  • Throughput baca/tulis dibatasi oleh satu partisi, menciptakan bottleneck yang jelas.

  • Distribusi hotspot yang tidak merata menyebabkan efek ekor panjang (long-tail effect) yang memperlambat pemrosesan secara keseluruhan.

  • Partisi hotspot menjadi bottleneck bagi seluruh pipeline bisnis dan memengaruhi sistem hulu dan hilir.

Ketika data didistribusikan secara merata ke seluruh partisi, beban baca/tulis tersebar ke semua partisi. Setiap permintaan hanya mencakup data lokal, dan Anda dapat melakukan penskalaan horizontal dengan menambahkan lebih banyak sumber daya.

Masalah hotspot umum dan solusinya

Pertimbangkan skenario pemantauan di mana tabel data menyimpan nilai metrik untuk setiap mesin pada setiap titik waktu, dengan desain kunci primer sebagai berikut:

Timestamp (kunci partisi)

MachineIp

Masalah

1718000001

10.10.0.1

Setiap penulisan ditambahkan ke akhir tabel (partisi terakhir), menciptakan hotspot ekor (tail hotspot).

1718000002

10.10.0.2

1718000003

10.10.0.1

Karena data dipartisi berdasarkan rentang kunci partisi, semua penulisan terkonsentrasi pada partisi terakhir, menciptakan hotspot ekor yang tidak dapat diselesaikan melalui pemisahan partisi.

Pendekatan 1: Ubah urutan kunci partisi

Pindahkan MachineIp ke kolom kunci primer pertama dan Timestamp ke kolom kedua. Kunci primer yang disesuaikan menjadi MachineIp = "10.10.0.1", Timestamp = 1718000001. Beban penulisan kemudian tersebar ke berbagai partisi berdasarkan mesin. Bidang lain yang secara alami terdistribusi seperti UserId, DeviceId, dan OrderId juga berfungsi sama baiknya sebagai kunci partisi.

Catatan

Jika penulisan dari rentang IP tertentu terkonsentrasi pada satu partisi, Tablestore secara otomatis membagi partisi tersebut untuk mendistribusikan beban ke beberapa partisi.

Pendekatan 2: Tambahkan awalan MD5

Hitung hash MD5 dari MachineIp dan tambahkan 4 karakter heksadesimal pertama ke depan IP sebagai kunci partisi. Misalnya, 4 karakter MD5 pertama dari 10.10.0.1 adalah a1b2, sehingga kunci partisi menjadi a1b2,10.10.0.1. Pendekatan ini memecah urutan berurutan dari rentang IP. Awalan heksadesimal juga membantu sistem melakukan pre-splitting.

Pendekatan 3: Alternatif untuk kebutuhan pengurutan global

Jika bisnis Anda memerlukan kueri terurut global berdasarkan waktu tetapi ingin menghindari hotspot ekor, pertimbangkan alternatif berikut:

  • Pengurutan lokal: Tempatkan bidang terdistribusi di kolom pertama. Data dengan nilai bidang terdistribusi yang sama tetap terurut berdasarkan waktu. Misalnya, data di bawah MachineIp tertentu tetap terurut berdasarkan Timestamp.

  • Penulisan berbasis bucket: Gunakan nilai waktu modulo N sebagai kolom kunci primer pertama (0 hingga N-1) dan waktu sebagai kolom kedua. Misalnya, dengan 16 bucket, kunci partisi untuk penulisan adalah timestamp % 16 = 3. Untuk membaca, lakukan kueri ke semua 16 bucket secara paralel dan gabungkan hasilnya. Meningkatkan jumlah bucket mendistribusikan beban lebih merata tetapi meningkatkan jumlah kueri paralel saat membaca.

  • Search index: Tulis data ke tabel data dengan distribusi merata, dan gunakan Search index untuk melakukan kueri terurut berdasarkan waktu atau bidang lainnya. Search index secara otomatis mendistribusikan data ke beberapa shard dan menggabungkan hasil selama kueri.

Batas panjang kolom kunci primer dan volume data

  • Pastikan volume data di bawah satu nilai kunci partisi tidak melebihi 10 GB (tidak ada batas keras). Baris dengan nilai kunci partisi yang sama tidak dapat dibagi lebih lanjut.

  • Batas panjang kolom kunci primer adalah 1 KB. Kunci primer yang lebih pendek meningkatkan kinerja kueri.

Gabungkan kolom menjadi kunci partisi

Jika total volume data untuk semua baris di bawah satu nilai kunci partisi berpotensi melebihi 10 GB, gabungkan beberapa kolom kunci primer menjadi kunci partisi baru untuk mendistribusikan data. Ikuti aturan berikut saat menggabungkan:

  • Kunci partisi hasil penggabungan harus secara efektif membagi catatan yang sebelumnya memiliki nilai kunci partisi yang sama ke nilai kunci partisi yang berbeda.

  • Tambahkan nol di depan kolom kunci primer bertipe integer untuk menjaga konsistensi pengurutan. Misalnya, OrderNumber = 123 menjadi 00000123 setelah padding, sehingga urutan leksikografis tetap konsisten dengan urutan numerik.

  • Pilih karakter pembatas dengan nilai ASCII lebih rendah daripada semua karakter dalam data untuk mempertahankan urutan leksikografis kunci partisi baru. Pilihan spesifik tergantung pada set karakter data bisnis Anda. Misalnya, jika nilai SellerID berisi angka dan huruf (seperti a100 dan a1001), pembatas yang berbeda memengaruhi pengurutan sebagai berikut:

    Pembatas

    Urutan pengurutan setelah penggabungan

    Alasan

    Hasil

    :

    000054:a1001 diurutkan sebelum 000054:a100:

    Nilai ASCII : lebih besar daripada angka. Pada karakter ke-5, a1001 membandingkan 1 < :

    Pengurutan salah

    ,

    000054,a100, diurutkan sebelum 000054,a1001

    Nilai ASCII , lebih rendah daripada semua angka dan huruf, sehingga urutan leksikografis sesuai dengan urutan data asli

    Pengurutan benar

Tambahkan awalan hash ke kunci partisi

Jika Anda harus menggunakan kolom yang meningkat secara berurutan sebagai kunci partisi, tambahkan awalan hash untuk mengacak distribusi data yang berdekatan dalam tabel dan mendistribusikan beban akses secara merata.

Catatan

Setelah menambahkan awalan hash, data yang sebelumnya berurutan menjadi tersebar. Anda tidak lagi dapat menggunakan operasi baca rentang untuk membaca data yang logis berurutan. Gunakan search index sebagai alternatif untuk kueri rentang.

Desain kolom atribut

  • Kontrol lebar baris: Tablestore mendukung baris lebar (hingga ratusan ribu kolom atribut), tetapi membaca baris yang sangat lebar dalam satu permintaan dapat timeout. Batasi kolom atribut hingga sepuluh ribu per baris. Gunakan spesifikasi nama kolom atau pagination untuk membaca baris lebar.

  • Batas ukuran kolom atribut: Nilai satu kolom atribut tidak boleh melebihi 2 MB. Bagi data yang melebihi batas ini ke beberapa kolom, atau simpan di Object Storage Service (OSS).

  • Pisahkan tabel berdasarkan frekuensi akses: Jika satu baris memiliki banyak kolom atribut dengan frekuensi akses yang sangat berbeda, simpan kolom berfrekuensi tinggi dan rendah di tabel terpisah. Misalnya, dalam sistem manajemen produk, kuantitas dan harga produk diakses sering, sedangkan deskripsi produk (teks besar) jarang diakses. Pisahkan keduanya ke dua tabel.

  • Kompres teks besar: Kompres teks kolom atribut besar dan simpan sebagai biner untuk menghemat ruang penyimpanan dan mengurangi overhead baca/tulis.

  • Gunakan tipe Long untuk nilai moneter: Tablestore tidak mendukung tipe BigDecimal. Untuk bidang yang memerlukan perhitungan presisi seperti jumlah uang, gunakan tipe Long untuk menyimpan nilai dalam satuan terkecil (misalnya, simpan 5,32 USD sebagai 532 sen) guna menghindari kehilangan presisi dengan tipe Double.

Pemisahan tabel dan perencanaan kapasitas

Pemisahan tabel

Pastikan volume data satu search index tidak melebihi 20 miliar baris. Jika volume data melebihi 20 miliar baris, hubungi dukungan teknis Tablestore untuk evaluasi dan desain pemisahan tabel.

Misalnya, jika tabel log terbesar saat ini memiliki 6,1 miliar baris dan bertambah 2,1 miliar baris per tahun, tabel tersebut tidak akan melebihi 20 miliar baris dalam 3 hingga 5 tahun ke depan dan tidak memerlukan pemisahan. Rencanakan strategi pemisahan tabel lebih awal jika data yang ada sudah besar dan tumbuh pesat.

Pemisahan data panas/dingin

Pola akses data biasanya sensitif terhadap waktu: data terbaru sering diakses, sedangkan data lama secara bertahap menjadi dingin. Menyimpan data panas dan dingin dalam satu tabel menyebabkan beban akses tidak merata dan throughput baca/tulis yang dicadangkan tidak dimanfaatkan optimal.

Simpan data panas dan dingin di tabel terpisah dengan throughput baca/tulis yang dicadangkan berbeda. Bangun search index pada tabel data panas untuk kueri multi-kondisi, dan gunakan secondary index dengan pola kueri tetap pada tabel data dingin untuk mengurangi biaya. Search index mendukung TTL (time-to-live) data untuk secara otomatis memisahkan data panas dan dingin.

Impor data massal

Saat mengimpor data ke Tablestore secara massal, menulis dalam urutan kunci primer memusatkan beban tulis pada satu partisi dan memperlambat proses impor. Lakukan langkah-langkah berikut:

  • Pisahkan set data menjadi subset yang lebih kecil dan gunakan beberapa thread pekerja untuk memilih dan mengimpor subset secara acak secara paralel.

  • Hubungi dukungan teknis Tablestore untuk melakukan pre-splitting sebelum menulis data, sehingga data tersebar ke beberapa partisi sejak awal.

  • Gunakan TableStoreWriter untuk penulisan asinkron berkonkurensi tinggi, yang secara otomatis menangani distribusi bucket dan pengiriman batch.

Studi kasus desain: Catatan transaksi kartu mahasiswa

Contoh berikut menggunakan sistem transaksi kartu mahasiswa universitas untuk menggambarkan proses pengambilan keputusan desain tabel. Kolom kunci primer tabel data mencakup CardID (ID kartu mahasiswa), SellerID (ID merchant), DeviceID (ID terminal), dan OrderNumber. Aturan bisnisnya adalah sebagai berikut:

  • Setiap kartu mahasiswa dipetakan ke satu CardID, dan setiap merchant dipetakan ke satu SellerID.

  • Setiap terminal dipetakan ke DeviceID yang unik secara global.

  • OrderNumber unik dalam satu terminal dan meningkat seiring waktu, tetapi tidak unik secara global.

  • Catatan transaksi ditulis secara real time.

Pemilihan kunci primer dan kunci partisi

Pertama, tentukan kunci partisi. Bandingkan efek pendekatan partisi berbeda berdasarkan karakteristik masing-masing kolom kunci primer:

Pendekatan partisi

Analisis

CardID sebagai kunci partisi

Setiap mahasiswa melakukan transaksi terbatas per hari. Beban tulis tersebar ke puluhan ribu kartu, memberikan distribusi data yang baik. Direkomendasikan.

SellerID sebagai kunci partisi

Jumlah merchant kecil, dan sebagian besar transaksi terkonsentrasi pada beberapa merchant, sehingga mudah menciptakan hotspot. Tidak direkomendasikan.

DeviceID sebagai kunci partisi

Perangkat terminal unik secara global, memberikan distribusi yang baik. Namun, beberapa terminal bertrafik tinggi (seperti pembaca kartu di kantin populer) masih dapat menciptakan hotspot lokal.

OrderNumber sebagai kunci partisi

OrderNumber meningkat seiring waktu dalam satu terminal. Menggunakannya langsung sebagai kunci partisi menyebabkan hotspot ekor. Diperlukan awalan hash.

Kesimpulan desain

Berdasarkan analisis, CardID memberikan distribusi data terbaik (puluhan ribu kartu, beberapa transaksi per mahasiswa per hari) dan merupakan kunci partisi yang direkomendasikan. Urutan kunci primer adalah CardID, DeviceID, SellerID, OrderNumber. Untuk sebagian besar skenario bisnis, pemilihan kunci primer dan kunci partisi sudah cukup.

Optimasi lanjutan

Pemilihan kunci partisi dasar mungkin tidak memenuhi persyaratan kinerja. Berikut dua pendekatan optimasi lanjutan yang umum.

Skenario 1: Gabungkan beberapa kolom menjadi kunci partisi jika satu kunci partisi memiliki terlalu banyak data

Jika bisnis memerlukan kueri berdasarkan DeviceID dan Anda memilihnya sebagai kunci partisi, volume data di bawah satu DeviceID dapat melebihi 10 GB. Dalam kasus ini, gabungkan DeviceID, SellerID, dan CardID menjadi kunci partisi baru untuk membagi catatan dari terminal yang sama berdasarkan merchant dan kartu mahasiswa.

Sebelum penggabungan

DeviceID (kunci partisi)

SellerID

CardID

OrderNumber

Masalah

54

10

1001

000001

Semua catatan untuk DeviceID=54 berada dalam satu partisi. Seiring waktu, volume data terakumulasi dapat melebihi 10 GB.

54

20

1002

000002

78

20

1001

000003

Setelah penggabungan

DeviceID,SellerID,CardID (kunci partisi baru)

OrderNumber

Efek

54,10,1001

000001

Catatan transaksi dari terminal yang sama dibagi ke nilai kunci partisi berbeda berdasarkan merchant dan kartu mahasiswa.

54,20,1002

000002

78,20,1001

000003

Skenario 2: Tambahkan awalan hash jika nilai kunci partisi meningkat secara berurutan

Jika bisnis memerlukan kueri berdasarkan OrderNumber dan Anda memilihnya sebagai kunci partisi, peningkatan berurutan OrderNumber dalam satu terminal menyebabkan hotspot ekor. Hitung awalan hash MD5 untuk OrderNumber guna mendistribusikan data secara merata:

Original OrderNumber

4 Karakter MD5 Pertama

HashOrderNumber (kunci partisi)

000001

e2c8

e2c8,000001

000002

3f79

3f79,000002

000003

a5b1

a5b1,000003

Setelah menambahkan awalan hash, Anda dapat menghitung awalan hash untuk OrderNumber apa pun dengan algoritma yang sama untuk mendapatkan HashOrderNumber-nya. Namun, awalan hash mengacak urutan asli, sehingga Anda tidak lagi dapat menggunakan operasi baca rentang untuk membaca catatan yang logis berurutan.

Pemisahan data panas/dingin

Catatan transaksi kartu mahasiswa memiliki pola sensitif waktu yang jelas: catatan terbaru sering dikueri, sedangkan catatan mahasiswa yang telah lulus jarang diakses. Rencanakan pemisahan data panas/dingin sebagai berikut:

  • Simpan data aktif terbaru (misalnya, satu tahun terakhir) dan data historis di tabel terpisah dengan throughput baca/tulis yang dicadangkan berbeda.

  • Konfigurasikan throughput yang dicadangkan lebih tinggi untuk tabel aktif dan throughput lebih rendah untuk tabel historis guna mengurangi biaya penyimpanan.

  • Bangun search index pada tabel aktif untuk kueri multidimensi (misalnya berdasarkan merchant atau rentang waktu). Tabel historis hanya memerlukan kueri kunci primer.

  • Lakukan migrasi berkala data yang melebihi periode retensi dari tabel aktif ke tabel historis.