2014-02-28 88 views
2

我使用pysnmp和所遇到的CPU使用率過高的CPU使用率過高。我知道netsnmp編寫Python中C和pysnmp,所以我希望CPU使用率次更高,因爲的約20-100%。相反,我看到20倍較高的CPU使用時間。如何避免與pysnmp

我使用pysnmp正確或者我可以做一些事情,使之使用較少的資源呢?

測試案例1 - PySNMP:

from pysnmp.entity.rfc3413.oneliner import cmdgen 
import config 
import yappi 

yappi.start() 
cmdGen = cmdgen.CommandGenerator() 
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd(
    cmdgen.CommunityData(config.COMMUNITY), 
    cmdgen.UdpTransportTarget((config.HOST, config.PORT)), 
    config.OID, 
    lexicographicMode=False, 
    ignoreNonIncreasingOid=True, 
    lookupValue=False, lookupNames=False 
) 
for varBindTableRow in varBindTable: 
    for name, val in varBindTableRow: 
     print('%s' % (val,)) 
yappi.get_func_stats().print_all() 

測試案例2 - NetSNMP:

import argparse 
import netsnmp 
import config 
import yappi 

yappi.start() 
oid = netsnmp.VarList(netsnmp.Varbind('.'+config.OID)) 
res = netsnmp.snmpwalk(oid, Version = 2, DestHost=config.HOST, Community=config.COMMUNITY) 
print(res) 
yappi.get_func_stats().print_all() 

如果有人想測試自己,測試案例需要設置,config.py的小文件:

HOST = '192.168.1.111' 
COMMUNITY = 'public' 
PORT = 161 
OID = '1.3.6.1.2.1.2.2.1.8' 

我比較返回值和他們是一樣的 - 這樣既examp les功能正常。所不同的是按照定時:

PySNMP:

Clock type: cpu 
Ordered by: totaltime, desc 

name         #n   tsub  ttot  tavg 
..dgen.py:408 CommandGenerator.nextCmd 1   0.000108 1.890072 1.890072 
..:31 AsynsockDispatcher.runDispatcher 1   0.005068 1.718650 1.718650 
..r/lib/python2.7/asyncore.py:125 poll 144  0.010087 1.707852 0.011860 
/usr/lib/python2.7/asyncore.py:81 read 72   0.001191 1.665637 0.023134 
..UdpSocketTransport.handle_read_event 72   0.001301 1.664446 0.023117 
..py:75 UdpSocketTransport.handle_read 72   0.001888 1.663145 0.023099 
..base.py:32 AsynsockDispatcher._cbFun 72   0.001766 1.658938 0.023041 
..:55 SnmpEngine.__receiveMessageCbFun 72   0.002194 1.656747 0.023010 
..4 MsgAndPduDispatcher.receiveMessage 72   0.008587 1.654553 0.022980 
..eProcessingModel.prepareDataElements 72   0.014170 0.831581 0.011550 
../ber/decoder.py:585 Decoder.__call__ 1224/216 0.111002 0.801783 0.000655 
...py:312 SequenceDecoder.valueDecoder 288/144 0.034554 0.757069 0.002629 
..tCommandGenerator.processResponsePdu 72   0.008425 0.730610 0.010147 
..NextCommandGenerator._handleResponse 72   0.008692 0.712964 0.009902 
... 

NetSNMP:

Clock type: cpu 
Ordered by: totaltime, desc 

name         #n   tsub  ttot  tavg 
..kages/netsnmp/client.py:227 snmpwalk 1   0.000076 0.103274 0.103274 
..s/netsnmp/client.py:173 Session.walk 1   0.000024 0.077640 0.077640 
..etsnmp/client.py:48 Varbind.__init__ 72   0.008860 0.035225 0.000489 
..tsnmp/client.py:111 Session.__init__ 1   0.000055 0.025551 0.025551 
... 

所以,netsnmp使用0.103 S的CPU時間pysnmp使用的CPU時間1.890小號爲相同的操作。我發現結果令人驚訝...我也測試了異步模式,但結果甚至更糟糕。

我是不是做錯了什麼(有pysnmp)?

UPDATE:

按照伊利亞的建議下,我一直在使用BULK代步tryed。整體而言,BULK確實快得多,但PySNMP仍然使用cca。相比20倍的CPU時間來netsnmp:

..dgen.py:496 CommandGenerator.bulkCmd 1   0.000105 0.726187 0.726187 

Netsnmp:

..es/netsnmp/client.py:216 snmpgetbulk 1   0.000109 0.044421 0.044421 

所以,問題仍然有效 - 我可以讓pySNMP更少的CPU密集?我使用不正確?

回答

2

嘗試使用,而不是GETNEXT GETBULK。通過您的代碼和Max-Repetitions = 25設置,在我的綜合測試中,性能提高了5倍。

+0

伊利亞,感謝您的建議。我一直在避免BULK,因爲我不是100%確定我總是獲取所有數據......將考慮它並嘗試使用它。但是,比較PySNMP BULK和netsnmp BULK的問題仍然是一樣的(我用新的統計數據更新了這個問題)。 – johndodo

+0

PySNMP實際上比任何基於C的解決方案都慢得多。大部分資源都用於BER數據處理,所以它顯然是一個熱點。從理論上講,它可以通過使用特殊用途(SNMP數據包專用)BER編解碼器來優化,它可以簡化八位字節流處理,但是這種編解碼器在其他(非SNMP)應用程序中將變得不可重用。 –

+0

如果您有興趣優化往返延遲,那麼異步設計可能會有所幫助。但是由於CPU看起來像是一個瓶頸,所以除了減少要處理的SNMP數據包的數量之外,我想不出什麼。所以GETBULK可能會有所幫助,但是Net-SNMP總是會在性能方面獲勝。 –