본문 바로가기
Java

SNMP GETBULK, SUBTREE 시간 성능 Test

by 쁘니쁘나 2020. 9. 16.

Switch 하드웨어 정보관리 Agent 개발을 어느 정도 마무리하고 기존에 GetBulk로 각각의 OID에서 데이터를 가져오던 것을 성능개선을 위해 Test 해보았습니다.

 

💡 기존방식 (GETBULK로 24개씩 데이터 받기)

예를 들어 24 포트짜리의 Switch라고 가정하였을 때, 하나의 OID 1.3.6.1.2.1.2.2.1.2에 대하여 각 24개의 포트 데이터를 GetBulk를 사용하여 한번에 24개를 가져왔습니다.

JAVA 코드단에서 작성된 코드 사이사이에 시간을 측정하여 확인해본 결과

1개의 OID에 대하여 24개의 데이터를 조회해오는데 0.1~0.2초 의 시간이 걸렸으며, 원하는 데이터 정보가 들어있는 총 14개의 OID에 대하여 24*14 = 336 개의 데이터를 조회하는 데는 1.3~1.5초의 시간이 걸린 것을 확인할 수 있었습니다.

 

 

💡 GETBULK로 최대 개수의 데이터 받기

기존에 GETBULK로 1개의 OID에 대하여 필요한 24개의 포트 정보만 한 번에 조회해 오는 대신, GETBULK로 필요한 OID를 전부 포함하는 1.3.6.1.2.1.2.2.1을 한 번만 조회하여 모든 데이터들을 다 가져오려 하였더니 GETBULK로 최대 가져올 수 있는 데이터의 개수는 100개였습니다. 그래서 시작 OID로 100개의 데이터를 가져오게끔 하고 마지막 데이터 즉, 100번째 데이터 OID 값을 다시 조회하여 그다음 100개, 또 그다음 100개를 반복적으로 가져오도록 하였습니다. 그리고 처음 설정해주었던 OID가 아니라면 조회를 그만하도록 하였습니다. 100개의 데이터를 7번 가져오더라고요. 즉, 7개의 OID를 GETBULK로 조회하였다는 것이죠.
public void getBulk(String switchOid, CommunityTarget target) throws IOException {
        Snmp snmp = new Snmp(new DefaultUdpTransportMapping());

        snmp.listen();

        // PDU Type Setting
        VariableBinding lastVb = new VariableBinding((new OID(switchOid))) ;
        while(lastVb.getOid().startsWith(new OID("1.3.6.1.2.1.2.2.1"))) {
            PDU pdu = new PDU();
            pdu.add(lastVb);
            pdu.setType(PDU.GETBULK);
            pdu.setMaxRepetitions(100); // repetition 최대 100

            ResponseEvent response = snmp.send(pdu, target);

            for (VariableBinding vb : response.getResponse().getVariableBindings()) {
                count++;
                log.info(vb + " ," + vb.getVariable().getSyntaxString());
                lastVb = vb;
            }
        }
    }

위에서 처럼 코드를 작성하고 처음과 마지막에 시간을 넣어 전체 시간 차이를 구하고 각 코드 중간에도 시간을 체크하여 어느 부분을 실행할 때 가장 시간이 많이 소요되는지 알아보았습니다.

1개의 OID에 대하여 100개의 데이터를 조회해오는데 0.6~0.7초의 시간이 걸렸으며, 전체 7개의 OID에 대하여 총 700개의 데이터를 조회하데는 4.3~5.5초의 시간이 소요되는 것을 확인할 수 있었습니다. 

 

 

💡 SUBTREE로 1개의 OID로 전체 데이터 조회

루트 OID인 하나의 OID만을 사용하여 전체 데이터를 조회해보았습니다. 
public void getSubTree(String tableOid, CommunityTarget target) {
        Map<String, String> result = new TreeMap<>();
        TransportMapping<? extends Address> transport = null;
        try {
            transport = new DefaultUdpTransportMapping();
            Snmp snmp = new Snmp(transport);
            transport.listen();

            TreeUtils treeUtils = new TreeUtils(snmp, new DefaultPDUFactory());
            List<TreeEvent> events = treeUtils.getSubtree(target, new OID(tableOid));
            if (events == null || events.size() == 0) {
                System.out.println("Error: Unable to read table...");
                return;
            }

            for (TreeEvent event : events) {
                if (event == null) {
                    continue;
                }
                if (event.isError()) {
                    System.out.println("Error: table OID [" + tableOid + "] " + event.getErrorMessage());
                    continue;
                }

                VariableBinding[] varBindings = event.getVariableBindings();
                if (varBindings == null || varBindings.length == 0) {
                    continue;
                }
                for (VariableBinding varBinding : varBindings) {
                    if (varBinding == null) {
                        continue;
                    }
                    result.put("." + varBinding.getOid().toString(), varBinding.getVariable().toString());
                }

            }
             snmp.close();
        } catch (IOException e) {
            log.error("snmpWalk fail : "+e.getMessage());
        }

    }

SUBTREE 방식은 GETBULK 방식과 다르게 TreeUtils 객체를 사용하여 조회하였는데요. 결과는 총데이터를 조회하는데 3~4초의 시간이 걸렸습니다.

 

결론!

공통적으로 GETBULK 방식은 snmp.send 하는 부분에서 제일 많은 시간이 소요되었고, SUBTREE 방식은 treeUtils.getSubtree 에서 시간이 많이 소요되었습니다. 또한, 기존 방식대로 필요한 OID를 직접 코드단에서 설정해주고 필요한 24개의 데이터들만 조회하는 것이 가장 시간 성능면에서 빠르다는 것을 알 수 있었습니다.

댓글