Bali, Indonesia
Insights

Jejak Memory Buffer TCP dan Redo Log Sync Batam-Singapura Saat RTT Turun ke Sub-2ms

October 14, 2026
0:00
Kabar landing-nya kabel laut Nongsa-Changi Cable (NCC) sepanjang 50 kilometer yang menghubungkan Batam dan Singapura memicu antusiasme besar di kalangan pengelola infrastruktur kawasan. Menghubungkan koridor data center Nongsa Digital Park langsung ke Changi dengan kapasitas agregat melampaui 1.6 Pbps dan latensi round-trip time (RTT) di bawah 2 milidetik—sebagaimana dilaporkan Xinhua—membuka pintu yang selama ini dianggap mustahil: replikasi sinkron (synchronous replication) lintas yurisdiksi negara dengan RPO (Recovery Point Objective) absolut nol. Namun, memindahkan topologi database dari model asinkron Batam-ke-Singapura menjadi synchronous multi-AZ melintasi selat sempit bukan sekadar membalik konfigurasi synchronous_commit = on atau mengaktifkan semi-sync replication. Ketika RTT anjlok dari kisaran 12-18ms (jalur darat-laut memutar via Jakarta/Johor) ke angka sub-2ms murni lewat fiber langsung, karakteristik TCP stack Linux mengalami disonansi drastis terhadap ekspektasi storage engine.
Dalam lanskap jaringan konvensional, Bandwidth-Delay Product (BDP) menentukan berapa banyak paket in-flight yang dapat ditampung kabel tanpa mengalami packet drop. Perhitungannya sederhana: BDP = Bandwidth × RTT. Di atas link 40 Gbps dengan RTT 1.8ms, BDP teoritis kita berada di sekitar 9 megabyte. Angka ini terlihat sangat ramah untuk memory footprint server modern. Namun, masalahnya bukan terletak pada volume BDP teoritis, melainkan bagaimana Linux kernel mengalokasikan memori saat terjadi fluktuasi commit rate yang eksplosif. Secara default, subsistem jaringan Linux mengandalkan autotuning socket buffer (tcp_moderate_rcvbuf). Ketika aplikasi basis data mendorong burst transaksi berukuran besar—misalnya bulk insert atau batch commit yang harus di-replicate ke replica node di Changi—TCP sender melihat saluran yang amat sangat lapang dengan ACK yang datang secepat kilat. TCP congestion window (snd_cwnd) membesar dengan cepat. Tetapi ketika storage I/O di sisi node penerima mengalami micro-stall sesaat (misalnya saat NVMe write cache flushing atau checkpointing), receive buffer (tcp_rmem) dipaksa membesar untuk menampung paket yang meluncur deras. Di Linux, memori socket buffer tidak hanya memakan payload mentah. Setiap segmen TCP dibungkus oleh struktur kernel struct sk_buff (skb) ditambah alokasi data buffer di slab allocator. Overhead metadata ini bisa memakan rasio 2:1 hingga 3:1 terhadap payload riil. Jika ratusan koneksi worker PostgreSQL atau thread replikasi MySQL aktif serempak, alokasi memori di kernel slab (kmalloc-512 dan kmalloc-2048) melesat dalam hitungan ratusan milidetik. Fenomena memory bloat ini kerap memicu intervensi OOM killer terhadap proses background lain yang berbagi host node.
Ketika latensi jaringan melorot di bawah 2ms, hambatan replikasi berpindah secara brutal dari network flight time ke disk commit queue. Dalam synchronous redo log replication, alurnya berantai: thread writer di primary node mengirim payload WAL/redo log ke standby node via TCP socket, standby node menulis payload tersebut ke disk lokal melalui fsync(), lalu mengirim ACK balik ke primary. Primary hanya boleh merespons COMMIT ke klien setelah ACK ini mendarat.
TEXT
Primary Engine         Kernel TCP Tx             Kabel NCC (Sub-2ms)           Kernel TCP Rx         Standby NVMe
[ WAL Writer ]  --->  [ sk_stream_wait ]  --->  =====================>  --->  [ Socket Buffer ] ---> [ fdatasync() ]
      |                      |                                                      |                    |
      +------ Blocking <-----+------------------ ACK Redo Log <---------------------+-------- Micro-stall +
Saat link fisik berkecepatan puluhan gigabit per detik dengan sub-2ms RTT, antrean soket terisi jauh lebih cepat daripada latensi p99 fdatasync() NVMe storage di node tujuan. Jika media penyimpanan di Batam atau Singapura mengalami lonjakan p99 flush latency hingga 5ms akibat tail latency SSD, TCP receive window di kernel akan langsung menyusut (zero-window advertisement). Ketika receive window menyusut, sisi pengirim (sender) akan membekukan socket buffer. Thread pengirim WAL di primary node langsung terjerembap ke state TASK_UNINTERRUPTIBLE (D-state) di dalam kernel function sk_stream_wait_memory. Akibatnya, seluruh transaksi tulis di primary node mendadak mengalami stall berantai. Kecepatan sub-2ms justru memperpendek fase isolasi kegagalan: anomali storage di satu sisi langsung merambatkan backpressure instan ke sisi seberang tanpa ada bantalan network latency yang memadai.
Untuk mengoperasikan synchronous cluster melintasi kabel laut ultra-low latency NCC tanpa mengorbankan stabilitas memori kernel, default konfigurasi TCP Linux harus diikat lebih ketat. Kita tidak ingin autotuning kernel mengizinkan satu socket replikasi mengembang tanpa batas hingga puluhan megabyte hanya karena mendeteksi pipa 40GbE/100GbE yang kosong. Batasi batas maksimum receive dan transmit memory di /etc/sysctl.conf agar kernel menolak alokasi skb yang tidak proporsional terhadap kebutuhan throughput realistis redo log:
BASH
# Membatasi buffer TCP maksimum agar tidak terjadi slab bloat liar
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 65536 4194304

# Mematikan tcp_slow_start_after_idle untuk mempertahankan window stabil
net.ipv4.tcp_slow_start_after_idle = 0

# Gunakan algoritma BBRv2 atau BBRv3 untuk mencegah antrean buffer berlebih
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Nilai 4MB (4194304) pada batas atas tcp_wmem dan tcp_rmem sudah lebih dari cukup untuk memenuhi BDP link sub-2ms Batam-Singapura pada kecepatan multi-gigabit tanpa membiarkan socket buffer menumpuk tak terkontrol saat downstream storage melambat. Penggunaan queue discipline fq (Fair Queueing) yang dipasangkan dengan algoritma congestion control BBR memastikan transmisi data dipecah secara halus (pacing), alih-alih disemburkan dalam bentuk microburst packet clumps yang sering membuat ring buffer NIC kehabisan deskriptor. Di level storage engine, isolasi thread WAL flusher menjadi krusial. Alih-alih mengandalkan single-threaded replication worker, pastikan database membagi beban flushing dan network dispatching. Jika beban kerja dibatasi di dalam container atau slice systemd, pastikan memory limit memperhitungkan kernel memory usage melalui cgroups v2, karena overhead alokasi sk_buff di kernel accounting modern kini dibebankan langsung ke memory cgroup milik proses pemilik soket tersebut. Kabel laut Nongsa-Changi membuktikan bahwa batas fisik antarnegara dapat dipangkas hingga mendekati karakteristik latensi intra-datacenter. Namun, menyatukan dua wilayah komputasi menjadi satu cluster konsisten membutuhkan pemahaman mendalam: latensi jaringan yang semakin tipis menuntut toleransi I/O yang semakin presisi, di mana setiap milidetik kelambatan storage akan langsung tercermin menjadi lonjakan konsumsi memori kernel di kedua ujung kabel." ], "uncoveredConcepts": [ { "concept": "sk_buff kernel allocation lifecycle", "suggestedTitle": "Menelusuri Alokasi sk_buff di Linux Kernel: Dari Ring Buffer NIC Hingga Slab Memory", "tag": "Linux Kernel" }, { "concept": "PostgreSQL synchronous_commit internals", "suggestedTitle": "Membedah synchronous_commit PostgreSQL: Trade-off Latensi fsync dan RPO Nol", "tag": "Database" }, { "concept": "BBR TCP pacing mechanics", "suggestedTitle": "Mengapa Fair Queueing dan BBR Pacing Menghentikan Microburst Packet Loss", "tag": "Networking" } ] }