Jumlah partisi adalah keputusan desain pertama yang diambil saat sebuah topic dibuat karena nilai itu menetapkan kapasitas tulis topic sekaligus tingkat paralelisme pembacaannya. Topik ini menjelaskan pertimbangan yang memengaruhi jumlah partisi, perhitungan yang menghasilkan angka awal, perintah untuk menambah partisi pada topic yang sudah ada, dan risiko penambahan partisi pada topic yang menggunakan key. Setelah membaca topik ini, jumlah partisi dapat ditetapkan berdasarkan angka yang dapat dihitung ulang.
Pertimbangan jumlah partisi#
Partisi adalah unit paralelisme pada Kafka. Producer menulis ke beberapa partisi secara serentak, sedangkan consumer group membagikan partisi kepada anggotanya sehingga setiap consumer mengerjakan partisi yang berbeda. Kapasitas tulis seluruh topic, yang lazim disebut throughput, mendekati penjumlahan kapasitas semua partisinya, dan jumlah consumer yang benar-benar bekerja tidak dapat melebihi jumlah partisi. Dua batas itulah yang menjadi dasar penentuan jumlah partisi.
Tabel berikut merangkum sisi-sisi yang terpengaruh ketika jumlah partisi ditambah.
| Sisi | Pertimbangan | Dampak menambah partisi |
|---|---|---|
| Producer | Throughput penulisan total | Kapasitas tulis bertambah karena beban terbagi ke lebih banyak partisi |
| Consumer group | Jumlah consumer yang bekerja serentak | Batas paralelisme pembacaan naik |
| Broker | Berkas log terbuka dan lalu lintas replikasi | Beban broker bertambah untuk setiap partisi baru |
| Aplikasi | Jaminan pengurutan per key | Pengurutan dalam satu partisi tetap, tetapi pemetaan key ke partisi berubah |
Setiap partisi membutuhkan satu berkas log di broker, satu alur replikasi, dan satu slot pada pembagian tugas consumer group. Topic dengan jumlah partisi yang besar memerlukan sumber daya broker yang tidak sedikit, sehingga penambahan partisi dilakukan dengan alasan throughput atau paralelisme yang jelas. Penambahan juga bersifat satu arah karena Kafka tidak menyediakan pengurangan jumlah partisi. Nilai yang ditetapkan pada awal pembuatan topic dengan demikian perlu diperhitungkan dengan cermat.
Perhitungan jumlah partisi#
Jumlah partisi minimal dihitung dari throughput yang harus dicapai oleh topic. Apabila throughput total yang dituju dinyatakan dan perkiraan throughput yang mampu ditulis ke satu partisi dinyatakan , jumlah partisi minimal dari sisi penulisan mengikuti
Perhitungan yang sama diulang dari sisi pembacaan dengan membagi throughput total dengan throughput yang mampu dibaca oleh satu consumer. Nilai terbesar dari kedua hasil dipilih karena hambatan dapat berada di salah satu sisi saja. Skrip berikut menghitung contoh konkret, yaitu topic yang harus menampung 60 MB per detik dengan perkiraan 10 MB per detik untuk penulisan satu partisi dan 15 MB per detik untuk pembacaan satu consumer.
import math
# angka contoh dalam megabyte per detik
target_total = 60 # throughput yang harus dicapai seluruh topic
per_partisi = 10 # perkiraan throughput producer per partisi
per_consumer = 15 # perkiraan throughput satu consumer
n_producer = math.ceil(target_total / per_partisi)
n_consumer = math.ceil(target_total / per_consumer)
n_pilih = max(n_producer, n_consumer)
print(f"partisi dari sisi producer : {n_producer}")
print(f"partisi dari sisi consumer : {n_consumer}")
print(f"jumlah partisi terpilih : {n_pilih}")partisi dari sisi producer : 6
partisi dari sisi consumer : 4
jumlah partisi terpilih : 6Nilai dari sisi producer adalah 6 karena 60 dibagi 10, sedangkan nilai dari sisi consumer adalah 4 karena 60 dibagi 15. Jumlah partisi terpilih adalah 6, yaitu nilai yang lebih besar, karena memilih 4 membuat sisi penulisan menjadi hambatan. Angka dalam skrip merupakan perkiraan awal dan bukan hasil pengukuran, sehingga setelah topic berjalan nilai tersebut diuji ulang dengan data aktual. Ruang tumbuh disediakan dengan menghitung berdasarkan target yang lebih besar dari beban hari ini, misalnya dua kali lipat, karena jumlah partisi tidak dapat dikurangi kembali.
Menambah partisi pada topic yang sudah ada#
Perintah pembuatan topic menerima opsi --partitions, dan jumlah itu tetap berlaku sampai diubah secara eksplisit. Perintah berikut membuat topic demo baru dengan tiga partisi, lalu menampilkan deskripsinya. Baris kepala deskripsi disaring menggunakan grep sehingga keluarannya hanya memuat baris per partisi.
(
cd /home/kal/my-project/kafka-runtime/kafka
bin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --if-exists --topic m2-partisi-demo 2>/dev/null
sleep 2
bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic m2-partisi-demo --partitions 3
bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic m2-partisi-demo | grep "Partition:" | expand
)Created topic m2-partisi-demo.
Topic: m2-partisi-demo Partition: 0 Leader: 1 Replicas: 1 Isr: 1 Elr: LastKnownElr:
Topic: m2-partisi-demo Partition: 1 Leader: 1 Replicas: 1 Isr: 1 Elr: LastKnownElr:
Topic: m2-partisi-demo Partition: 2 Leader: 1 Replicas: 1 Isr: 1 Elr: LastKnownElr: Keluaran memuat satu baris untuk setiap partisi, mulai dari Partition: 0 sampai Partition: 2, sehingga jumlah partisi terlihat langsung dari hasil perintah. Setiap baris menyebut Leader: 1 dan Isr: 1 karena demo ini berjalan pada broker tunggal, dan setiap partisi hanya memiliki satu replika. Pada topic yang sudah ada, penambahan jumlah partisi dilakukan dengan opsi --alter, misalnya bin/kafka-topics.sh --bootstrap-server localhost:9092 --alter --topic m2-partisi-demo --partitions 6. Partisi yang baru ditambahkan hanya menerima pesan yang ditulis setelahnya, sedangkan pesan lama beserta offset-nya tetap berada di partisi semula.
Risiko penambahan partisi pada topic berkunci#
Producer memetakan key ke partisi melalui fungsi hash, kemudian menerapkan operasi modulo terhadap jumlah partisi. Pemetaan ini stabil hanya selama jumlah partisi tidak berubah. Ketika jumlah partisi naik dari tiga menjadi enam, hampir semua key berpindah partisi karena hasil modulo ikut berubah.
Pergeseran pemetaan itu membawa dua akibat yang perlu diantisipasi. Pesan dengan key yang sama dapat tercatat pada partisi berbeda setelah penambahan, sehingga jaminan pengurutan per key tidak lagi mencakup pesan lama dan pesan baru sekaligus. Selain itu, consumer yang menyimpan keadaan per key pada memori atau penyimpanan turunan yang dibangun dari aliran pesan menerima campuran data dari pemetaan lama dan pemetaan baru. Pada topic tanpa key, pergeseran semacam ini tidak muncul karena distribusi pesan tidak bergantung pada key.
Karena itu, jumlah partisi topic berkunci sebaiknya ditetapkan sejak awal dengan ruang tumbuh yang cukup. Bila kebutuhan paralelisme benar-benar melonjak, pilihan yang lebih aman adalah membuat topic baru dengan jumlah partisi lebih besar dan memindahkan aliran ke sana dalam satu kali perpindahan. Cara tersebut menjaga pemetaan key tetap stabil selama masa pakai topic.
Ringkasan#
- Jumlah partisi menetapkan kapasitas tulis topic dan jumlah consumer yang bekerja serentak dalam satu consumer group.
- Jumlah partisi awal dihitung dari throughput total dibagi throughput per partisi dan dibagi throughput per consumer, lalu diambil nilai terbesar dari keduanya.
- Penambahan partisi dilakukan dengan
--alter --partitions, tidak dapat dibatalkan, dan partisi baru hanya menerima pesan baru. - Pada topic berkunci, penambahan partisi mengubah pemetaan key sehingga urutan per key antara pesan lama dan pesan baru tidak dijaga.
Referensi#
- Apache Kafka documentation: Topic configs — Apache Software Foundation — daftar konfigurasi tingkat topic yang diberlakukan broker per partisi, termasuk pengaturan lognya.
- Apache Kafka documentation: Design — Apache Software Foundation — penjelasan desain log terpartisi yang menjadikan partisi sebagai unit paralelisme penulisan dan pembacaan.