我正在使用pysnmp
并遇到高 CPU 使用率。我知道netsnmp
它是用 C 和pysnmp
Python 编写的,因此我预计 CPU 使用时间会因此提高 20-100%。相反,我看到CPU 使用时间增加了20倍。
我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'
我已经比较了返回的值,它们是相同的——所以两个例子都能正常工作。不同之处在于时间:
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
...
网络SNMP:
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 秒的 CPU 时间和pysnmp
1.890秒的 CPU 时间进行相同的操作。我发现结果令人惊讶......我也测试了异步模式,但结果更糟。
我做错了什么(用pysnmp
)?
更新:
根据 Ilya 的建议,我尝试使用 BULK 而不是 WALK。BULK 总体上确实快得多,但 PySNMP 仍然使用 cca。与 netsnmp 相比,20 倍的 CPU 时间:
..dgen.py:496 CommandGenerator.bulkCmd 1 0.000105 0.726187 0.726187
网管:
..es/netsnmp/client.py:216 snmpgetbulk 1 0.000109 0.044421 0.044421
所以问题仍然存在——我可以让 pySNMP 减少 CPU 密集度吗?我使用不正确吗?