Apa itu algoritma Nagle dan bagaimana pengaruhnya terhadap game online?

Pembaruan terakhir: 27/02/2026
Pengarang: Daniel Terrasa

  • Algoritma Nagle mengurangi tinygram dengan membatasinya pada segmen kecil tanpa ACK per koneksi, sehingga meningkatkan efisiensi pada jaringan yang lambat tetapi menambah latensi.
  • Interaksinya dengan ACK yang tertunda dapat menimbulkan jeda hingga 500 ms dalam pola tulis-tulis-baca dan protokol permintaan-respons.
  • TCP_NODELAY dan TCP_QUICKACK memungkinkan Anda untuk menonaktifkan Nagle dan/atau Delayed ACK untuk memprioritaskan latensi dalam aplikasi interaktif dan sistem terdistribusi modern.
  • Keputusan untuk menggunakan Nagle atau tidak harus didasarkan pada pola lalu lintas aktual: throughput besar versus latensi satu arah yang kritis.
algoritma nagle

Saat bekerja dengan jaringan, soket, atau sekadar bergelut dengan latensi aplikasi TCP, cepat atau lambat Anda akan menemui masalah yang terkenal itu. Algoritma Nagle (Algoritma NagleIni adalah salah satu mekanisme dalam tumpukan TCP/IP yang hampir tidak pernah kita konfigurasi secara manual di awal, tetapi hal ini dapat membuat perbedaan antara aplikasi yang berjalan lancar dan aplikasi yang berjalan "tersendat-sendat" dengan penundaan misterius hingga ratusan milidetik.

Dalam artikel ini, kita akan dengan tenang menguraikan apa itu algoritma Nagle, masalah apa yang ingin dipecahkannya pada tahun 80-an, dan bagaimana algoritma ini berpadu (terkadang berakibat fatal) dengan mekanisme ACK yang tertunda. Kapan waktu yang tepat untuk mematikannya? Kita akan membahas TCP_NODELAY dan opsi yang tersedia di sistem operasi utama untuk menyesuaikan perilakunya. Semuanya dijelaskan dengan sederhana.

Apa itu algoritma Nagle dan masalah apa yang coba dipecahkannya?

Algoritma Nagle muncul dari kebutuhan yang sangat spesifik: hindari banjir paket-paket kecil (tinygrams) Hal itu membebani jaringan lambat pada masa-masa awal TCP. Bayangkan aplikasi terminal interaktif, di mana setiap penekanan tombol mengirimkan satu byte: untuk setiap karakter, 1 byte yang dapat digunakan dikirim ditambah 20 byte header TCP dan 20 byte header IP. Artinya, total 41 byte, di mana hanya 1 byte yang benar-benar data: overhead sebesar 4000%, suatu hal yang sangat tidak masuk akal jika diulang ribuan kali.

John Nagle mengusulkan solusi yang “sederhana dan elegan”: selama ada Data dikirim tanpa konfirmasi (tanpa ACK) Dalam koneksi TCP, pengirim harus menahan diri dan tidak terus-menerus mengirimkan segmen-segmen kecil baru. Dengan cara ini, alih-alih mengirimkan paket-paket kecil satu demi satu, sistem menunggu ACK tiba atau data terkumpul lebih banyak, sehingga segmen yang lebih besar dan lebih efisien dapat dibentuk.

Sederhananya, idenya adalah bahwa koneksi TCP hanya dapat memiliki satu segmen kecil yang belum terkonfirmasi dalam perjalanan. Fragmen-fragmen kecil yang tersisa yang dihasilkan oleh aplikasi tetap berada di buffer soket hingga segmen kecil yang tertunda menerima pengakuannya, pada saat itu sistem mengemas data yang terkumpul ke dalam segmen yang lebih besar dan mengirimkannya sekaligus.

Logika ini membuat algoritma agak adaptif: semakin lambat jaringan atau semakin besar latensi, semakin lama waktu yang dibutuhkan ACK untuk kembali dan semakin banyak data yang dikelompokkan dalam setiap segmen. Pada tautan WAN dengan latensi tinggi dan bandwidth yang relatif terbatas, ini sangat berharga untuk meningkatkan kinerja. efisiensi lalu lintas secara keseluruhan.

Algoritma Nagle

Definisi formal dan fungsi internal

Spesifikasi asli algoritma Nagle, yang terdapat dalam RFC 896 tentang pengendalian kemacetan di jaringan IP/TCP, merangkum perilakunya sebagai berikut: algoritma tersebut seharusnya menghambat pengiriman segmen TCP baru Ketika data tiba dari aplikasi, sistem akan memeriksa apakah ada data yang telah dikirim sebelumnya yang belum dikenali. Berdasarkan definisi ini, banyak implementasi mengekspresikannya dalam pseudocode.

Secara praktis, logika untuk setiap koneksi TCP dapat dirumuskan sebagai berikut: jika data baru tiba dan jendela pengiriman Jika jumlah data yang belum diakui lebih besar dari atau sama dengan MSS, dan terdapat setidaknya MSS byte dalam buffer, segmen MSS ukuran penuh akan segera dikirim. Jika kondisi ini tidak terpenuhi, tetapi masih ada data yang belum diakui "dalam pipeline," data baru ini akan dimasukkan ke dalam antrian dan akan ditunggu ACK. Ketika tidak ada data yang belum diakui, data baru apa pun yang diterima dari aplikasi akan segera dikirim.

Pada akhirnya, yang terpenting adalah hubungan antara MSS (Ukuran Segmen Maksimum)Ukuran jendela dan volume data yang secara bertahap dikeluarkan oleh aplikasi merupakan faktor kunci. Jika alur aplikasi sangat granular (banyak penulisan kecil), Nagle bertindak sebagai "corong" dan mengelompokkan data; jika volumenya lebih besar, dampaknya berkurang dan algoritma menjadi kurang mengganggu.

Beberapa deskripsi yang lebih modern menambahkan nuansa kecil, seperti memicu pengiriman juga ketika data yang terkumpul mencapai setengah ukuran jendela atau melebihi MSS, tetapi inti dari mekanisme tersebut tetap sama: jangan kirim segmen kecil berikutnya sampai yang sebelumnya dikonfirmasi.

Konten eksklusif - Klik Disini  Kotak Centang Sisipkan Kata

ACK Tertunda: pengakuan yang ditunda untuk mengurangi beban kerja.

Sejalan dengan Nagle, dan sekitar waktu yang sama, optimasi lain diperkenalkan dalam TCP yang sama terkenalnya hingga saat ini: ACK TertundaIde tersebut sangat masuk akal untuk jaringan pada waktu itu: jika Anda baru saja menerima segmen dan akan mengirim data kembali, mengapa tidak menunggu sebentar dan menggunakan paket keluar tersebut untuk "menumpang" pada ACK di header yang sama?

Mekanisme ini didasarkan pada pengatur waktu: setelah menerima data, penerima menyimpan ACK dan menunggu interval singkat (biasanya antara 200 dan 500 ms) untuk melihat apakah ACK tersebut muncul selama waktu tersebut. lalu lintas keluar yang kemudian dapat ditambahkan dengan konfirmasi penerimaan. Jika tidak ada yang diterima, saat penghitung waktu habis, konfirmasi penerimaan (ACK) akan dikirim secara terpisah.

Hasilnya adalah pengurangan jumlah total ACK yang beredar di jaringan, yang menghemat header TCP/IP dan mengurangi beban pada router dan titik akhir. Dalam banyak kasus, terutama dengan protokol interaktif yang menggunakan gema karakter (seperti konfigurasi Telnet tertentu), penerima dapat mengelompokkan beberapa ACK menjadi satu ACK tanpa memengaruhi latensi yang dirasakan.

Namun, teknik ini memiliki kelemahan: penundaan yang disengaja hingga setengah detik Hal ini bisa berakibat fatal bagi aplikasi-aplikasi yang sensitif terhadap waktu. Dan ketika dikombinasikan dengan algoritma Nagle, efek yang tidak diinginkan akan meningkat drastis, menghasilkan kerusakan dan jeda periodik yang sangat sulit didiagnosis pada pandangan pertama.

 

Kombinasi yang dahsyat: Nagle + ACK Tertunda

Masalah praktis utama Nagle tidak muncul dengan sendirinya, melainkan ketika dikombinasikan dengan ACK tertundaKedua fungsi tersebut dirancang secara independen pada awal tahun 80-an, dan menurut Nagle sendiri, kombinasi tersebut "sangat buruk." Tidak ada koordinasi eksplisit di antara keduanya, sehingga mereka dapat terjebak dalam semacam lingkaran tunggu timbal balik.

Bayangkan sebuah aplikasi yang melakukan dua penulisan berturut-turut melalui koneksi TCP dan kemudian pembacaan, menunggu data yang dihasilkan oleh penulisan kedua. Dengan Nagle diaktifkan, setelah segmen kecil pertama, tumpukan TCP tidak akan mengirim paket kecil kedua sampai menerima ACK untuk yang pertama. Tetapi jika penerima menggunakan Delayed ACK, pengakuan tersebut tidak akan dikirim segera; sebaliknya, ia akan menunggu sampai dapat dilampirkan ke paket respons atau sampai timer 200-500 ms berlalu.

Hasilnya adalah hambatan buatan: pengirim tidak mengirim segmen kedua karena sedang menunggu ACK dari segmen pertama, dan penerima tidak mengirim ACK karena sedang menunggu lalu lintas lebih lanjut. Mereka berdua terjebak hingga timer ACK yang tertunda berakhir, sehingga menimbulkan latensi tambahan hingga 500 ms di setiap urutan tersebut.

Pola ini sangat berbahaya dalam protokol-protokol berikut: permintaan-respons non-pipelinisasi, seperti HTTP melalui koneksi persisten ketika permintaan atau respons dibagi menjadi beberapa segmen dan paket terakhir bersifat parsial. Dengan algoritma aslinya, jika penulisan menghasilkan 2n segmen di mana 2 pertamanSegmen pertama berukuran penuh, dan segmen terakhir berukuran kecil; TCP menahan segmen kecil sambil menunggu ACK. Jika penerima juga menunda ACK, segmen kecil akan tertinggal hingga setengah detik.

latensi dalam game

Kapan sebaiknya menonaktifkan Nagle: TCP_NODELAY?

Tumpukan TCP modern sering kali mengekspos opsi soket untuk secara eksplisit menonaktifkan Nagle: yang terkenal Opsi TCP_NODELAYFitur ini telah tersedia sejak 4.2BSD (1983) dan telah diwarisi oleh banyak penerusnya, termasuk sebagian besar sistem Unix, macOS, dan Windows. Di AIX dan Windows, misalnya, Nagle diaktifkan secara default dan dapat dinonaktifkan per soket menggunakan flag ini.

Menonaktifkan algoritma sangat masuk akal ketika prioritas absolutnya adalah... latensi searah Bandwidth rendah dan volume data per pesan yang kecil namun sangat sering. Dalam konteks bermain gameContoh tipikalnya meliputi gim video multipemain waktu nyata, desktop jarak jauh di mana setiap pergerakan mouse harus segera diperhatikan, atau alat interaktif yang mengirimkan penekanan tombol satu per satu, seperti telnet atau rsh.

Dalam lingkungan ini, penundaan ratusan milidetik yang dapat ditimbulkan oleh kombinasi Nagle + Delayed ACK tidak dapat diterima: pengguna jelas merasakan bahwa antarmuka tidak merespons tepat waktu. Oleh karena itu, banyak aplikasi latensi rendah mengaktifkan TCP_NODELAY pada semua koneksi mereka, mengorbankan sebagian efisiensi header sebagai imbalan untuk interaksi yang jauh lebih cepat.

Konten eksklusif - Klik Disini  5 tips untuk pembersih memori gratis

Selain itu, kerangka kerja dan pustaka untuk protokol yang "banyak berkomunikasi", seperti terowongan SSL/TLS tertentu, solusi tipe Citrix, atau sistem yang melakukan banyak pertukaran kontrol singkat, juga umumnya memilih nonaktifkan Nagle secara defaultkarena dalam praktiknya, hal itu justru menimbulkan biaya latensi yang lebih besar daripada penghematan yang mereka dapatkan dari headend.

Namun, untuk lalu lintas data yang besar seperti unduhan HTTP, SOAP, XMLRPC, atau transfer file berukuran besar, di mana throughput menjadi faktor dominan dan biaya setiap header tidak signifikan dibandingkan dengan volume data, mengaktifkan Nagle biasanya tidak menjadi masalah dan, dalam banyak kasus, tidak ada perbedaan yang terlihat saat mematikannya.

Apakah Nagle masih relevan dalam sistem modern?

Jika kita melihat jaringan saat ini, dengan pusat data di mana waktu tempuh pulang pergi (RTT) diukur dalam ratusan mikrodetik atau beberapa milidetik antara wilayah yang berdekatan, pembenaran awal Nagle kehilangan kekuatannya. Memblokir transmisi segmen hingga ACK berikutnya tidak lagi melibatkan penantian beberapa detik, tetapi dapat menjadi hambatan yang tidak perlu ketika setiap mikrodetik sangat berarti.

Selain itu, saat ini jarang sekali aplikasi serius mengirim paket mentah 1-byte. Sebagian besar sistem terdistribusi, basis data, dan layanan backend membangun pesan yang lebih besar, menggunakan TLS (yang menambah bebannya sendiri), dan menserialisasi data dengan JSON, Protobuf, dan turunannya. Masalah mendasar dengan tinygram telah "ditingkatkan" dan sebagian besar dikelola dari... lapisan aplikasiyang biasanya mengelompokkan informasi secara logis sebelum memasukkannya ke dalam soket.

Itulah mengapa banyak insinyur yang merancang layanan latensi rendah di pusat data modern memulai dengan aturan yang sangat pragmatis: untuk lalu lintas kontrol internal mereka, pilihan yang aman adalah selalu mengaktifkan TCP_NODELAY, dan masalah throughput apa pun akan ditangani dengan cara lain. Dengan kata lain, lebih baik mengambil risiko menggunakan beberapa header tambahan daripada memperkenalkan pemblokiran multi-RTT pada titik-titik kritis dalam logika bisnis.

Ini tidak berarti bahwa Nagle sudah tidak lagi berguna, terutama dalam konteks tautan sempit atau sangat berisik (misalnya, SLIP, tautan seluler atau satelit tertentu) di mana setiap paketnya mahal. Namun, hal ini memperkuat gagasan bahwa penggunaannya harus dilakukan dengan bijak: dalam banyak penerapan perusahaan saat ini, pengaturan default yang mengaktifkannya bukanlah pilihan terbaik untuk aplikasi yang berjalan di atasnya.

Argumen tambahan lainnya adalah bahwa rekomendasi Nagle sendiri untuk menghindari perilaku patologis adalah agar aplikasi tidak mengikuti pola tulis-tulis-baca, melainkan tulis-baca-tulis-baca atau tulis-tulis-tulis, mengelompokkan operasi dan mengosongkan buffer hanya jika benar-benar diperlukan. Hal ini memperkuat argumen tersebut. tanggung jawab untuk tidak "menumpahkan" byte ke soket. Idealnya, hal itu seharusnya menjadi tanggung jawab kode pengguna.

Nonaktifkan Delayed ACK: TCP_QUICKACK dan mekanisme lainnya

Cara lain untuk mengatasi masalah kombinasi Nagle + Delayed ACK adalah dengan menangani sisi lainnya: alih-alih menonaktifkan Nagle, nonaktifkan atau kurangi perilaku delayed ACK. Di sini, situasinya lebih kompleks, karena antarmuka sangat bervariasi antar sistem operasi.

Di Linux ada flag tersebut. TCP_QUICKACK Sejak kernel 2.4.4 (2001), ini memungkinkan stack diminta untuk mengenali segmen yang masuk dengan lebih cepat. Mekanisme serupa atau terkait juga ada di Windows, seperti operasi SIO_TCP_SET_ACK_FREQUENCY, dan parameter pencatatan seperti TcpAckFrequency yang, jika diatur ke 1, memaksa pengiriman ACK secara langsung.

Di FreeBSD, perilaku default ACK yang ditangguhkan dikendalikan oleh parameter sysctl. jaringan.net.tcp.pengakuan_tertundayang dapat disesuaikan untuk membuat pengakuan lebih agresif atau lebih longgar sesuai kebutuhan. Namun, di Linux tidak ada saklar global sederhana yang setara: penanganan ACK yang tertunda lebih tertanam dalam logika internal TCP.

Meskipun opsi-opsi ini ada, banyak pengembang sistem terdistribusi menggunakannya dengan hati-hati. Di satu sisi, Benda-benda itu tidak portabel. Kompatibilitas lintas platform mempersulit penulisan kode generik yang mudah dipelihara; lebih jauh lagi, semantiknya terkadang tidak intuitif dan bergantung pada versi kernel. Selain itu, bahkan dengan ACK yang cepat, kernel mungkin masih menahan sementara data yang lebih disukai aplikasi untuk dikirim segera, sehingga akar penyebab masalah tidak dihilangkan.

Karena semua alasan ini, dalam banyak kasus taktik yang lebih disukai adalah lebih langsung: jika prioritasnya adalah setiap panggilan ke write() benar-benar berarti "kirim ini sekarang", kecenderungannya adalah mengaktifkan TCP_NODELAY dan menerima biaya kecil pada header, daripada mencoba mengendalikan perilaku Delayed ACK dengan flag khusus sistem.

Konten eksklusif - Klik Disini  Bagaimana cara menambahkan watermark ke dokumen Word?

Bagaimana cara memutuskan apakah akan mengaktifkan atau menonaktifkan TCP_NODELAY?

Pertanyaan praktis yang besar adalah: kapan sebaiknya Nagle diaktifkan, dan kapan lebih baik menonaktifkannya dengan TCP_NODELAY? Tidak ada aturan universal, tetapi ada beberapa pedoman yang cukup solid berdasarkan jenis lalu lintas dan perilaku yang diamati.

Jika layanan Anda terutama menangani transfer besar Untuk tugas non-interaktif (unduhan file, respons HTTP besar, aliran streaming yang di-buffer dengan baik), prioritasnya biasanya adalah throughput dan efisiensi keseluruhan. Dalam kasus ini, membiarkan Nagle diaktifkan adalah hal yang wajar dan jarang menimbulkan masalah latensi yang signifikan.

Sebaliknya, jika Anda berurusan dengan aplikasi yang sangat interaktif yang mengirim banyak pesan kecil—game online, desktop jarak jauh, Citrix, terowongan SSL tertentu, atau protokol yang membutuhkan banyak jabat tangan singkat—Nagle cenderung menjadi penghalang. Mengaktifkan TCP_NODELAY biasanya menghasilkan peningkatan yang jelas dalam daya tanggap untuk pengguna.

Cara yang lebih analitis untuk melihatnya adalah dengan memasang instrumen pada jaringan dan mengamati statistik seperti jumlah tinygram (paket dengan muatan sangat kecil) dan jumlah penundaan yang disebabkan oleh Nagle. Alat analisis lalu lintas yang mendalam dapat membantu Anda melihat berapa persentase paket Anda yang berukuran sangat kecil dan berapa banyak waktu yang dihabiskan paket tersebut "terjebak" karena mekanisme ini.

Jika, setelah mengamati beberapa saat, Anda melihat banyak tinygram tetapi sedikit penundaan karena Nagle, mungkin ada baiknya untuk tetap mengaktifkannya karena membantu mengurangi penundaan tersebut. Sebaliknya, jika Anda melihat banyak tinygram dan persentase penundaan yang tinggi karena algoritma tersebut, itu adalah tanda jelas bahwa pola lalu lintas Anda tidak memanfaatkan Nagle, dan menonaktifkannya bisa bermanfaat.

Seperti halnya hampir semua hal dalam hal performa, keputusan akhir biasanya membutuhkan beberapa iterasi: menyesuaikan opsi, mengukur, menunggu, meninjau metrik, dan, berdasarkan hasilnya, menyesuaikan lagi. Dan semua ini dengan pemahaman bahwa perpaduan aplikasi pada jaringan berubah seiring waktu, jadi apa yang berhasil hari ini mungkin tidak ideal dalam beberapa bulan mendatang.

Alternatif dan solusi ketika TCP tidak sesuai

Dalam beberapa skenario ekstrem, bahkan menonaktifkan Nagle dan menyesuaikan Delayed ACK pun tidak cukup untuk mencapai latensi yang diinginkan. Jika aplikasi Anda terus-menerus mengirimkan frame yang sangat kecil dan penundaan tambahan apa pun tidak dapat diterima, TCP mungkin bukan protokol transport terbaik untuk Anda.

Dalam kasus ini, banyak pengembang memilih protokol tanpa koneksi seperti UDPDalam lingkungan ini, tidak ada kontrol kemacetan atau jaminan pengiriman, tetapi latensinya minimal dan tidak ada mekanisme seperti Nagle atau ACK tertunda. Namun, semua yang dilakukan TCP untuk Anda—pengiriman ulang, pengurutan, kontrol kehilangan, dll.—harus diimplementasikan pada lapisan aplikasi.

Alternatif lain adalah mendesain ulang protokol aplikasi itu sendiri untuk menghindari pola tulis-tulis-baca yang bermasalah dan mengurangi jumlah minimum pertukaran yang diperlukan untuk menyelesaikan setiap operasi logis. Terkadang, perubahan sederhana dalam cara pesan dikelompokkan dapat menghindari dampak terburuk dari Nagle tanpa mengubah opsi soket.

Di lingkungan perusahaan besar, mereka juga menggunakan penyesuaian pada load balancer dan proxyHal ini memungkinkan Anda untuk mengaktifkan atau menonaktifkan TCP_NODELAY secara dinamis berdasarkan jenis lalu lintas yang terdeteksi, atau mengurangi timer Delayed ACK secara selektif. Pendekatan ini memungkinkan adaptasi perilaku terhadap campuran lalu lintas yang sangat heterogen tanpa memerlukan modifikasi pada semua aplikasi akhir.

Bagaimanapun, sebelum mengeluarkan uang untuk perangkat keras tambahan atau tautan baru, biasanya sangat bermanfaat untuk memeriksa apakah parameter TCP Anda (Nagle, Delayed ACK, ukuran jendela, buffer, dll.) benar-benar sesuai dengan pola penggunaan jaringan Anda yang sebenarnya. Tidak jarang penyesuaian yang dilakukan dengan baik pada lapisan-lapisan ini dapat mencapai peningkatan yang signifikan tanpa mengubah satu kabel pun.

Mengingat semua hal di atas, pemahaman menyeluruh tentang cara kerja algoritma Nagle dan bagaimana algoritma tersebut berinteraksi (atau bekerja dengan baik) dengan Delayed ACK, TCP_NODELAY, dan TCP_QUICKACK hampir wajib jika Anda memperhatikan latensi dan kinerja dalam aplikasi TCP Anda: pada akhirnya, memutuskan apakah akan memprioritaskan efisiensi atau kecepatan dalam setiap kasus adalah hal yang membedakan antara jaringan yang "berjalan dengan sendirinya" dan jaringan yang selalu tampak berjalan dengan rem tangan terpasang.