python - 如何使用 pysnmp 避免高 CPU 使用率

标签 python net-snmp pysnmp

我正在使用 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
...

因此,对于同样的操作。我发现结果令人惊讶......我也测试了异步模式,但结果更糟糕。

我是不是做错了什么(pysnmp)?

更新:

根据 Ilya 的建议,我尝试使用 BULK 而不是 WALK。 BULK确实整体上快很多,但是PySNMP还是用cca。与 netsnmp 相比,20 倍的 CPU 时间:

..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 密集度吗?我使用不当吗?

最佳答案

尝试使用 GETBULK 而不是 GETNEXT。使用您的代码和 Max-Repetitions=25 设置,它使我的综合测试性能提高了 5 倍。

关于python - 如何使用 pysnmp 避免高 CPU 使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22089477/

相关文章:

python - 在 Django 中从 DateField 迁移到 DateTimeField

python - PySNMP:加载错误:错误的 OctetString 初始值设定项

SNMP net-snmp 与预期的 OID 转换不同

perl - SNMP:运行子代理

ios - 将 C 库更改为 IOS 库时出现错误

python - 如何在 pysnmp 中查找 mib 表?

python - 解析或拆分 pysnmp 输出以更新到数据库中

python - 在较长列表的每个第 n 个元素处将两个不同长度的列表组合成元组

python - 按列表顺序替换值

python - 将文本格式的固定宽度表格转换为dataframe/excel/csv