लिनक्स में टीसीपी / आईपी कनेक्शन की अधिकतम संख्या बढ़ाना


214

मैं एक सर्वर की प्रोग्रामिंग कर रहा हूं और ऐसा लगता है कि मेरे कनेक्शन की संख्या सीमित हो रही है क्योंकि मेरे बैंडविड्थ को तब भी संतृप्त नहीं किया जा रहा है जब मैंने कनेक्शन की संख्या को "असीमित" पर सेट किया है।

मैं अपने उबंटू लिनक्स बॉक्स को एक बार में खोलने वाले अधिकतम कनेक्शनों को कैसे बढ़ा या समाप्त कर सकता हूं? क्या ओएस इसे सीमित करता है, या यह राउटर या आईएसपी है? या यह कुछ और है?


2
@ शेपर बंदर: मैंने इसका जवाब वैसे भी दिया क्योंकि मुझे उम्मीद है कि यह किसी ऐसे व्यक्ति के लिए उपयोगी हो सकता है जो वास्तव में भविष्य में एक सर्वर लिख रहा है।
व्युत्पन्न

1
@derobert: मैंने देखा कि +1। दरअसल, मेरी पिछली टिप्पणी के बाद भी मैंने ऐसा ही सोचा था, लेकिन मुझे लगा कि मैं टिप्पणी को खड़ा कर दूंगा।
लॉरेंस डोल

जवाबों:


396

क्लाइंट और सर्वर दोनों पक्षों पर कुछ सीमाओं के अनुसार अधिकतम संख्या में कनेक्शन प्रभावित होते हैं, भले ही वे कुछ अलग हों।

क्लाइंट की तरफ: एफर्मल पोर्ट रेंज बढ़ाएँ, और घटाएँtcp_fin_timeout

डिफ़ॉल्ट मानों का पता लगाने के लिए:

sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout

इफरमल पोर्ट रेंज एक आउटबाउंड सॉकेट्स की अधिकतम संख्या को परिभाषित करता है जो एक होस्ट एक विशेष आईपी पते से बना सकता है। fin_timeoutकम से कम समय इन सॉकेट में रहेगी परिभाषित करता है TIME_WAITराज्य (एक बार इस्तेमाल किया जा रहा करने के बाद बेकार)। सामान्य प्रणाली चूक हैं:

  • net.ipv4.ip_local_port_range = 32768 61000
  • net.ipv4.tcp_fin_timeout = 60

इसका मूल रूप से मतलब है कि आपका सिस्टम लगातार (61000 - 32768) / 60 = 470प्रति सेकंड सॉकेट से अधिक की गारंटी नहीं दे सकता है । यदि आप इससे खुश नहीं हैं, तो आप शुरुआत को बढ़ा सकते हैं port_range। सीमा तय करना 15000 61000इन दिनों बहुत आम है। आप घटाकर उपलब्धता को और बढ़ा सकते हैं fin_timeout। मान लीजिए कि आप दोनों करते हैं, तो आपको 1500 से अधिक आउटबाउंड कनेक्शन प्रति सेकंड, अधिक आसानी से देखना चाहिए।

मान बदलने के लिए :

sysctl net.ipv4.ip_local_port_range="15000 61000"
sysctl net.ipv4.tcp_fin_timeout=30

उपरोक्त की व्याख्या नहीं की जानी चाहिए क्योंकि प्रति सेकंड आउटबाउंड कनेक्शन बनाने के लिए सिस्टम की क्षमता को प्रभावित करने वाले कारक। लेकिन बल्कि ये कारक "गतिविधि" की बड़ी अवधि के लिए एक स्थायी तरीके से समवर्ती कनेक्शन को संभालने की प्रणाली की क्षमता को प्रभावित करते हैं।

tcp_tw_recycle& के लिए एक विशिष्ट लिनक्स बॉक्स पर डिफ़ॉल्ट Sysctl मान tcp_tw_reuseहोगा

net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0

ये "उपयोग किए गए" सॉकेट (प्रतीक्षा की स्थिति में) से कनेक्शन की अनुमति नहीं देते हैं और सॉकेट्स को पूरा time_waitचक्र चलाने के लिए मजबूर करते हैं । मैं सेटिंग की सलाह देता हूं:

sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1 

यह time_waitराज्य में सॉकेट्स के तेजी से साइकिल चलाने और उन्हें फिर से उपयोग करने की अनुमति देता है। लेकिन इससे पहले कि आप इस परिवर्तन को सुनिश्चित करें कि यह प्रोटोकॉल के साथ संघर्ष नहीं करता है जो आप उस एप्लिकेशन के लिए उपयोग करेंगे जो इन सॉकेट्स की आवश्यकता है। निहितार्थ को समझने के लिए विन्सेंट बर्नट से "टीसीपी टाइम-वाइट के साथ नकल" पोस्ट को पढ़ना सुनिश्चित करें । यह net.ipv4.tcp_tw_recycle विकल्प सार्वजनिक-सामना करने वाले सर्वरों के लिए काफी समस्याग्रस्त है क्योंकि यह एक ही NAT डिवाइस के पीछे दो अलग-अलग कंप्यूटरों से कनेक्शन को संभाल नहीं पाएगा , जिसका पता लगाने और आपको काटने के लिए इंतजार करना एक समस्या है। ध्यान दें कि लिनक्स 4.12 से हटाnet.ipv4.tcp_tw_recycle दिया गया है

सर्वर साइड पर:net.core.somaxconn मूल्य एक महत्वपूर्ण भूमिका है। यह एक सुनने वाले सॉकेट के लिए कतारबद्ध अनुरोधों की अधिकतम संख्या को सीमित करता है। यदि आप अपने सर्वर एप्लिकेशन की क्षमता के बारे में सुनिश्चित हैं, तो इसे 128 से 1024 की तरह डिफ़ॉल्ट 128 से टकराएं। अब आप इस एप्लिकेशन के श्रवण कॉल में सुने बैकलॉग वैरिएबल को एक समान या उच्च पूर्णांक तक संशोधित करके इस लाभ का लाभ उठा सकते हैं।

sysctl net.core.somaxconn=1024

txqueuelenआपके ईथरनेट कार्ड के पैरामीटर की भी भूमिका होती है। डिफ़ॉल्ट मान 1000 हैं, इसलिए उन्हें 5000 या उससे अधिक तक टक्कर दें यदि आपका सिस्टम इसे संभाल सकता है।

ifconfig eth0 txqueuelen 5000
echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local

इसी तरह मूल्यों के लिए टकराओ net.core.netdev_max_backlogऔर net.ipv4.tcp_max_syn_backlog। उनके डिफ़ॉल्ट मान क्रमशः 1000 और 1024 हैं।

sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048

अब अपने क्लाइंट और सर्वर साइड एप्लिकेशन को शेल में एफडी अल्सर बढ़ाकर दोनों को शुरू करना याद रखें।

उपरोक्त के अलावा प्रोग्रामर द्वारा उपयोग की जाने वाली एक और लोकप्रिय तकनीक है tcp लिखना कॉल की संख्या को कम करना। मेरी अपनी प्राथमिकता एक बफर का उपयोग करना है जिसमें मैं ग्राहक को भेजने के लिए वांछित डेटा को धक्का देता हूं, और फिर उपयुक्त बिंदुओं पर मैं बफर सॉकेट को वास्तविक सॉकेट में लिखता हूं। यह तकनीक मुझे बड़े डेटा पैकेट का उपयोग करने, विखंडन को कम करने, उपयोगकर्ता भूमि और कर्नेल-स्तर पर मेरे सीपीयू उपयोग को कम करने की अनुमति देती है।


4
शानदार जवाब! मेरी समस्या थोड़ी अलग थी, यानी मैं PHP के माध्यम से एक एप्लिकेशन स्तर सत्र भंडारण से सत्र जानकारी स्थानांतरित करने की कोशिश कर रहा था। किसी कारण से, मैं 28230 से अधिक सत्रों को एक ही बार में बहुत सारी नींद में शामिल किए बिना नहीं जोड़ सकता था, जिसमें कोई भी त्रुटि नहीं थी जो कि php या रेडिस लॉग पर देखी गई थी। हमने एक पूरे दिन के लिए इस पर अपने सिर को तोड़ दिया जब तक मुझे लगा कि शायद समस्या php / redis के साथ नहीं है, लेकिन tcp / ip लेयर में दोनों को जोड़ने और इस जवाब पर आया। उसके बाद कुछ ही समय में इस मुद्दे को ठीक करने के लिए प्रबंधित: :) बहुत बहुत धन्यवाद!
s1d

27
यह न भूलें कि हम हमेशा IP + पोर्ट के बारे में बात कर रहे हैं। XY को कई अलग-अलग IP से पोर्ट करने के लिए आपके पास "असीमित" सॉकेट हो सकते हैं। 470 की सीमा केवल आईपी के लिए खोली गई सॉकेट्स पर लागू होती है। एक और आईपी में समान पोर्ट के लिए अपने स्वयं के 470 कनेक्शन हो सकते हैं।
मर्क्य ५५५

6
@ Marki555: आपकी टिप्पणी बहुत सही है। आउटबाउंड कनेक्शनों की एक बड़ी संख्या को उत्पन्न करने और बनाए रखने के लिए विकसित किए गए एप्लिकेशन में आउटबाउंड कनेक्शन बनाने के लिए उपलब्ध आईपी की "जागरूकता" होनी चाहिए, और फिर किसी प्रकार के "राउंड-रॉबिन एल्गोरिथ्म" का उपयोग करके इन आईपी पते के लिए उचित रूप से बाध्य होना चाहिए और बनाए रखना चाहिए। एक "स्कोरबोर्ड"।
mdk

8
इस उत्तर में गलतियाँ हैं। सबसे पहले, net.ipv4.tcp_fin_timeout केवल FIN_WAIT_2 स्थिति ( cs.uwaterloo.ca/~brecht/servers/ip-sysctl.txt ) के लिए है। दूसरे, जैसा कि @ एरिक ने कहा, "किसी भी समय 470 सॉकेट्स" सही नहीं है।
शरवनाथ

3
@mdk: मैं इस गणना भाग के साथ स्पष्ट नहीं हूं (61000 - 32768) / 60 = 470 sockets per second। क्या आप इसे विस्तृत कर सकते हैं?
टॉम टेलर

64

कनेक्शन की अधिकतम संख्या निर्धारित करने के लिए कुछ चर हैं। सबसे अधिक संभावना है, आप पहले फ़ाइल संख्या से बाहर चल रहे हैं। Ulimit -n की जाँच करें। उसके बाद, वहाँ सेटिंग्स / खरीद रहे हैं, लेकिन उन हजारों के लिए डिफ़ॉल्ट।

इससे भी महत्वपूर्ण बात यह है कि ऐसा लगता है कि आप कुछ गलत कर रहे हैं। एक एकल टीसीपी कनेक्शन को दो पक्षों के बीच सभी बैंडविड्थ का उपयोग करने में सक्षम होना चाहिए; अगर यह नहीं है:

  • जांचें कि क्या आपकी टीसीपी विंडो सेटिंग काफी बड़ी है। वास्तव में तेजी से इनसेट लिंक (सैकड़ों mbps) या फास्ट सैटेलाइट लिंक को छोड़कर लिनक्स डिफॉल्ट सब कुछ के लिए अच्छा है। आपका बैंडविड्थ * विलंब उत्पाद क्या है?
  • बड़े पैकेट के साथ पिंग का उपयोग करके पैकेट के नुकसान की जांच करें ( ping -s 1472...)
  • दर सीमित करने के लिए जाँच करें। लिनक्स पर, इसके साथ कॉन्फ़िगर किया गया हैtc
  • पुष्टि करें कि आपके अनुसार बैंडविड्थ वास्तव में मौजूद है जैसे, iperf
  • पुष्टि करें कि आपका प्रोटोकॉल समझदार है। विलंबता याद है।
  • यदि यह एक गीगाबिट + लैन है, तो क्या आप जंबो पैकेट का उपयोग कर सकते हैं? क्या आप?

संभवतः मुझे गलत समझा गया है। हो सकता है कि आप बिटटोरेंट जैसा कुछ कर रहे हों, जहाँ आपको बहुत सारे कनेक्शनों की आवश्यकता हो। यदि हां, तो आप कितने कनेक्शन आप वास्तव में (कोशिश का उपयोग कर रहे यह पता लगाने की जरूरत है netstatया lsof)। यदि वह संख्या पर्याप्त है, तो आप निम्न कर सकते हैं:

  • बहुत सारे बैंडविड्थ हैं, जैसे, 100mbps +। इस मामले में, आपको वास्तव में अप करने की आवश्यकता हो सकती है ulimit -n। फिर भी, ~ 1000 कनेक्शन (मेरे सिस्टम पर डिफ़ॉल्ट) काफी कुछ है।
  • नेटवर्क समस्याएं हैं जो आपके कनेक्शन को धीमा कर रही हैं (जैसे, पैकेट नुकसान)
  • कुछ और आपको धीमा कर रहा है, उदाहरण के लिए, IO बैंडविड्थ, खासकर यदि आप चाहते हैं। क्या आपने जाँच की है iostat -x?

इसके अलावा, यदि आप उपभोक्ता-ग्रेड NAT राउटर (Linksys, Netgear, DLink, आदि) का उपयोग कर रहे हैं, तो सावधान रहें कि आप हजारों क्षमताओं के साथ इसकी क्षमताओं को पार कर सकते हैं।

मुझे उम्मीद है कि इससे कुछ मदद मिलेगी। आप वास्तव में एक नेटवर्किंग सवाल पूछ रहे हैं।


16

Derobert द्वारा दिए गए उत्तर पर सुधार करने के लिए,

आप यह निर्धारित कर सकते हैं कि nf_conntrack_max को पूरा करके आपकी OS कनेक्शन सीमा क्या है।

उदाहरण के लिए: cat / proc / sys / net / netfilter / nf_conntrack_max

Tcp पोर्ट की दी गई श्रेणी के लिए tcp कनेक्शन की संख्या की गणना करने के लिए आप निम्न स्क्रिप्ट का उपयोग कर सकते हैं। डिफ़ॉल्ट रूप से 1-65535।

यह पुष्टि करेगा कि आप अपने OS कनेक्शन की सीमा को अधिकतम कर रहे हैं या नहीं।

यहाँ स्क्रिप्ट है।

#!/bin/bash
OS=$(uname)

case "$OS" in
    'SunOS')
            AWK=/usr/bin/nawk
            ;;
    'Linux')
            AWK=/bin/awk
            ;;
    'AIX')
            AWK=/usr/bin/awk
            ;;
esac

netstat -an | $AWK -v start=1 -v end=65535 ' $NF ~ /TIME_WAIT|ESTABLISHED/ && $4 !~ /127\.0\.0\.1/ {
    if ($1 ~ /\./)
            {sip=$1}
    else {sip=$4}

    if ( sip ~ /:/ )
            {d=2}
    else {d=5}

    split( sip, a, /:|\./ )

    if ( a[d] >= start && a[d] <= end ) {
            ++connections;
            }
    }
    END {print connections}'

3
which awkक्या आपका दोस्त
जागने का

2
@PanagiotisM। whichउस कार्यक्रम पर निर्भर करता PATHहै जिसमें awkपूर्ण पथ प्रदान करने के बजाय आप किस स्थिति में उपयोग कर सकते हैं । (उस ने कहा, मुझे यकीन नहीं है कि अगर स्क्रिप्ट में समाधान पूर्णता के करीब है, लेकिन यह स्क्रिप्ट के बारे में ऐसा नहीं है)।
माइकल क्रेलिन -

5
मुझे पसंद है कि यह स्क्रिप्ट awkस्थान निर्धारण के लिए कैसे बैलिस्टिक हो जाती है, लेकिन मानती है कि शेल हमेशा /bin/bash (प्रो टिप: AIX5 / 6 में डिफ़ॉल्ट रूप से बैश भी नहीं होता है)।
kubanczyk

क्या awkपता लगाना उपयोगी है? व्यक्तिगत रूप से मैं बस एक सही है PATHलेकिन एक उचित विकल्प /usr/bin/env awkऔर /usr/bin/env bashक्रमशः हो सकता है मान जाएगा । जो इसके लायक है, उसके लिए मेरे लिनक्स सिस्टम पर स्थान गलत है। यह /usr/bin/awkनहीं है/bin/awk
वोल्फ

1
जब मैं इस स्क्रिप्ट को चलाता हूं तो मुझे 798 मिलते हैं, तो इसका क्या मतलब है?

10

एक एप्लिकेशन स्तर में, यहां कुछ डेवलपर कर सकते हैं:

सर्वर की ओर से:

  1. जांचें कि क्या लोड बैलेंसर (यदि आपके पास है), सही तरीके से काम करता है।

  2. 503 फास्ट तत्काल प्रतिक्रिया में धीमी टीसीपी टाइमआउट को चालू करें, यदि आप बैलेंसर काम को सही तरीके से लोड करते हैं, तो इसे काम करने के लिए काम करने वाले संसाधन को चुनना चाहिए, और यह अप्रत्याशित त्रुटि मालिश के साथ वहां लटकने से बेहतर है।

उदाहरण: यदि आप नोड सर्वर का उपयोग कर रहे हैं, तो आप npm से toobusy का उपयोग कर सकते हैं। कार्यान्वयन कुछ इस तरह है:

var toobusy = require('toobusy');
app.use(function(req, res, next) {
  if (toobusy()) res.send(503, "I'm busy right now, sorry.");
  else next();
});

क्यों 503? यहां ओवरलोड के लिए कुछ अच्छी जानकारी दी गई है: http://ferd.ca/queues-don-t-fix-overload.html

हम ग्राहक पक्ष में भी कुछ काम कर सकते हैं:

  1. बैच में समूह कॉल करने का प्रयास करें, ट्रैफ़िक और कुल अनुरोध संख्या b / w क्लाइंट और सर्वर को कम करें।

  2. अनावश्यक डुप्लिकेट अनुरोधों को संभालने के लिए कैश मिड-लेयर बनाने का प्रयास करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.