聶永的博客

          記錄工作/學(xué)習(xí)的點點滴滴。

          100萬并發(fā)連接服務(wù)器筆記之1M并發(fā)連接目標(biāo)達成

          第四個遇到的問題:tcp_mem

          在服務(wù)端,連接達到一定數(shù)量,諸如50W時,有些隱藏很深的問題,就不斷的拋出來。 通過查看dmesg命令查看,發(fā)現(xiàn)大量TCP: too many of orphaned sockets錯誤,也很正常,下面到了需要調(diào)整tcp socket參數(shù)的時候了。

          第一個需要調(diào)整的是tcp_rmem,即TCP讀取緩沖區(qū),單位為字節(jié),查看默認(rèn)值

          cat /proc/sys/net/ipv4/tcp_rmem
          4096 87380 4161536
          

          默認(rèn)值為87380 byte ≈ 86K,最小為4096 byte=4K,最大值為4064K。

          第二個需要調(diào)整的是tcp_wmem,發(fā)送緩沖區(qū),單位是字節(jié),默認(rèn)值

          cat /proc/sys/net/ipv4/tcp_wmem
          4096 16384 4161536
          

          解釋同上

          第三個需要調(diào)整的tcp_mem,調(diào)整TCP的內(nèi)存大小,其單位是頁,1頁等于4096字節(jié)。系統(tǒng)默認(rèn)值:

          cat /proc/sys/net/ipv4/tcp_mem
          932448 1243264 1864896
          

          tcp_mem(3個INTEGER變量):low, pressure, high

          • low:當(dāng)TCP使用了低于該值的內(nèi)存頁面數(shù)時,TCP不會考慮釋放內(nèi)存。
          • pressure:當(dāng)TCP使用了超過該值的內(nèi)存頁面數(shù)量時,TCP試圖穩(wěn)定其內(nèi)存使用,進入pressure模式,當(dāng)內(nèi)存消耗低于low值時則退出pressure狀態(tài)。
          • high:允許所有tcp sockets用于排隊緩沖數(shù)據(jù)報的頁面量,當(dāng)內(nèi)存占用超過此值,系統(tǒng)拒絕分配socket,后臺日志輸出“TCP: too many of orphaned sockets”。

          一般情況下這些值是在系統(tǒng)啟動時根據(jù)系統(tǒng)內(nèi)存數(shù)量計算得到的。 根據(jù)當(dāng)前tcp_mem最大內(nèi)存頁面數(shù)是1864896,當(dāng)內(nèi)存為(1864896*4)/1024K=7284.75M時,系統(tǒng)將無法為新的socket連接分配內(nèi)存,即TCP連接將被拒絕。

          實際測試環(huán)境中,據(jù)觀察大概在99萬個連接左右的時候(零頭不算),進程被殺死,觸發(fā)out of socket memory錯誤(dmesg命令查看獲得)。每一個連接大致占用7.5K內(nèi)存(下面給出計算方式),大致可算的此時內(nèi)存占用情況(990000 * 7.5 / 1024K = 7251M)。

          這樣和tcp_mem最大頁面值數(shù)量比較吻合,因此此值也需要修改。

          三個TCP調(diào)整語句為:

          echo "net.ipv4.tcp_mem = 786432 2097152 3145728">> /etc/sysctl.conf
          echo "net.ipv4.tcp_rmem = 4096 4096 16777216">> /etc/sysctl.conf
          echo "net.ipv4.tcp_wmem = 4096 4096 16777216">> /etc/sysctl.conf
          

          備注: 為了節(jié)省內(nèi)存,設(shè)置tcp讀、寫緩沖區(qū)都為4K大小,tcp_mem三個值分別為3G 8G 16G,tcp_rmemtcp_wmem最大值也是16G。

          目標(biāo)達成

          經(jīng)過若干次的嘗試,最終達到目標(biāo),1024000個持久連接。1024000數(shù)字是怎么得來的呢,兩臺物理機器各自發(fā)出64000個請求,兩個配置為6G左右的centos測試端機器(綁定7個橋接或NAT連接)各自發(fā)出640007 = 448000。也就是 1024000 = (64000) + (64000) + (640007) + (64000*7), 共使用了16個網(wǎng)卡(物理網(wǎng)卡+虛擬網(wǎng)卡)。
          終端輸出

          ......
          online user 1023990
          online user 1023991
          online user 1023992
          online user 1023993
          online user 1023994
          online user 1023995
          online user 1023996
          online user 1023997
          online user 1023998
          online user 1023999
          online user 1024000
          

          在線用戶目標(biāo)達到1024000個!

          服務(wù)器狀態(tài)信息

          服務(wù)啟動時內(nèi)存占用:

                           total       used       free     shared    buffers     cached
              Mem:         10442        271      10171          0         22         78
              -/+ buffers/cache:        171      10271
              Swap:         8127          0       8127

          系統(tǒng)達到1024000個連接后的內(nèi)存情況(執(zhí)行三次 free -m 命令,獲取三次結(jié)果):

                           total       used       free     shared    buffers     cached
              Mem:         10442       7781       2661          0         22         78
              -/+ buffers/cache:       7680       2762
              Swap:         8127          0       8127

                           total       used       free     shared    buffers     cached
              Mem:         10442       7793       2649          0         22         78
              -/+ buffers/cache:       7692       2750
              Swap:         8127          0       8127

                           total       used       free     shared    buffers     cached
              Mem:         10442       7804       2638          0         22         79
              -/+ buffers/cache:       7702       2740
              Swap:         8127          0       8127

          這三次內(nèi)存使用分別是7680,7692,7702,這次不取平均值,取一個中等偏上的值,定為7701M。那么程序接收1024000個連接,共消耗了 7701M-171M = 7530M內(nèi)存, 7530M*1024K / 1024000 = 7.53K, 每一個連接消耗內(nèi)存在為7.5K左右,這和在連接達到512000時所計算較為吻合。
          虛擬機運行Centos內(nèi)存占用,不太穩(wěn)定,但一般相差不大,以上數(shù)值,僅供參考。

          執(zhí)行top -p 某刻輸出信息:

              top - 17:23:17 up 18 min,  4 users,  load average: 0.33, 0.12, 0.11
              Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
              Cpu(s):  0.2%us,  6.3%sy,  0.0%ni, 80.2%id,  0.0%wa,  4.5%hi,  8.8%si,  0.0%st
              Mem:  10693580k total,  6479980k used,  4213600k free,    22916k buffers
              Swap:  8323056k total,        0k used,  8323056k free,    80360k cached

                PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                      
               2924 yongboy   20   0 82776  74m  508 R 51.3  0.7   3:53.95 server 

          執(zhí)行vmstate:

          vmstat
          procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
           r b swpd free buff cache si so bi bo in cs us sy id wa st
           0 0 0 2725572 23008 80360 0 0 21 2 1012 894 0 9 89 2 0 

          獲取當(dāng)前socket連接狀態(tài)統(tǒng)計信息:

          cat /proc/net/sockstat
          sockets: used 1024380
          TCP: inuse 1024009 orphan 0 tw 0 alloc 1024014 mem 2
          UDP: inuse 11 mem 1
          UDPLITE: inuse 0
          RAW: inuse 0
          FRAG: inuse 0 memory 0
          

          獲取當(dāng)前系統(tǒng)打開的文件句柄:

          sysctl -a | grep file
          fs.file-nr = 1025216 0 1048576
          fs.file-max = 1048576
          

          此時任何類似于下面查詢操作都是一個慢,等待若干時間還不見得執(zhí)行完畢。

          netstat -nat|grep -i "8000"|grep ESTABLISHED|wc -l 
          netstat -n | grep -i "8000" | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

          以上兩個命令在二三十分鐘過去了,還未執(zhí)行完畢,只好停止。

          小結(jié)

          本次從頭到尾的測試,所需要有的linux系統(tǒng)需要調(diào)整的參數(shù)也就是那么幾個,匯總一下:

              echo "* - nofile 1048576" >> /etc/security/limits.conf

              echo "fs.file-max = 1048576" >> /etc/sysctl.conf
              echo "net.ipv4.ip_local_port_range = 1024 65535" >> /etc/sysctl.conf

              echo "net.ipv4.tcp_mem = 786432 2097152 3145728" >> /etc/sysctl.conf
              echo "net.ipv4.tcp_rmem = 4096 4096 16777216" >> /etc/sysctl.conf
              echo "net.ipv4.tcp_wmem = 4096 4096 16777216" >> /etc/sysctl.conf

          其它沒有調(diào)整的參數(shù),僅僅因為它們暫時對本次測試沒有帶來什么影響,實際環(huán)境中需要結(jié)合需要調(diào)整類似于SO_KEEPALIVE、tcpmax_orphans等大量參數(shù)。

          本文代表一次實踐,不足之處,歡迎批評指正。

          posted on 2013-04-11 09:01 nieyong 閱讀(53100) 評論(9)  編輯  收藏 所屬分類: C1M

          評論

          # re: 100萬并發(fā)連接服務(wù)器筆記之1M并發(fā)連接目標(biāo)達成 2013-04-16 22:55 piboye

          有沒有方法把 發(fā)送緩存區(qū)的 4k去掉, 就不需要每個連接 7.5k, 而只需要2.5k?  回復(fù)  更多評論   

          # re: 100萬并發(fā)連接服務(wù)器筆記之1M并發(fā)連接目標(biāo)達成 2013-04-17 15:49 iriyadays

          socket太多時統(tǒng)計狀態(tài)可以用ss -s  回復(fù)  更多評論   

          # re: 100萬并發(fā)連接服務(wù)器筆記之1M并發(fā)連接目標(biāo)達成 2013-04-28 10:05 nieyong

          @piboye
          正常,發(fā)送和接收都得需要,要不就發(fā)送或接收不了啦。  回復(fù)  更多評論   

          # re: 100萬并發(fā)連接服務(wù)器筆記之1M并發(fā)連接目標(biāo)達成 2013-04-28 10:05 nieyong

          @iriyadays
          十分高效,謝謝~  回復(fù)  更多評論   

          # re: 100萬并發(fā)連接服務(wù)器筆記之1M并發(fā)連接目標(biāo)達成 2013-09-11 23:56 mecoring

          把接收緩沖區(qū)設(shè)置小了,如果請求量太大,而處理較慢的慢,會導(dǎo)致對方無法寫入吧。。。

          把發(fā)送緩沖區(qū)設(shè)置過小,同上。。。  回復(fù)  更多評論   

          # re: 100萬并發(fā)連接服務(wù)器筆記之1M并發(fā)連接目標(biāo)達成 2013-12-16 19:45 肚腩照明月

          echo "net.ipv4.tcp_rmem = 4096 4096 16777216">> /etc/sysctl.conf

          單位是字節(jié) ,那么這個最大是16M吧  不是16G
            回復(fù)  更多評論   

          # re: 100萬并發(fā)連接服務(wù)器筆記之1M并發(fā)連接目標(biāo)達成 2014-02-28 14:10 good90

          默認(rèn)值為87380bit ≈ 86K,最小為4096bit=4K,
          中bit => byte  回復(fù)  更多評論   

          # re: 100萬并發(fā)連接服務(wù)器筆記之1M并發(fā)連接目標(biāo)達成[未登錄] 2014-04-03 19:28 ming

          你們,能寫一下虛擬網(wǎng)卡的配置嗎?
          我實驗的時候所有虛擬網(wǎng)卡創(chuàng)建的總端口數(shù)超不過65536
          謝謝了  回復(fù)  更多評論   

          # re: 100萬并發(fā)連接服務(wù)器筆記之1M并發(fā)連接目標(biāo)達成 2016-07-08 11:27 mammut

          上面 `net.ipv4.tcp_mem` 的三個值 `786432 2097152 3145728` 應(yīng)該分別是 3G 8G 12G~  回復(fù)  更多評論   

          公告

          所有文章皆為原創(chuàng),若轉(zhuǎn)載請標(biāo)明出處,謝謝~

          新浪微博,歡迎關(guān)注:

          導(dǎo)航

          <2013年4月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          統(tǒng)計

          常用鏈接

          留言簿(58)

          隨筆分類(130)

          隨筆檔案(151)

          個人收藏

          最新隨筆

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 鸡西市| 正定县| 北票市| 封开县| 晋州市| 瓮安县| 高陵县| 通许县| 湘西| 宜丰县| 东莞市| 长丰县| 巴中市| 屏东市| 灯塔市| 寿宁县| 平阴县| 张家界市| 保山市| 宣威市| 喜德县| 昭通市| 福清市| 温州市| 阿城市| 托克逊县| 泗阳县| 白银市| 腾冲县| 铜山县| 西城区| 金堂县| 托克托县| 布尔津县| 嵩明县| 三河市| 吴江市| 钟山县| 易门县| 维西| 海门市|