Bu Linux TCP varsayılan ayarlarına nasıl karar verildi?


13

Son zamanlarda, bir veritabanı sunucusu kaybolması poll()bağlı bir istemci için 2 saat ( libpq istemci kitaplığında bir çağrı için uzun süre beklemek) kadar askıya neden üretim, bir sorun izlemek için biraz zaman geçirdim . Sorunu inceleyerek, kopmuş TCP bağlantılarının zamanında fark edilebilmesi için bu çekirdek parametrelerinin aşağı doğru ayarlanması gerektiğini fark ettim:

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

Yukarıdaki dört değer bir Ubuntu 12.04 makinesindendir ve bu varsayılanların geçerli Linux çekirdek varsayılanlarından farklı olduğu görülmektedir .

Bu ayarlar, mevcut bir bağlantıyı açık tutmaya ve tutma probları ile son derece cimri olmaya eğilimli görünüyor. AIUI, varsayılan tcp_keepalive_time2 saat, uzak bir ana bilgisayar için bir yanıt beklediğimiz anlamına gelir, bağlantımızın hala geçerli olduğunu doğrulamak için bir koruma probu başlatmadan önce 2 saat sabırla bekleyeceğiz. Ve sonra, uzak ana makine bir tutma probuna yanıt vermezse, bu tutma problarını 9 kez ( tcp_keepalive_probes), 75 saniye arayla ( tcp_keepalive_intvl) yeniden deneriz , bu yüzden bağlantının gerçekten öldüğüne karar vermeden önce 11 dakika daha fazla olur.

Bu, alanda gördüklerimle eşleşiyor: örneğin, psqluzak bir PostgreSQL örneğine bağlı bir oturum başlatırsam , bazı sorgularda yanıt beklerken

SELECT pg_sleep(30);

ve sonra uzak sunucunun korkunç bir ölümle ölmesini sağlayın (örneğin, o makineye trafik bırakın), psql oturumumun bağlantısının öldüğünü anlamadan önce 2 saat 11 dakika kadar beklediğini görüyorum. Tahmin edebileceğiniz gibi, bu varsayılan ayarlar, bir veritabanı yerine çalışma olayı sırasında bir veritabanıyla konuştuğumuz kod için ciddi sorunlara neden olur. Bu düğmeleri kapatmak çok yardımcı oldu! Ve bu varsayılanların düzeltilmesini tavsiye etmede yalnız olmadığımı görüyorum .

Yani sorularım:

  • Varsayılanlar ne kadar zamandır böyle?
  • Bu TCP ayarlarını varsayılan yapmak için orijinal gerekçe neydi?
  • Herhangi bir Linux dağıtımı bu varsayılan değerleri değiştirir mi?

Ve bu ortamların gerekçesi ile ilgili diğer herhangi bir tarih veya perspektif takdir edilecektir.



Eğer soket seçenekleri ile müşteri kodunun ilk üç başına bağlantıyı değişebileceğini Not TCP_KEEPIDLE, TCP_KEEPCNTve TCP_KEEPINTVL.
wnoise

1
@wnoise aslında Linux 2.6.37'den bu yana sistem genelinde TCP_USER_TIMEOUTayar yapmak yerine soket seçeneğini de belirtmek mümkün olmalıdır net.ipv4.tcp_retries2. Tabii ki birçok uygulama (buradaki örneğimdeki PostgreSQL gibi) TCP_USER_TIMEOUThenüz desteklemiyor .
Josh Kupershmidt

Yanıtlar:


6

RFC 1122 , bölüm 4.2.3.6'da canlı tutma süresinin varsayılan olarak iki saatten az olmaması gerektiğini belirtir.


1
Güzel, kazdığın için teşekkürler. tcp_keepalive_timeDiğer 72 ayar için emsal / açıklama ile ilgilenmeye devam etsem de, çoğunlukla neden 7200'e neden olduğu sorusuna cevap verdiğini düşünüyorum .
Josh Kupershmidt

Bu soruya cevap olarak cevabımı kaldırmak (en azından değerlerden biri için)
coteyr

1
@coteyr Yine de teşekkürler, çabayı takdir ediyorum. IIRC, daha önceki Linux çekirdeklerinde varsayılanın 15 dakika olduğunu gösteren cevabınızla ilgili ilginç bir yorum vardı. Bunun nasıl / neden 2 saate değiştirildiğini veya ilk etapta 15 dakikaya ayarlandığını merak ediyorum.
Josh Kupershmidt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.