刮除多个单一和分支OID的最有效方法是什么? [英] What is the most efficient way to scrape multiple single and branch OIDs?

查看:299
本文介绍了刮除多个单一和分支OID的最有效方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在最大速度和最小资源消耗之间进行斗争,因此我的目标是找到速度和资源消耗的最佳组合。

对于每个snmp设备,我都希望扫描其oid在几个分支下。

每个分支下都有一个动态数量的oid,所以我不知道我需要什么特定的oid,我只知道我在一个分支下需要所有oid。

我有一些仅支持SNMPv1的设备,因此对于那些设备,我编写与SNMPv1兼容的代码。

对于其余的设备,我使用SNMPv2。

I am always in a war between maximum speed and minimal resource consumption, so my goal is to find the best combination for speed and resource consumption.
For each snmp device I would like to scan the oids under several branches.
Each branch has a dynamic amount of oids under it so i don't know what specific oids i need, I just know that I need all oids under a branch.
I have some devices that only support SNMPv1 so for those devices I write code that is compatible with SNMPv1.
For the rest of the devices I use SNMPv2.

假设我有两个OID,我想遍历其分支('1.3.6.1.2.1.4 '和'1.3.6.1.2.1.6')

通过分支OID我指的是分支下的所有OID。

我有以下内容代码:

Let's say I have two OIDs that I would like to walk their branch('1.3.6.1.2.1.4' and '1.3.6.1.2.1.6').
By branch OID I mean all the OIDs under a branch.
I have the following code:

cmdGen = cmdgen.AsynCommandGenerator()
cmdGen.asyncNextCmd(
  cmdgen.CommunityData('public', mpModel=1),
  cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
  (str('1.3.6.1.2.1.4'),str('1.3.6.1.2.1.6'),),
  (__cbFun_Walk, (cmdgen.CommunityData('public', mpModel=1), cmdgen.UdpTransportTarget(('192.168.0.101', 161)))))
cmdGen.snmpEngine.transportDispatcher.runDispatcher()

这很好,但是唯一的问题是我只能一次停止所有步行,因此我不能单独停止每个步行,因此,只要最长的步行路程完成,所有步行都会完成。

显然这效率低下。

我也可以写2 asyncNextCmd 对于分支OID:

This works well but the only problem is that I can only stop all walks at once, therefore I can't stop each walk individually, so all walks will finish once the longest walk has finished.
Obviously this is inefficient.
I could also write 2 asyncNextCmd for the branch OIDs:

cmdGen = cmdgen.AsynCommandGenerator()
cmdGen.asyncNextCmd(
        cmdgen.CommunityData('public', mpModel=1),
        cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
        (str('1.3.6.1.2.1.4'),),
        (__cbFun_Walk, (cmdgen.CommunityData('public', mpModel=1),
        cmdgen.UdpTransportTarget(('192.168.0.101', 161))))) 
cmdGen.asyncNextCmd(
        cmdgen.CommunityData('public', mpModel=1),
        cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
        (str('1.3.6.1.2.1.6'),),
        (__cbFun_Walk, (cmdgen.CommunityData('public', mpModel=1),
        cmdgen.UdpTransportTarget(('192.168.0.101', 161)))))
cmdGen.snmpEngine.transportDispatcher.runDispatcher()

我不太了解SNMP ,但是我假设第二个代码有一些缺点。

例如,在某些客户端上,我有数百个SNMP设备,因此我为打开了每个网络设备同时运行。

这导致很多设备无响应并且CPU使用率过高。

I don't know SNMP too well, but I assume that the second code has some drawbacks.
For example on some clients I have hundreds of SNMP devices, so I opened an asyncCmd for each network device simultaneously.
This resulted in a lot of unresponsive devices and too high CPU usage.

我还想尝试了解批量的工作原理,以及是否可以使用它使我的代码更高效。

可以说我有两个分支,我想walk。

1.3.6.1.2.1.4.20具有5个oid,而1.3.6.1.2.1.4.21具有39个oid。 oids。

我得到了两个分支中的所有值,但我也得到了更多的值,然后我也想得到。

我得到的值的数量始终是金额最高的分支oid数乘以我拥有的分支数。

例如,具有最多oid的分支有39个oid,分支数为2,所以39 * 2 = 78,这意味着getBulk将返回78个oids。

我希望getBulk返回每个分支的所有分支oids,而不是其他任何东西,因此在我的情况下,我想要44个oids(39 + 5 = 44)。

这是我的代码:

I would also want to try to understand how the bulk works and if I can use it to make my code more efficient.
Lets say I have 2 branches that I would like to walk.
1.3.6.1.2.1.4.20 that has 5 oids, and 1.3.6.1.2.1.4.21 that has 39 oids.
I get all the values in both branches but i also get more values then i want aswell.
The amount of values that I get is always the branch with the highest amount of oids times the amount of branches that I have.
For example the branch with the most oids has 39 oids, and the amount of branches is 2, so 39*2=78, that means the getBulk will return 78 oids.
I want the getBulk to return all the branch oids for each branch and not anything more, so in my case I want 44 oids(39+5 = 44).
This is my code:

cmdGen = cmdgen.CommandGenerator()

errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.bulkCmd(
  cmdgen.CommunityData('public'),
  cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
  0, 1,
  '1.3.6.1.2.1.4.21', '1.3.6.1.2.1.4.20'
)

if errorIndication:
  print errorIndication
elif errorStatus:
  print '%s at %s\n' % (
    errorStatus.prettyPrint(),
    errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
  )
else:
  for varBindTableRow in varBindTable:
    for name, val in varBindTableRow:
      print str(name.prettyPrint()) + ' = ' + str(val.prettyPrint())

那么为SNMPv1和SNMPv2刮取多个分支OID的最有效方法是什么?

So what is the most efficient way to scrape multiple branch OIDs for both SNMPv1 and SNMPv2?

推荐答案

首先要意识到的是,您无法指示SNMP代理准确地向您返回分支。 SNMP(在协议级别)不支持这种操作。管理员可以控制要请求的OID以及何时停止。代理可以一次返回确切的单个OID(GET)或下一个OID(GETNEXT / GETBULK)或一次返回下一个OID的近似数量(GETBULK)。

The first thing to realize is that you can't instruct SNMP agent to return you precisely a "branch". Such operation is not supported in SNMP (at protocol level). The manager is in control in regards to what OIDs to request and when to stop. Agent can return the exact single OID (GET) or next OID (GETNEXT/GETBULK) or approximate number of next OIDs at once (GETBULK).

动态OID,您无法可靠地预测在任何给定时刻有多少OID。因此,我认为您不可能在单个SNMP操作中严格地获得分支OID或多或少。

In case when you have dynamic OIDs, you can't reliably anticipate how many of them are there at any given moment. Hence I don't think you could get strictly the branch OIDs not more or less in a single SNMP operation.

我曾说过,我认为您应该尝试在任何地方使用GETBULK可能。瞄准最大预期数量的OID,以一次GETBULK操作来获取它们。但是请检查您的代码,您确实可以获取所有内容(代理可能不会一次返回所有请求的OID数量)。

Having said that I think you should try to use GETBULK wherever possible. Aim at the maximum anticipated number of OIDs to grab them in one GETBULK operation. But check in your code that you indeed get everything (agent may not return the requested number of OIDs all at once).

对于您正在使用的pysnmp API,要停止它的GETBULK / GETNEXT迭代应该从您的回调函数返回True。您可以分析从代理那里获得的OID,并在它们超出您感兴趣的分支时返回True。这将终止一个分支的检索,其余的将继续运行。

As for pysnmp API you are using, to stop its GETBULK/GETNEXT iteration you are supposed to return True from your callback function. You could analyze what OIDs you are getting from the agent there and return True as they get beyond the branch you are interested in. That would terminate one branch retrieval, the rest will keep running.

将不同的OID发送到同一SNMP代理的多个并行查询的设计效率明显降低。

The design where you send multiple parallel queries to the same SNMP agent for different OIDs is obviously much less efficient.

这篇关于刮除多个单一和分支OID的最有效方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆