Bagaimana pengaturan default Linux TCP ini diputuskan?

13

Saya menghabiskan beberapa waktu untuk melacak masalah dalam produksi baru-baru ini, di mana server database menghilang akan menyebabkan hang hingga 2 jam (lama menunggu poll()panggilan di perpustakaan klien libpq) untuk klien yang terhubung. Menggali masalah, saya menyadari bahwa parameter kernel ini harus disesuaikan agar koneksi TCP terputus agar diperhatikan secara tepat waktu:

net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_probes = 9 net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_retries2 = 15

Keempat nilai di atas berasal dari mesin Ubuntu 12.04, dan sepertinya default ini tidak berubah dari default kernel Linux saat ini .

Pengaturan ini tampaknya sangat bias menjaga koneksi yang ada terbuka, dan menjadi sangat pelit dengan probe keepalive. AIUI, standarnyatcp_keepalive_time 2 jam berarti ketika kami menunggu respons untuk host jarak jauh, kami akan menunggu dengan sabar selama 2 jam sebelum memulai penyelidikan keepalive untuk memverifikasi koneksi kami masih valid. Dan kemudian, jika host jarak jauh tidak menanggapi probe keepalive, kami coba lagi probe keepalive tersebut 9 kali ( tcp_keepalive_probes), berjarak 75 detik terpisah ( tcp_keepalive_intvl), jadi itu tambahan 11 menit sebelum kami memutuskan koneksi benar-benar mati.

Ini cocok dengan apa yang saya lihat di lapangan: misalnya, jika saya memulai psqlsesi yang terhubung dengan instance PostgreSQL jarak jauh, dengan beberapa permintaan menunggu jawaban, misalnya

SELECT pg_sleep(30);

dan kemudian memiliki server jauh mati dengan kematian yang mengerikan (misalnya, drop traffic ke mesin itu), saya melihat sesi psql saya menunggu hingga 2 jam dan 11 menit sebelum menemukan koneksi yang mati. Seperti yang Anda bayangkan, pengaturan default ini menyebabkan masalah serius untuk kode yang kita bicarakan dengan basis data selama, katakanlah, peristiwa kegagalan basis data. Mengecilkan tombol-tombol ini sangat membantu! Dan saya melihat bahwa saya tidak sendirian dalam merekomendasikan default ini disesuaikan.

Jadi pertanyaan saya adalah:

  • Berapa lama standarnya seperti ini?
  • Apa dasar pemikiran asli untuk menjadikan pengaturan TCP ini sebagai default?
  • Apakah ada distro Linux yang mengubah nilai default ini?

Dan setiap sejarah atau perspektif lain tentang alasan pengaturan ini akan dihargai.

Josh Kupershmidt
sumber
Beberapa info yang relevan di sini ... tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html
Drav Sloan
Perhatikan bahwa Anda dapat mengubah tiga pertama per-koneksi dalam kode klien dengan pilihan socket TCP_KEEPIDLE, TCP_KEEPCNTdan TCP_KEEPINTVL.
Berkumandang
1
@wnoise sebenarnya sejak Linux 2.6.37 juga dimungkinkan untuk menentukan opsi soket TCP_USER_TIMEOUT, alih-alih mengatur seluruh net.ipv4.tcp_retries2sistem. Tentu saja banyak aplikasi (seperti PostgreSQL dalam contoh saya di sini) belum mendukung TCP_USER_TIMEOUT.
Josh Kupershmidt

Jawaban:

6

RFC 1122 menentukan dalam bagian 4.2.3.6 bahwa periode keep-live tidak boleh default kurang dari dua jam.

Wnoise
sumber
1
Bagus, terima kasih telah menggali itu. Saya pikir sebagian besar menjawab pertanyaan mengapa tcp_keepalive_timedefault ke 7200, meskipun saya masih tertarik pada preseden / penjelasan untuk tiga pengaturan yang relevan lainnya.
Josh Kupershmidt
Menghapus jawaban saya karena ini menjawab pertanyaan (setidaknya untuk salah satu nilai)
coteyr
1
@coteyr Terima kasih, saya menghargai upaya ini. IIRC ada komentar menarik pada jawaban Anda yang menunjukkan bahwa pada kernel Linux sebelumnya, standarnya adalah 15 menit. Saya akan tertarik pada bagaimana / mengapa itu berubah menjadi 2 jam, atau diatur ke 15 menit di tempat pertama.
Josh Kupershmidt