Pernah gak sih kalian bayangin punya sistem kayak Face Recognition Gate di stasiun kereta? Dimana ribuan orang lewat, data wajah dicocokkan dalam hitungan detik, dan sistemnya gak boleh mati meskipun salah satu servernya meledak?
Kali ini aku akan dokumentasikan eksperimen lab gratisan. Kita akan membangun arsitektur High Availability (Active-Active) menggunakan 3 server Ubuntu.
Tujuannya simpel: Server A, B, dan C harus selalu sinkron.
Kalau misal nihya aku pengen input data atau upload foto di Server A, detik itu juga data harus muncul di Server B dan C. Kalau Server B mati? Sistem jalan terus. Begitu Server B hidup lagi? Dia otomatis ngejar ketertinggalan datanya. Magic!
Tools Yang Digunakan
Dulu pasti dalam benak terbesit kenapa gak pakai copy-paste biasa atau cronjob? apa iya tiap menit ada jeda soalnya pake cronjob? maka dari itu Karena kita butuh real-time dan consistency. Ini tools yang aku gunakan:
1. MariaDB Galera Cluster
Ini bukan replikasi Master-Slave biasa. Galera menggunakan sistem Multi-Master (Active-Active).
-
Kenapa Galera? Semua node bisa baca-tulis. Tidak ada istilah "Server Utama" dan "Server Cadangan". Semua setara.
-
Keuntungan: Synchronous replication. Data dijamin sama persis di semua node. Kalau satu node mati, node lain otomatis ambil alih tanpa perlu config manual.
2. Syncthing
Database cuma buat simpan teks. Lha foto wajahnya gimana? Kita pakai Syncthing.
-
Kenapa Syncthing? Ini adalah aplikasi sinkronisasi file P2P (Peer-to-Peer) yang terdesentralisasi.
-
Keuntungan: Ringan, punya GUI Dashboard web yang enak dilihat, dan sangat cepat mendeteksi file baru. Enggak perlu ribet setup NFS atau GlusterFS yang berat.
Skenario Lab
Kita asumsikan sudah ada 3 Server Ubuntu yang sudah terinstall MariaDB.
-
Server A: 192.168.56.11
-
Server B: 192.168.56.12
-
Server C: 192.168.56.13
(Pastikan port 3306, 4567, 4568, 4444 sudah di-allow di firewall ya!)
1. Konfigurasi MariaDB Galera Cluster
Langkah pertama, matikan dulu service database di ketiga server biar gak bentrok saat diedit.
sudo systemctl stop mariadb
Edit Konfigurasi (my.cnf)
Buat atau edit file konfigurasi Galera di /etc/mysql/mariadb.conf.d/60-galera.cnf.
Isi konfigurasi ini di SEMUA Server (Sama persis), kecuali bagian IP Address node-nya.
[mysqld]
binlog_format = ROW
default-storage-engine = innodb
innodb_autoinc_lock_mode = 2
bind-address = 0.0.0.0
# Setting Galera
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
# Masukkan IP ketiga server di sini
wsrep_cluster_address = "gcomm://192.168.56.11,192.168.56.12,192.168.56.13"
wsrep_cluster_name = "my_ha_cluster"
wsrep_sst_method = rsync
# --- BAGIAN INI SESUAIKAN TIAP SERVER ---
# Contoh di Server A:
wsrep_node_address = "192.168.56.11"
wsrep_node_name = "Node_A"
# DI SERVER B (192.168.56.12):
# wsrep_node_address = "192.168.56.12"
# wsrep_node_name = "Node_B"
# DI SERVER C (192.168.56.13):
# wsrep_node_address = "192.168.56.13"
# wsrep_node_name = "Node_C"
(Jangan lupa ubah wsrep_node_address di Server B dan C sesuai IP mereka masing-masing).
The Moment of Truth: Bootstrapping
Cluster gak akan jalan kalau dinyalakan barengan. Harus ada satu pemimpin yang memulai.
-
Di Server A (Hanya Server Pertama): Jalankan perintah ini untuk inisiasi cluster baru.
sudo galera_new_cluster -
Di Server B dan C: Nyalakan service seperti biasa. Mereka otomatis akan mencari Server A dan bergabung.
sudo systemctl start mariadb
Cek Status
Masuk ke mysql dan ketik query ini:
SHOW STATUS LIKE 'wsrep_cluster_size';
Kalau angkanya 3, selamat! Database kalian sudah High Availability. Coba insert di A, pasti muncul di C.
2. Konfigurasi File Sync dengan Syncthing
Sekarang urusan file gambar. Install dulu di ketiga server:
sudo apt install syncthing -y
Buat Service agar jalan otomatis (sebagai root/user): Kita jalankan sebagai user saat ini (misal root atau ubuntu) agar tidak pusing permission folder. contoh kali ini ubuntu;# Ganti 'ubuntu' dengan username Anda jika bukan ubuntu, atau 'root'
sudo systemctl enable syncthing@ubuntu1
sudo systemctl start syncthing@ubuntu1
# ubah sesuai urutan di server 1-3
Buka Akses GUI
Secara default Syncthing cuma bisa dibuka dari localhost. Karena ini server headless, kita harus ubah config-nya biar bisa diakses dari laptop kita.
Edit file ~/.config/syncthing/config.xml:
Cari baris : Ubah 127.0.0.1:8384 menjadi 0.0.0.0:8384.
Restart syncthing: sudo systemctl restart syncthing@ubuntu1.
Pairing (Menjodohkan Server)
Buka browser laptop, akses IP ketiga server di port 8384 (contoh: http://192.168.56.11:8384).
-
Tab 1:
http://192.168.56.11:8384(Server A) -
Tab 2:
http://192.168.56.12:8384(Server B) -
Tab 3:
http://192.168.56.13:8384(Server C)
(Jika diminta set password GUI, set saja dulu bebas).
-
Di Tab Server A:
-
Klik Actions > Show ID. Copy kode QR/ID panjangnya.
-
-
Di Tab Server B:
-
Klik Add Remote Device.
-
Paste ID Server A. Beri nama "Server A".
-
Klik Save.
-
-
Kembali ke Tab Server A:
-
Akan muncul notifikasi "Server B wants to connect". Klik Add Device.
-
Save. (Sekarang A dan B sudah sehati).
-
-
Ulangi langkah ini agar semua saling kenal:
-
Hubungkan B ke C.
-
Hubungkan C ke A.
-
Pastikan di dashboard setiap server, bagian "Remote Devices" terlihat Connected (Hijau).
-
Di Dashboard Server A, klik Actions > Show ID. Copy ID-nya.
-
Di Dashboard Server B, klik Add Remote Device, paste ID Server A.
-
Lakukan hal yang sama agar membentuk Segitiga (A ke B, B ke C, C ke A).
Sharing Folder
-
Buat folder target di terminal semua server:
mkdir /opt/nyoba && sudo chmod 777 /opt/nyoba. -
Di Dashboard Server A: Add Folder, arahkan path ke
/opt/nyoba. -
Di tab Sharing, centang Server B dan Server C.
-
Server B dan C akan dapat notifikasi pop-up. Klik Add, dan pastikan path-nya sama.
Sekarang, coba upload foto ke /opt/nyoba di Server A. Dalam hitungan detik, foto itu akan ada di Server B dan C!
Bagaimana Jika Salah Satu Server Mati?
Ini bagian paling seru. Apa yang harus dilakukan admin jika Server B mati mendadak (kena tendang kabelnya, misalnya)?
Jawabannya: TIDAK ADA.
Iya, beneran. Kalian bisa lanjut ngopi.
-
Saat Mati: Galera Cluster di Server A dan C akan sadar B hilang. Mereka lanjut bekerja berdua. Aplikasi/API tetap jalan normal. Syncthing akan menandai B sebagai "Disconnected".
-
Saat Hidup Lagi: Begitu Server B dinyalakan, Galera otomatis melakukan IST (Incremental State Transfer). Dia cuma minta data transaksi yang "bolong" selama dia mati. Syncthing juga akan scan folder dan download file yang belum dia punya.
Best Practice:
Jika server mati sangat lama (berhari-hari), pastikan koneksi jaringan kencang saat dia dinyalakan kembali, karena dia akan melakukan sinkronisasi data yang cukup besar (Full Sync).
Jika server mati sangat lama (database bertambah bergiga-giga saat dia mati), proses SST (Snapshot State Transfer) di MariaDB akan memakan bandwidth besar karena dia meng-copy ulang seluruh database.
Saran Konfigurasi (Optional): Di file 60-galera.cnf, ada setting bernama gcache.size. Defaultnya kecil (sekitar 128MB). Ini adalah "memori ingatan" Galera.
-
Jika data baru di Server A < 128MB, Server B pakai IST (Cepat).
-
Jika data baru di Server A > 128MB, Server B kena SST (Copy ulang total).
Kalau server kamu traffic-nya tinggi, kamu bisa naikkan gcache.size = 1G di semua server agar Server B punya kesempatan lebih besar untuk melakukan IST daripada harus download ulang semua DB.
Meskipun arsitektur yang dibangun (MariaDB Galera + Syncthing) ini sangat powerful dan standar industri, tidak ada sistem yang sempurna. Ada beberapa "Jebakan Batman" atau kekurangan yang harus waspadai, terutama untuk kasus absensi wajah.
Berikut adalah analisis risiko dan hal yang perlu diperhatikan:
1. MariaDB Galera Cluster (Database)
"The Weakest Link" (Si Paling Lemot)
Galera menggunakan Synchronous Replication. Artinya, saat melakukan INSERT di Server A, transaksi itu belum dianggap "sukses" sampai Server B dan C mengonfirmasi "Oke, saya sudah terima!".
-
Risikonya: Jika jaringan ke Server C lemot (misal kabelnya kendor), maka proses
INSERTdi Server A juga akan ikut lemot menunggu Server C. Performa write cluster ditentukan oleh server/jaringan yang paling lambat.
Deadlock pada "Hot Row"
Karena ini Multi-Master, apa yang terjadi jika Server A dan Server B mencoba mengedit baris data yang sama di detik yang sama?
-
Risikonya: Galera akan membatalkan salah satunya (Deadlock).
-
Solusi: Aplikasi kamu misal Python/Go harus siap menangkap error deadlock dan melakukan retry otomatis. Hindari logic yang mengupdate satu baris counter secara brutal dari banyak node sekaligus.
Jangan Hapus Data Masal (Large Transaction)
Jangan pernah melakukan query seperti DELETE FROM log_transaksi WHERE tanggal < '2024-01-01' yang menghapus jutaan baris sekaligus.
-
Risikonya: Cluster bisa hang atau stall karena semua node sibuk memproses transaksi raksasa tersebut.
-
Solusi: Pecah transaksi besar menjadi kecil-kecil (
LIMIT 1000).
2. Syncthing (File Sync)
Race Condition (Balapan DB vs File)
Ini risiko paling nyata untuk aplikasi. Database (Galera) itu sangat cepat (milidetik), sedangkan File Sync (Syncthing) butuh waktu untuk scan, hash, dan transfer (bisa beberapa detik).
-
Skenario Masalah:
-
User upload foto di Server A.
-
Server A simpan file & insert DB.
-
User lain refresh halaman via Server B.
-
Database di Server B sudah ada datanya, TAPI Filenya belum sampai (masih OTW).
-
Aplikasi error "File Not Found".
-
-
Solusi: Di kode API (endpoint
GET), berikan logic pengecekan: "Jika data di DB ada tapi file belum ada, tunggu sebentar atau lempar status Processing, jangan 404/Error."
Conflict Files
Jika Server A mengedit wajah.jpg dan Server B juga mengedit wajah.jpg di waktu bersamaan.
-
Risikonya: Syncthing tidak akan menggabungkan (merge) fotonya. Dia akan membuat file baru bernama
wajah.sync-conflict-blabla.jpg. -
Solusi: Pastikan nama file yang diupload selalu unik (misal pakai UUID atau Timestamp), jangan pakai nama statis yang ditimpa terus-menerus.
Syncthing Bukan Backup!
Ini salah kaprah yang sering terjadi.
-
Risikonya: Jika ada hacker atau admin yang tidak sengaja menghapus folder
/opt/face_datadi Server A... Syncthing akan dengan patuh menghapus folder itu juga di Server B dan C dalam hitungan detik. -
Solusi: Tetap lakukan backup berkala (snapshot/zip) ke hardisk eksternal atau cloud storage yang tidak terhubung sinkronisasi real-time.
3. Infrastruktur & Jaringan
Split Brain (Otak Terbelah)
Galera butuh "Quorum" (suara mayoritas) untuk berjalan.
-
Skenario: Kita punya 3 Server.
-
Jika 1 mati, sisa 2 (Mayoritas). Aman.
-
Jika 2 mati, sisa 1 (Minoritas).
-
-
Risikonya: Server terakhir yang hidup ini akan menolak semua transaksi tulis (Read-Only) demi keamanan, karena dia bingung "Saya yang terputus dari jaringan, atau teman-teman saya yang mati?".
-
Solusi: Pastikan kamu punya minimal 3 node ganjil. Jika sisa 1 server saja, kamu harus manual memaksa dia jadi Primary (
SET GLOBAL wsrep_provider_options='pc.bootstrap=YES').
Rangkuman untuk Developer
Mengingat kali aja pembaca sebagai developer Backend (PHP/Go/Python), ini yang harus diperhatikan di kode:
-
Handling Delay File: Saat read data, cek
file_exists()dulu. Jika DB ada tapi file tidak ada, mungkin file sedang OTW. -
Unique Filename: Gunakan UUID untuk nama file foto agar tidak konflik di Syncthing.
-
Retry Mechanism: Jika insert DB gagal karena Deadlock, buat fungsi auto-retry 3x.
Secara umum, untuk skala Face Recognition korporat/pabrik, solusi ini sudah sangat mumpuni dan jauh lebih baik daripada single server.
Tambahan untuk solusi dari permasalahan "Galera menggunakan Synchronous Replication".
Berikut solusinya, dari yang paling mudah hingga yang paling advanced:
1. Solusi Konfigurasi: Parallel Slave Threads (Paling Mudah)
Jika Server C lambat bukan karena jaringan, tapi karena CPU/Disk-nya kewalahan memproses antrean transaksi, kita bisa suruh dia kerja "lebih ngebut" dengan menggunakan multi-threading.
Secara default, Galera mungkin hanya pakai 1 jalur untuk menulis data replikasi. Ubah agar dia pakai banyak jalur sekaligus.
-
Caranya: Edit
my.cnfatau60-galera.cnfdi SEMUA server.# Sesuaikan dengan jumlah Core CPU. # Rumus kasar: 4 x Jumlah Core. Misal 2 Core = 8 threads. wsrep_slave_threads = 8Efek: Server C bisa mengejar ketertinggalan lebih cepat.
2. Solusi "Curang": Relaxed Durability (innodb_flush_log)
Ini trik yang sering dipakai developer untuk meningkatkan performa write drastis, dengan sedikit risiko.
Default MySQL (innodb_flush_log_at_trx_commit = 1) memaksa data ditulis ke hardisk fisik setiap kali ada transaksi. Ini lambat. Kita bisa ubah ke nilai 2. Artinya: "Tulis ke RAM dulu, baru ke hardisk tiap 1 detik sekali."
-
Caranya: Edit
my.cnfdi SEMUA server.innodb_flush_log_at_trx_commit = 2 -
Risikonya: Jika mati listrik total mendadak (tanpa UPS), ada potensi hilang data transaksi 1 detik terakhir.
-
Keuntungannya: Proses write jadi jauh lebih ringan, sehingga Server C tidak mudah jadi bottleneck.
3. Solusi Arsitektur: Asynchronous Processing (Best Practice)
Jika API aplikasimuharus responsif (user tidak boleh menunggu loading lama), jangan biarkan user menunggu database selesai insert.
Gunakan konsep "Fire and Forget" di aplikasi kamu.
-
Cara Kerja Lama (Blocking): User Upload -> Python terima -> Python Insert ke DB (Nunggu Galera A,B,C deal) -> Python Balas "Sukses". (User nunggu lama).
-
Cara Kerja Baru (Async/Background Task): User Upload -> Python terima -> Simpan File & Taruh Task di Background -> Python Balas "Sukses, sedang diproses".
-
Di belakang layar (
BackgroundTasksdi FastAPI), Python baru pelan-pelan insert ke DB. -
Jika Server C lemot, yang nunggu adalah "Background Task"-nya, bukan User-nya.
-
4. Solusi Topologi: Hybrid (Galera + Async Slave)
Jika Server C lokasinya jauh (misal beda kota) atau jaringannya memang jelek dan tidak bisa diperbaiki, jangan masukkan Server C ke dalam Cluster Galera.
Ubah topologinya menjadi:
-
Server A & Server B: Galera Cluster (Satu lokasi, jaringan kencang).
-
Server C: Standard MySQL Slave (Async replication) yang mengambil data dari Server A.
-
Keuntungan: Server A & B ngebut tanpa nunggu C. Server C akan terima data "sebisanya" (mungkin telat beberapa detik), tapi tidak akan membebani performa A & B.
-
Kerugian: Server C tidak bisa dipakai untuk write (harus Read-Only). Jika A & B mati semua, C tidak bisa otomatis jadi Master tanpa setting manual.
5. Mekanisme Otomatis Galera: Flow Control
Sebenarnya Galera punya fitur bawaan namanya Flow Control. Jika Server C tertinggal terlalu jauh (queue-nya menumpuk), Galera otomatis akan MEMPAUSE Server A dan B supaya C bisa mengejar. Inilah yang bikin terasa "lemot".
Jika ingin Server C "ditinggal saja" kalau terlalu lemot (daripada mengorbankan performa A & B), Anda bisa mengatur agar node yang lemot ditendang keluar cluster. Tapi ini berbahaya (cluster jadi tidak sync), jadi tidak disarankan kecuali darurat.
Jadi mending yang mana?
-
Langkah Pertama (Wajib): Terapkan Solusi No. 1 (
wsrep_slave_threads). Ini gratis dan mudah. -
Langkah Kedua (Rekomendasi): Terapkan Solusi No. 2 (
innodb_flush_log_at_trx_commit = 2). Performanya naik signifikan, risikonya kecil selama ada UPS. -
Langkah Ketiga (Coding): Gunakan Solusi No. 3 (Background Task) di Python FastAPI. Ini membuat aplikasi terasa sangat cepat di mata user, tidak peduli DB-nya lagi lemot atau tidak.
Arsitektur yang baru saja kita bangun ini secara teknis memiliki nama gabungan yang keren, Kita bisa menyebutnya sebagai:
"High-Availability Edge Computing Cluster"
Mari kita bedah satu per satu kenapa namanya begitu, karena ini gabungan dari Lokasi, Fungsi, dan Topologi.
1. Sisi Lokasi & Fungsi: Edge Computing
Ya, ini adalah Edge Computing.
-
Alasannya: Kita melakukan pemrosesan berat (face recognition) di lokasi kejadian (di pabrik/stasiun/kantor), bukan mengirim video streaming ke Cloud (AWS/Google) untuk diproses di sana.
-
Ciri Khas: Server fisik berada dekat dengan "sumber data" (kamera CCTV/Gate).
-
Keuntungan: Latency sangat rendah (wajah terdeteksi instan) dan hemat bandwidth internet.
2. Sisi Operasional: Active-Active HA Cluster
Ini menjelaskan bagaimana server-server tersebut bekerja sama.
-
Cluster: Kumpulan komputer yang bekerja seolah-olah satu sistem tunggal.
-
High Availability (HA): Sistem didesain agar tidak boleh mati (downtime minim).
-
Active-Active: Ini poin kuncinya. Server A, B, dan C semuanya Aktif melayani trafik. Bukan model Active-Passive (dimana Server B cuma tidur menunggu Server A mati).
3. Sisi Data: Shared-Nothing Architecture
Ini istilah teknis untuk cara kita menyimpan data tadi.
-
Shared-Disk (Cara Lama/Mahal): Server A dan B terhubung ke satu kabel storage mahal (SAN/NAS). Kalau storage-nya rusak, semua server mati.
-
Shared-Nothing (Cara Kita): Server A punya hardisk sendiri, Server B punya sendiri. Tidak ada satu titik kegagalan pusat. Data disinkronkan via software (Galera & Syncthing). Ini arsitektur modern yang dipakai Google/Facebook di awal-awal mereka.
Jadi kalau ditanya orang, jawabannya apa?
Kita bisa menjawab dengan 3 level jawaban tergantung siapa yang bertanya:
-
Jawaban Singkat (Untuk Orang Awam/Manajemen):
"Kita pakai sistem Edge Server Cluster. Jadi ada 3 server yang saling backup secara real-time. Kalau satu rusak, sistem face recognition tetap jalan tanpa putus."
-
Jawaban Teknis (Untuk IT/Developer):
"Arsitekturnya Active-Active Edge Cluster dengan 3 node. Databasenya pakai MariaDB Galera Multi-Master dan file sync-nya pakai P2P Mesh (Syncthing)."
-
Jawaban Arsitek (Advance):
"Ini adalah Decentralized Shared-Nothing Architecture yang berjalan di Edge, memanfaatkan synchronous replication untuk database dan eventual consistency untuk file storage."
Apakah ini sama dengan Cloud?
Bukan. Ini justru kebalikannya Cloud.
-
Cloud: Centralized (Terpusat di satu data center raksasa).
-
Edge (Punyamu): Decentralized (Tersebar di lokasi user).
Sistem yang dibangun ini sangat valid dan modern. Banyak perusahaan IoT dan Smart City beralih ke arsitektur ini karena Cloud terlalu lambat untuk absensi wajah real-time.
Kesimpulan
Dengan modal 3 VM Ubuntu, MariaDB, dan Syncthing, kita berhasil membuat infrastruktur yang:
-
Active-Active: Semua server bisa menerima trafik.
-
Redundant: Satu mati, sistem tetap jalan.
-
Self-Healing: Otomatis sinkron saat server pulih.
Skema ini sangat cocok untuk kasus seperti Face Recognition di banyak titik lokasi, atau aplikasi IoT.
Selamat mencoba di lab masing-masing! Jangan lupa siapin kopi biar makin enjoy.

Comments