1. 程式人生 > >系統技術非業餘研究 » 網路棧記憶體不足引發程序掛起問題

系統技術非業餘研究 » 網路棧記憶體不足引發程序掛起問題

我們知道TCP socket有傳送緩衝區和接收緩衝區,這二個緩衝區都可以透過setsockopt設定SO_SNDBUF,SO_RCVBUF來修改,但是這些值設多大呢?這些值和協議棧的記憶體控制相關的值什麼關係呢?
我們來解釋下:

$ sysctl net|grep mem
net.core.wmem_max = 131071
net.core.rmem_max = 131071
net.core.wmem_default = 124928
net.core.rmem_default = 124928
net.core.optmem_max = 20480
net.ipv4.igmp_max_memberships = 20
net.ipv4.tcp_mem = 4631520 6175360 9263040
net.ipv4.tcp_wmem = 4096 16384 4194304
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.udp_mem = 4631520 6175360 9263040
net.ipv4.udp_rmem_min = 4096
net.ipv4.udp_wmem_min = 4096

下面的圖很好的解釋了上面的問題:

socket_mem

這裡要記住的是:TCP協議棧記憶體是不可交換實體記憶體,用一位元組少一位元組。
也正是由於這一點,作業系統出廠的時候上面的預設的記憶體設定都不算太大。對於一個不是網路密集型的伺服器問題不大,但是對於如承擔C1M連結的伺服器來講,問題就來了。我們在實踐中會發現tcp服務經常超時,有時候超過100ms. 那麼這個問題如何定位呢?

我們知道當協議棧缺少記憶體的時候會呼叫sk_stream_wait_memory等待其他程序釋放出記憶體,所以這個函式的等待時間就是我們的程序被阻塞的時間。
下面我們來驗證下:

$ cat /usr/share/doc/systemtap-1.6/examples/network/sk_stream_wait_memory.stp
#!/usr/bin/stap
# Simple probe to detect when a process is waiting for more socket send
# buffer memory. Usually means the process is doing writes larger than the
# socket send buffer size or there is a slow receiver at the other side.
# Increasing the socket's send buffer size might help decrease application
# latencies, but it might also make it worse, so buyer beware.
#
# Typical output: timestamp in microseconds: procname(pid) event
#
# 1218230114875167: python(17631) blocked on full send buffer
# 1218230114876196: python(17631) recovered from full send buffer
# 1218230114876271: python(17631) blocked on full send buffer
# 1218230114876479: python(17631) recovered from full send buffer

probe kernel.function("sk_stream_wait_memory")
{
        printf("%u: %s(%d) blocked on full send buffer\n",
                gettimeofday_us(), execname(), pid())
}

probe kernel.function("sk_stream_wait_memory").return
{
        printf("%u: %s(%d) recovered from full send buffer\n",
                gettimeofday_us(), execname(), pid())
}
$ sudo stap sk_stream_wait_memory.stp  
1218230114875167: python(17631) blocked on full send buffer
1218230114876196: python(17631) recovered from full send buffer
1218230114876271: python(17631) blocked on full send buffer
1218230114876479: python(17631) recovered from full send buffer

如果我們觀察到了程序由於缺少記憶體被阻塞,那麼是時候調整協議棧的記憶體限制了。

小結:網路很複雜,需要定量分析!

祝玩得開心。

Post Footer automatically generated by wp-posturl plugin for wordpress.

相關推薦

系統技術業餘研究 » 網路記憶體不足引發程序問題

我們知道TCP socket有傳送緩衝區和接收緩衝區,這二個緩衝區都可以透過setsockopt設定SO_SNDBUF,SO_RCVBUF來修改,但是這些值設多大呢?這些值和協議棧的記憶體控制相關的值什麼關係呢? 我們來解釋下: $ sysctl net|grep mem net.core.wme

系統技術業餘研究 » Linux快取記憶體使用率調查

Linux的快取記憶體pagecache對效能的影響至關重要,但是實際系統中我們的利用率如何呢,特別是具體到每個裝置的利用情況。 從下圖我們可以很清楚的看到: 我們知道IO請求由vfs發起,經過pagecache快取,擋不住的就落實到io裝置去,那麼統計這個利用率就很簡單。 我們只要知道擋不住的

系統技術業餘研究 » Linux Used記憶體到底哪裡去了?

前幾天 純上 同學問了一個問題: 我ps aux看到的RSS記憶體只有不到30M,但是free看到記憶體卻已經使用了7,8G了,已經開始swap了,請問ps aux的實際實體記憶體統計是不是漏了哪些記憶體沒算?我有什麼辦法確定free中used的記憶體都去哪兒了呢? 這個問題不止一個同學遇到過了

系統技術業餘研究 » iotop統計linux下per程序的IO活動

Linux下的IO統計工具如iostat, nmon等大多數是隻能統計到per裝置的讀寫情況, 如果你想知道每個程序是如何使用IO的就比較麻煩. 當然如果你會systemtap, 或者blktrace這些事情難不到你, 但是沒專用工具總不是很舒服的. 幸運的是Linux 2.6.20核心以後提供了

系統技術業餘研究 » dropwatch 網路協議丟包檢查利器

在做網路伺服器的時候,會碰到各種各樣的網路問題比如說網路超時,通常一般的開發人員對於這種問題最常用的工具當然是tcpdump或者更先進的wireshark來進行抓包分析。通常這個工具能解決大部分的問題,但是比如說wireshark發現丟包,那深層次的原因就很難解釋了。這不怪開發人員,要怪就怪lin

系統技術業餘研究 » Erlang R15的記憶體delayed dealloc特性對訊息密集型程式的影響

在新的NUMA體系結構下,每個CPU都有自己的本地記憶體,如果要訪問其他CPU的記憶體,那算remote了,要走CPU之間的QPI通道,通常這樣速度會有40%的下降。 那麼對於多執行緒的程式來講,這個硬體的變化對軟體也有很大的影響。在多執行緒程式裡面,通常一個執行緒會為一個物件分配記憶體,然後把這

系統技術業餘研究 » gcc mudflap 用來檢測記憶體越界的問題

我們用C語言在做大型伺服器程式的時候,不可避免的要面對記憶體錯誤的問題。典型的問題是記憶體洩漏,越界,隨機亂寫等問題。 在linux下valgrind是個很好的工具,大部分問題都可以查的到的。但是對於更微妙的越界問題,valgrind有時候也是無能為力的。比如下面的問題。 [[email

系統技術業餘研究 » Linux系統記憶體相關資訊獲取

大型的伺服器,特別是資料庫伺服器的主要瓶頸主要在記憶體,CPU,以及IO上。CPU是可再生資源,不夠用等等就有了;記憶體和土地一樣是不可再生資源,被佔用了,後續的使用必須等到該資源釋放.而IO也非常依賴於記憶體的使用情況,故記憶體的倒騰效率會大大影響伺服器的效率,那麼瞭解伺服器記憶體的使用情況就非

系統技術業餘研究 » Erlang 網路密集型伺服器的瓶頸和解決思路

最近我們的Erlang IO密集型的伺服器程式要做細緻的效能提升,從每秒40萬包處理提升到60萬目標,需要對程序和IO排程器的原理很熟悉,並且對行為進行微調,花了不少時間參閱了相關的文件和程式碼。 其中最有價值的二篇文章是: 1. Characterizing the Scalability of

系統技術業餘研究 » erlsnoop erlang訊息監聽器(除錯erlang網路程式利器,支援最新的R13B04)

由於R13B以後, Erlang的分佈協議修改了格式, 添加了Atom Cache, erlsnoop在新版本下無法使用, 我特地打了patch, 使得它支援最新的版本,原始碼在附件中下載. 在erlang的郵件列表上看到: Have you tried putting a snoop to se

系統技術業餘研究 » Erlang網路程序模型的實驗

在做網路程式的時候我們會經常用到多程序模式. 主程序執行bind呼叫得到控制代碼後, 同時fork N個子程序, 把控制代碼傳遞給子程序, 多程序同時accept來處理. 這個模型在erlang下很有現實意義的. 在之前的測試中,我們演示了erlang的單處理器模式的威力,最多的時候在單cpu上可

系統技術業餘研究 » R13B03 binary vheap有助減少binary記憶體壓力

R13B03 binary vheap有助減少binary記憶體壓力. OTP-8202 A new garbage collecting strategy for binaries which is more aggressive than the previous implementati

系統技術業餘研究 » blktrace未公開選項網路儲存擷取資料

我們透過blktrace來觀察io行為的時候,第一件事情需要選擇目標裝置,以便分析該裝置的io行為。具體使用可以參考我之前寫的幾篇:這裡 這裡 這裡 blktrace分為核心部分和應用部分,應用部分收到我們要捕捉的裝置名單,傳給核心。核心分佈在block層的各個tracepoint就會開始工作,把

系統技術業餘研究 » 調研核心呼叫方便的工具 kmalloc

我們在研究核心的時候,看了核心程式碼後,就想著某個函式被誰誰呼叫。 呼叫路徑有很多條,有熱門的,有偏門的,但從程式碼不大容易看出。 如果我們能和gdb那樣在函式上設個斷點,看下核心函式的呼叫棧就清楚了。 但是如何統計熱門路線呢?用systemtap就可以,參看這裡, 這裡。 但是用systemt

系統技術業餘研究 » Linux IO協議框圖

這張圖很清晰的把linux IO協議棧的層次給勾出來了,而且內容很與時俱進,特別是SCSI裝置的層次對大家理解sg3這樣的包非常有幫助,強烈推薦大家好好研習! 祝玩得開心! Post Footer automatically generated by wp-posturl plugin fo

系統技術業餘研究 » 巧用Netcat方便網路程式開發

首先介紹下NC,這個號稱網路瑞士軍刀的工具。 What is Netcat? Netcat is a featured networking utility which reads and writes data across network connections, using the TC

系統技術業餘研究 » systemtap函式呼叫資訊不齊的原因和解決方法

有時候在看系統程式碼的時候,我們很難從原始碼中看出我們感興趣的函式是如何被呼叫的,因為呼叫路徑有可能太多。使用者空間的程式gdb設斷點是個好的方法,核心的就麻煩了。這時候systemtap可以幫忙, 比如: $uname -r 2.6.18-164.el5 $stap -V Syste

系統技術業餘研究 » qperf測量網路頻寬和延遲

我們在做網路伺服器的時候,通常會很關心網路的頻寬和延遲。因為我們的很多協議都是request-reponse協議,延遲決定了最大的QPS,而頻寬決定了最大的負荷。 通常我們知道自己的網絡卡是什麼型號,交換機什麼型號,主機之間的物理距離是多少,理論上是知道頻寬和延遲是多少的。但是現實的情況是,真正的

系統技術業餘研究 » 詳解伺服器記憶體頻寬計算和使用情況測量

前段時間我們在MYSQL調優上發現有瓶頸,懷疑是過多拷貝記憶體,導致記憶體頻寬用完。在Linux下CPU的使用情況有top工具, IO裝置的使用情況有iostat工具,就是沒有記憶體使用情況的測量工具。 我們可以看到大量的memcpy和字串拷貝(可以用systemtap來測量),但是像簡單的資料移

系統技術業餘研究 » nicstat 網路流量統計利器

前段時間看到brendangregg的 Linux Performance Analysis and Tools PPT裡面提到的nicstat,研究了下是個不錯的東西,分享給大家。 nicstat is to network interfaces as “iostat” is to disks,