简体   繁体   English

从具有三个库的OID读取SNMP可以得出不同的执行时间

[英]SNMP reading from an OID with three libraries gives different execution times

I already used easysnmp to read SNMP OIDs, but I chose pysnmp library now because easysnmp did not support asyncio archtecture in Python3 . 我已经使用easysnmp读取SNMP OID,但是现在选择pysnmp库是因为easysnmpeasysnmp中不支持asyncio 体系结构

The considered issue is that, pysnmp is too slower than other libraries: 考虑的问题是, pysnmp的速度比其他库慢:

pysnmp: pysnmp:

from pysnmp.hlapi import *
import time

t = time.time()
iterator = getCmd(SnmpEngine(),
                  CommunityData('public'),
                  UdpTransportTarget(('192.168.1.120', 161)),
                  ContextData(),
                  ObjectType(ObjectIdentity("1.3.6.1.2.1.33.1.2.7.0")))

errorIndication, errorStatus, errorIndex, varBinds = next(iterator)

if errorIndication:  # SNMP engine errors
    print(errorIndication)
else:
    if errorStatus:  # SNMP agent errors
        print('%s at %s' % (
            errorStatus.prettyPrint(),
            varBinds[int(errorIndex)-1] if errorIndex else '?'))
    else:
        for varBind in varBinds:  # SNMP response contents
            print(' = '.join([x.prettyPrint() for x in varBind]))


print(time.time() - t, 's') 

Out: 日期:

SNMPv2-SMI::mib-2.33.1.2.7.0 = 21
0.15317177772521973 s

easysnmp easysnmp

from easysnmp import snmp_get
import time

if __name__ == '__main__':
    t = time.time()
    response = snmp_get(
        '1.3.6.1.2.1.33.1.2.7.0', hostname='192.168.1.120',
        community='public', version=1
    )
    print(response.value)
    print(time.time() - t, 's')

Out: 日期:

21
0.0063724517822265625 s

gosnmp gosnmp

func elapsed(what string) func() {
    start := time.Now()
    fmt.Println("start")
    return func() {
        fmt.Printf("%s took %v\n", what, time.Since(start))
    }
}

func snmpRead() {
    g.Default.Target = "192.168.1.120"
    err := g.Default.Connect()
    if err != nil {
        log.Fatalf("Connect() err: %v", err)
    }
    defer g.Default.Conn.Close()

    oids := []string{"1.3.6.1.2.1.33.1.2.7.0"}
    result, err2 := g.Default.Get(oids) // Get() accepts up to g.MAX_OIDS
    if err2 != nil {
        log.Fatalf("Get() err: %v", err2)
    }

    for i, variable := range result.Variables {
        fmt.Printf("%d: oid: %s ", i, variable.Name)

        switch variable.Type {
        case g.OctetString:
            fmt.Printf("string: %s\n", string(variable.Value.([]byte)))
        default:
            fmt.Printf("number: %d\n", g.ToBigInt(variable.Value))
        }
    }
}

func main() {
    defer elapsed("snmp")()
    snmpRead()
}

Out: 日期:

start
0: oid: .1.3.6.1.2.1.33.1.2.7.0 number: 21
snmp took 3.668148ms

30x faster than pysnmp pysnmp快30 pysnmp


I need to the asynchronous performance which go-routine populated asyncio in Python3 . 我需要在asyncio go-routine填充asyncio的异步性能。

So, is this means that I should migrate from pysnmp to gosnmp ? 所以,这意味着我应该从pysnmp迁移到gosnmp吗?

Keep in mind that first pysnmp call might take much more time relative to the subsequent calls. 请记住,相对于后续调用,第一次pysnmp调用可能要花费更多时间。 Because of the lazy imports, indexing, possible MIB compilation etc. 由于延迟导入,索引编制,可能的MIB编译等。

So if your use-case is to issue many SNMP queries from the same process, I'd advise to take that into account when measuring the time taken. 因此,如果您的用例是从同一过程发出许多SNMP查询,则建议在测量所用时间时考虑到这一点。

The other thing is that the latest (unreleased) pysnmp has introduced asyncio bindings over low-level SNMP routines ie excluding SNMP engine and all the heavy machinery it involves. 另一件事是,最新的(未发布的)pysnmp通过低级SNMP例程引入了异步绑定,即不包括SNMP引擎及其涉及的所有繁琐的机制。

The pysnmp.hlapi.v1arch.asyncio API is intended to be very similar to pysnmp.hlapi.v3arch.asyncio from its signature viewpoint, however it should be faster at the expense of no SNMPv3 support. 从签名角度来看, pysnmp.hlapi.v1arch.asyncio API的目的与pysnmp.hlapi.v3arch.asyncio非常相似,但是应该更快,但要以不支持SNMPv3为代价。 MIB support is still in place, if you need it. 如果需要,MIB支持仍然存在。

When you import just pysnmp.hlapi.asyncio , you will effectively get pysnmp.hlapi.v3arch.asyncio , so to get on v1arch you need to import it explicitly. 当仅导入pysnmp.hlapi.asyncio ,您将有效地获取pysnmp.hlapi.v3arch.asyncio ,因此要获得v1arch ,需要显式导入。

For example the script below (running under GitHub master pysnmp) might be faster: 例如,以下脚本(在GitHub 主站 pysnmp下运行)可能会更快:

import asyncio
from pysnmp.hlapi.v1arch.asyncio import *


@asyncio.coroutine
def run():
    snmpDispatcher = SnmpDispatcher()

    iterator = getCmd(
        snmpDispatcher,
        CommunityData('public'),
        UdpTransportTarget(('192.168.1.120', 161)),
        ('1.3.6.1.2.1.33.1.2.7.0', None)
    )

    errorIndication, errorStatus, errorIndex, varBinds = yield from iterator

    if errorIndication:
        print(errorIndication)

    elif errorStatus:
        print('%s at %s' % (
            errorStatus.prettyPrint(),
            errorIndex and varBinds[int(errorIndex) - 1][0] or '?'
        )
              )
    else:
        for varBind in varBinds:
            print(' = '.join([x.prettyPrint() for x in varBind]))

    snmpDispatcher.transportDispatcher.closeDispatcher()


asyncio.get_event_loop().run_until_complete(run())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM