Nodeflux Central
Cluster Sharding

Cluster Sharding

Distribusikan data face recognition ke beberapa node FREMIS-N dengan coordinator routing untuk skala besar.

FREMIS-N mendukung mode cluster untuk mendistribusikan data enrollment ke beberapa node secara horizontal. Ini adalah pilihan arsitektur untuk deployment skala besar — ketika satu node tidak lagi mampu menampung volume enrollment yang terus berkembang, atau ketika target QPS melebihi kapasitas komputasi satu mesin.

Sebelum membaca halaman ini, pastikan Anda sudah memahami konsep dasar FREMIS-N — enrollment, keyspace, dan cara kerja recognition. Lihat Konsep untuk pengantar singkat, dan Deployment untuk panduan memilih antara standalone dan cluster.


Kapan Butuh Cluster?

Mode standalone sudah mencukupi untuk sebagian besar deployment awal. Pertimbangkan beralih ke cluster ketika salah satu kondisi berikut terpenuhi:

  • Volume enrollment besar — lebih dari ~500 ribu identitas, atau pertumbuhan yang cepat menuju jutaan enrollment
  • QPS tinggi — banyak kamera atau klien yang mengirim recognition request secara bersamaan dan satu node sudah mendekati batas kapasitasnya
  • Kapasitas memori — indeks pencarian in-memory tumbuh melampaui RAM yang tersedia di satu mesin
  • Rencana pertumbuhan — Anda mengantisipasi pertumbuhan data yang signifikan dan ingin merancang arsitektur yang dapat di-scale secara horizontal sejak awal

Mode Standalone

Semua enrollment, komputasi embedding, dan pencarian kemiripan berjalan dalam satu node. Tidak ada koordinasi antar mesin.

Klien(Visionaire / Lenz / API) FREMIS-NNode Tunggal(semua 256 partisi) DatabaseExternal

Kelebihan: Deployment sederhana, tidak ada jaringan antar node, mudah dimonitor dan di-debug.

Keterbatasan: Kapasitas dibatasi oleh satu mesin — RAM, CPU/GPU, dan storage hanya dari satu host.

Mode Cluster

Data dibagi ke beberapa node. Setiap node memegang subset dari 256 partisi total. Sebuah coordinator menerima semua permintaan dari klien dan merutekannya ke node yang tepat.

Klien(Visionaire / Lenz / API) Coordinator(router — partisi 0–255) Node 1Partisi 0–127 Node 2Partisi 128–255 DatabaseNode 1 DatabaseNode 2

Kelebihan: Kapasitas total adalah jumlah kapasitas semua node. Setiap node hanya memuat sebagian data — lebih sedikit memori per node.

Keterbatasan: Perlu mengelola beberapa node + coordinator, jaringan privat antar node, dan konfigurasi partisi awal.


Arsitektur Cluster

Komponen Utama

Cluster FREMIS-N terdiri dari dua jenis komponen:

Worker node — instance FREMIS-N yang berjalan dalam mode httpserver dengan parameter --partition-start dan --partition-end. Setiap node hanya menyimpan dan melayani data untuk rentang partisi yang ditugaskan kepadanya. Setiap node memiliki:

  • Indeks pencarian in-memory untuk subset partisinya
  • Koneksi ke database eksternal miliknya sendiri
  • Endpoint HTTP yang sama persis dengan node standalone

Coordinator — instance FREMIS-N yang berjalan dalam mode coordinator. Coordinator tidak menyimpan data enrollment sama sekali — fungsinya murni sebagai router. Coordinator:

  • Menerima semua permintaan dari klien (API-nya identik dengan node biasa)
  • Membaca file konfigurasi untuk mengetahui node mana yang memegang partisi mana
  • Meneruskan setiap permintaan ke node yang bertanggung jawab atas partisi yang relevan
Worker Nodes face_id → partisi 0–127 face_id → partisi 128–255 Klien Coordinator:4005 DB Node 1 DB Node 2 Node 1:4003Partisi 0–127 Node 2:4004Partisi 128–255

Transparansi API

Bagi klien yang mengonsumsi FREMIS-N — Visionaire, Lenz, atau integrasi kustom — coordinator terlihat persis seperti node biasa. Endpoint, format request, dan format response tidak berubah. Tidak ada perubahan kode di sisi klien saat beralih dari standalone ke cluster.


Konsep Sharding: 256 Partisi

FREMIS-N membagi data enrollment secara internal ke dalam 256 partisi (nomor 0 sampai 255). Partisi adalah unit distribusi terkecil — setiap enrollment disimpan di tepat satu partisi.

Cara Partisi Ditentukan

Partisi untuk setiap enrollment ditentukan secara deterministik berdasarkan keyspace_id dan face_id. Rumus yang digunakan adalah:

partition = SHA-1("{keyspace_id}-{face_id}") → ambil 4 byte pertama sebagai uint32 → mod 256

Penetapan partisi bersifat deterministik dan stabil — face_id yang sama dalam keyspace yang sama selalu dipetakan ke partisi yang sama, tidak peduli kapan enrollment dilakukan. Ini berarti Anda tidak dapat memindahkan identitas secara manual ke partisi lain. Jika redistribusi diperlukan, identitas harus didaftarkan ulang (re-enroll) dengan face_id baru, atau rentang partisi node perlu dikonfigurasi ulang.

Sebagai operator, Anda tidak menentukan partisi secara eksplisit — yang Anda tentukan hanyalah rentang partisi yang menjadi tanggung jawab setiap node.

Replikasi Partisi

Satu partisi dapat ditugaskan ke lebih dari satu worker node dalam konfigurasi coordinator. Ini adalah fitur yang didukung: coordinator akan mengirim enrollment ke semua node yang memegang partisi tersebut, dan menyeimbangkan read (recognition) secara acak di antara node-node tersebut menggunakan load balancer internal.

Replikasi partisi tidak setara dengan replikasi otomatis pada level storage. Coordinator mengirim enrollment ke semua replica yang sehat pada saat request masuk — namun tidak ada mekanisme sinkronisasi data yang berjalan di latar belakang antar node. Jika sebuah node sedang tidak tersedia saat enrollment dilakukan, enrollment tersebut akan di-antri oleh health watchdog internal dan diputar ulang saat node tersebut kembali online. Pastikan Anda memahami perilaku ini sebelum merancang strategi high availability berbasis replikasi partisi.

Implikasi untuk Operasi

  • Enrollment — coordinator menentukan partisi berdasarkan SHA-1 dari "{keyspace_id}-{face_id}", lalu mengirim enrollment ke semua node yang memegang partisi tersebut (termasuk replica jika dikonfigurasi).
  • Recognition (1:N) — pencarian harus menjangkau semua partisi. Coordinator mem-fan-out permintaan recognition ke semua node secara paralel, mengumpulkan hasil, dan mengembalikan kandidat terbaik ke klien. Lihat bagian Recognition 1:N di Cluster untuk detail lengkap.
  • Match (1:1) — tidak bergantung pada partisi karena tidak memerlukan lookup ke database enrollment.
  • Get by face_id — coordinator menghitung partisi dari face_id, lalu meneruskan request ke node yang bertanggung jawab atas partisi tersebut.

Recognition 1:N di Cluster — Fan-out dan Penggabungan Hasil

Untuk recognition 1:N, coordinator tidak merutekan ke satu partisi. Sebaliknya, coordinator melakukan fan-out — mengirim permintaan recognition ke semua worker node secara paralel, satu request per partisi yang ditugaskan, secara asinkron.

search — async search — async kandidat + skor kandidat + skor Klien Coordinator Node 1Partisi 0–127 Node 2Partisi 128–255 CoordinatorGabungkan & urutkanberdasarkan similarity

Setelah semua respons terkumpul, coordinator:

  1. Menggabungkan semua kandidat dari seluruh node
  2. Mengurutkan ulang berdasarkan similarity score secara descending
  3. Memotong hasil sesuai nilai k yang diminta
  4. Mengembalikan daftar kandidat final ke klien

Untuk enrollment, get-by-id, dan 1:1 match, coordinator merutekan ke satu node yang bertanggung jawab atas partisi yang dihitung dari face_id.

Hasil Parsial saat Node Tidak Tersedia

Coordinator mendukung mode allow_partial_search — jika diaktifkan, coordinator dapat mengembalikan hasil parsial dari node-node yang merespons ketika satu atau lebih node sedang tidak tersedia, alih-alih menggagalkan seluruh request. Jika sebagian hasil dikembalikan, respons akan menyertakan informasi node mana yang tidak berhasil dihubungi.

Hasil parsial berarti recognition hanya mencakup sebagian populasi enrollment. Keputusan berbasis hasil parsial harus ditangani dengan hati-hati di sisi aplikasi — terutama jika identitas yang dicari berada di partisi node yang sedang tidak tersedia.


Coordinator Routing

Coordinator adalah titik masuk tunggal untuk semua permintaan dalam deployment cluster. Cara kerjanya:

  1. Klien mengirim permintaan (enrollment, recognition, dll.) ke coordinator.
  2. Coordinator membaca konfigurasi node (config.yml) untuk mengetahui rentang partisi setiap node.
  3. Coordinator menentukan node mana yang harus menangani permintaan — berdasarkan partisi yang relevan.
  4. Coordinator meneruskan permintaan ke node target melalui HTTP.
  5. Respons dari node dikembalikan ke klien melalui coordinator.

Format Konfigurasi Coordinator

Coordinator memerlukan file konfigurasi YAML yang mendefinisikan alamat dan rentang partisi setiap node:

version: "v1"
nodes:
- address: "0.0.0.0:4003"  # node1
  partition_start: 0
  partition_end: 127
- address: "0.0.0.0:4004"  # node2
  partition_start: 128
  partition_end: 255

Coordinator kemudian dijalankan dengan merujuk ke file konfigurasi ini:

fremis_n_app coordinator \
  --listen-port 4005 \
  --config-path config.yml

Menjalankan Cluster

Contoh: 2 Node

Berikut adalah contoh lengkap menjalankan cluster dengan 2 node yang membagi 256 partisi secara merata.

Jalankan Node 1 (Partisi 0–127)

fremis_n_app httpserver \
  --access-key ACCESS_KEY \
  --secret-key SECRET_KEY \
  --storage postgres \
  --db-address 0.0.0.0 \
  --db-port 5432 \
  --db-name cluster \
  --db-username postgres \
  --db-password password \
  --partition-start 0 \
  --partition-end 127

Node ini hanya memuat dan melayani data untuk partisi 0 hingga 127.

Jalankan Node 2 (Partisi 128–255)

fremis_n_app httpserver \
  --access-key ACCESS_KEY \
  --secret-key SECRET_KEY \
  --storage postgres \
  --db-address 0.0.0.0 \
  --db-port 5432 \
  --db-name cluster \
  --db-username postgres \
  --db-password password \
  --partition-start 128 \
  --partition-end 255

Node ini hanya memuat dan melayani data untuk partisi 128 hingga 255.

Buat File Konfigurasi Coordinator

Buat file config.yml yang mendeskripsikan topologi cluster:

version: "v1"
nodes:
- address: "0.0.0.0:4003"
  partition_start: 0
  partition_end: 127
- address: "0.0.0.0:4004"
  partition_start: 128
  partition_end: 255

Sesuaikan address dengan alamat dan port aktual setiap node di jaringan Anda.

Jalankan Coordinator

fremis_n_app coordinator \
  --listen-port 4005 \
  --config-path config.yml

Setelah coordinator berjalan, semua permintaan klien diarahkan ke port coordinator (4005 dalam contoh ini). Node-node bekerja di belakang layar.

Verifikasi Cluster

Gunakan endpoint healthcheck untuk memastikan coordinator dan semua node merespons:

# Cek coordinator
curl http://coordinator-host:4005/v1/healthcheck

# Cek node individual (opsional, untuk debugging)
curl http://node1-host:4003/v1/healthcheck
curl http://node2-host:4004/v1/healthcheck

Contoh: 3 Node

Untuk 3 node, bagi 256 partisi menjadi tiga rentang yang kira-kira merata:

NodeRentang PartisiJumlah Partisi
Node 10 – 8485
Node 285 – 16985
Node 3170 – 25586

Rentang tidak harus merata secara sempurna — Anda bisa menyesuaikan distribusi jika beberapa node memiliki kapasitas RAM atau storage yang lebih besar.


Sizing Cluster

Prinsip Dasar

Dalam mode cluster, beban dibagi ke seluruh node. Setiap node hanya perlu menampung data untuk rentang partisinya:

  • Memori per node berkurang proporsional dengan jumlah node. Jika satu node standalone membutuhkan 32 GB RAM untuk 1 juta enrollment, maka 2 node masing-masing hanya perlu ~16 GB untuk beban yang sama.
  • Storage per node juga dibagi — setiap node hanya menyimpan data enrollment untuk partisinya.
  • Beban komputasi untuk recognition terdistribusi — coordinator mengirim permintaan ke semua node dan menggabungkan hasilnya.

Pertimbangan Jaringan

Coordinator berkomunikasi dengan setiap node untuk setiap permintaan recognition. Latency jaringan antar node berkontribusi langsung pada latency yang dirasakan klien.

Jalankan semua node coordinator dan worker dalam satu data center atau private network. Targetkan latency antar node di bawah 1 ms. Hindari menempatkan node di lokasi geografis berbeda atau melewati jaringan publik tanpa optimasi — ini akan meningkatkan latency recognition secara signifikan.

Aturan Praktis

SkenarioRekomendasi
1–2 juta enrollment2 node worker + 1 coordinator
2–5 juta enrollment3–4 node worker + 1 coordinator
Di atas 5 juta enrollmentSesuaikan berdasarkan benchmark; tambah node sesuai kebutuhan

Angka-angka di atas adalah titik awal. Validasi dengan benchmark menggunakan dataset nyata dari lingkungan Anda sebelum menentukan spesifikasi produksi final. Kapasitas aktual bergantung pada hardware, jumlah variasi enrollment per identitas, dan distribusi keyspace.


Ketahanan (Fault Tolerance)

FREMIS-N cluster tidak memiliki replikasi otomatis pada level storage. Jika satu node worker mengalami kegagalan dan tidak ada replica untuk partisi tersebut, data di partisi itu tidak dapat dilayani hingga node pulih kembali. Recognition request yang membutuhkan partisi dari node yang mati akan gagal — kecuali allow_partial_search diaktifkan, yang berarti hasil akan dikembalikan tanpa data dari partisi yang tidak tersedia.

Implikasi praktis:

  • Satu node mati (tanpa replica) — recognition request yang bergantung pada partisi di node tersebut akan gagal. Enrollment dan recognition untuk partisi di node lain tetap berjalan normal.
  • Satu node mati (dengan replica) — coordinator akan mengalihkan read ke replica yang sehat. Enrollment baru untuk partisi tersebut akan di-antri dan diputar ulang ke node yang mati begitu ia kembali online.
  • Coordinator mati — semua permintaan dari klien gagal, meskipun node-node worker masih berjalan. Coordinator adalah single point of failure.
  • Pemulihan node — saat node yang mati kembali online, indeks pencarian in-memory perlu di-load ulang dari database. Durasi pemulihan bergantung pada jumlah enrollment dalam partisi node tersebut. Health watchdog internal juga akan memutar ulang enrollment yang tertunda secara otomatis.

Rekomendasi Mitigasi

  • Gunakan storage yang andal dan berredundansi untuk database setiap node (RAID, managed database service)
  • Monitor kesehatan setiap node secara aktif (lihat bagian Monitoring di bawah)
  • Siapkan prosedur restart node yang terstandar agar pemulihan dapat dilakukan dengan cepat
  • Pertimbangkan redundansi coordinator dengan load balancer di depannya (misalnya nginx atau HAProxy) jika ketersediaan tinggi coordinator adalah prioritas
  • Jika high availability diperlukan, konfigurasikan replica untuk partisi-partisi kritis — coordinator mendukung beberapa node per partisi

Keyspace dalam Cluster

Keyspace adalah konsep logis — namespace tempat enrollment dikelompokkan. Dalam mode cluster, satu keyspace dapat tersebar di banyak node secara otomatis, karena data enrollment dalam satu keyspace didistribusikan ke partisi yang berbeda-beda.

Dari perspektif operator dan klien, keyspace tetap berperilaku sama seperti di mode standalone:

  • Membuat, menghapus, dan memanajemen keyspace dilakukan melalui coordinator — sama seperti di standalone.
  • Recognition ke keyspace tertentu dirutekan oleh coordinator ke semua node yang relevan secara otomatis.
  • Tidak perlu mengonfigurasi keyspace secara berbeda untuk cluster.

Untuk panduan lengkap manajemen keyspace, lihat Keyspace.


Monitoring Cluster

Dalam cluster, setiap node perlu dipantau secara individual. Coordinator tidak mengagregasi status kesehatan semua node — Anda perlu mengquery masing-masing node secara terpisah.

Coordinator menjalankan health watchdog internal yang memonitor kesehatan setiap node secara periodik. Jika sebuah node sementara tidak tersedia, health watchdog internal mengantri enrollment dan operasi keyspace yang belum berhasil dikirim, lalu memutarnya ulang secara otomatis begitu node kembali online. Ini berarti operasi tulis tidak hilang begitu saja saat terjadi gangguan sementara — namun konsistensi antara replica tetap bergantung pada pemulihan node.

Memantau Kapasitas per Node

Gunakan endpoint /v1/loaded-vectors pada setiap node untuk melihat berapa banyak vektor yang sedang dimuat di memori:

# Query setiap node untuk melihat jumlah vektor yang dimuat
curl http://node1-host:4003/v1/loaded-vectors
curl http://node2-host:4004/v1/loaded-vectors

Endpoint ini berguna untuk memvalidasi bahwa distribusi data antar node sesuai ekspektasi — dan untuk mendeteksi ketidakseimbangan yang mungkin terjadi setelah enrollment besar ke keyspace tertentu.

Memantau Resource per Node

Gunakan endpoint /v1/resource-stats untuk memantau penggunaan CPU, RAM, dan GPU di setiap node:

# Query resource stats tiap node
curl http://node1-host:4003/v1/resource-stats
curl http://node2-host:4004/v1/resource-stats

Pantau penggunaan RAM secara khusus — jika satu node mendekati batas memori karena indeks pencarian in-memory tumbuh, ini adalah sinyal untuk mempertimbangkan penambahan node atau redistribusi partisi.

Lihat Cluster Operations API untuk dokumentasi lengkap kedua endpoint ini.


Deployment Cluster dan Instalasi

Topologi cluster dipilih saat instalasi awal, bukan di kemudian hari. Pastikan Anda sudah memutuskan topologi sebelum memulai proses instalasi.

Untuk panduan instalasi dan dependensi yang diperlukan, lihat Install Dependencies.

Migrasi dari standalone ke cluster di kemudian hari membutuhkan perencanaan yang matang — termasuk redistribusi data dan downtime untuk rekonfigurasi. Jika Anda mengantisipasi pertumbuhan ke skala cluster dalam 6–12 bulan ke depan, lebih baik merancang topologi cluster sejak awal.


Troubleshooting Cluster

Tiga skenario yang spesifik untuk deployment cluster — bukan masalah inti FREMIS-N.

Coordinator Returns Errors untuk Sebagian Request

Coordinator mengembalikan 500 atau "not found" untuk beberapa face_id, padahal identitas seharusnya ada.

  1. Periksa kesehatan setiap node. Dari host coordinator, curl http://<node>:4003/health untuk semua worker. Pastikan semua node yang terdaftar di config.yml accessible dan berjalan.
  2. Verifikasi partition mapping. Buka coordinator_config.yml dan pastikan partition_start/partition_end antar node tidak ada gap dan tidak overlap. Contoh valid: Node1 [0–127], Node2 [128–255]. Contoh invalid: Node1 [0–100], Node2 [150–255] (gap 101–149).
  3. Reload coordinator config. Update file dengan mapping yang benar, restart coordinator, lalu coba ulang request yang gagal.
  4. Identifikasi partisi dari face_id. Hash "{keyspace_id}-{face_id}" dengan SHA-1, ambil 4 byte pertama sebagai uint32, mod 256. Verifikasi partisi tersebut ter-map ke node yang accessible.

Partition Imbalance

Beberapa node menerima jauh lebih banyak request atau memegang lebih banyak vektor dari yang lain.

  1. Analisis distribusi. Pantau /v1/loaded-vectors per node untuk jumlah enrollment per partisi. Identifikasi node yang dominan.
  2. Rebalance jika sangat imbalanced. Misalnya 90% data di satu node — pertimbangkan re-shard dengan partition boundary baru. Ini memerlukan data re-migration; rencanakan downtime atau migrasi multi-fase. Hubungi support untuk skala besar.
  3. Monitor sebelum dan sesudah. Catat distribusi load sebelum dan setelah rebalance untuk memastikan perbaikan tercapai.

Latency Cluster Lebih Tinggi dari Standalone

Coordinator ditambah satu hop network — di LAN tipikal kontribusinya < 1ms. Jika latency naik signifikan:

  • Pastikan semua node dan coordinator berada di private network yang sama dengan latency antar node < 1ms.
  • Hindari menempatkan node di lokasi geografis berbeda atau via Internet/VPN publik.
  • Untuk fan-out 1:N, latency akhir adalah max latency seluruh node (paralel), jadi satu node lambat sudah cukup memperlambat seluruh request. Lihat node mana yang outlier dengan /v1/resource-stats.

Untuk masalah yang bukan spesifik cluster — recognition, enrollment, performa, lisensi, database — lihat halaman fitur masing-masing: 1:N Search, Enrollment, Developer Guide — Performance, Services, Installation.


Selanjutnya

On this page