VMware {code} Community
jeyakarthika
Contributor
Contributor

ResourcePool Performance taking more time to complete

Hi,

My code ll get resourcepool performance details from virtual center using VI SDK 2.5 .

Code is calling queryPerf method for each resource pool. This method call is taking 30-45 secs for some Resource pools .

In our environment we are having 30 Resource pools. So Code is taking 5 to 6 minutes to complete.

Why it is taking this much of time? Is there any way to optimize?

Piece of code :

PerfQuerySpec[] perfQSpecs = new PerfQuerySpec[http://resourcePoolRefs.size()|http://resourcePoolRefs.size()];

Enumeration rps = resourcePoolRefs.keys();

int numPQSs=0;

long currentTime service.currentTime(svcRef).getTimeInMillis();

long previousTime = (currentTime - 86400000); //To set previous time as 1 day before

Date currentDate = new Date(currentTime);

Date prevDate =new Date (previousTime);

Calendar current = new GregorianCalendar();

current.setTime(currentDate);

Calendar previous = new GregorianCalendar();

previous.setTime(prevDate);

try

{

while(rps.hasMoreElements())

{

ManagedObjectReference rpRef = (ManagedObjectReference) rps.nextElement();

String rpName = (String) resourcePoolRefs.get(rpRef);

perfQSpecs[numPQSs] = new PerfQuerySpec();

perfQSpecs[numPQSs].setEntity(rpRef);

perfQSpecs[numPQSs].setMetricId(metricIds);

perfQSpecs[numPQSs].setStartTime(previous);

perfQSpecs[numPQSs].setEndTime(current);

perfQSpecs[numPQSs].setMaxSample(new Integer(1));

perfQSpecs[numPQSs].setIntervalId(300); // set interval id as 5 minutes

numPQSs++;

}

}

catch (Exception exce)

{

exce.printStackTrace();

}

for (int r=0; r<perfQSpecs.length; r++)

{

PerfQuerySpec[] qSpecs = new PerfQuerySpec[1];

qSpecs[0] = perfQSpecs[r];

PerfEntityMetricBase[] retVal = _service.queryPerf(pmRef,qSpecs);

int j = 1;

for (PerfEntityMetricBase pemb : retVal) {

System.out.println("PerfEntityMetricBase : " + j);

PerfMetricSeries[] vals = ((PerfEntityMetric) pemb).getValue();

PerfSampleInfo[] infos = ((PerfEntityMetric) pemb).getSampleInfo();

System.out.println("Sample time range: "+ infos[0].getTimestamp().getTime().toString() + " - "

+ infos[http://infos.length - 1|http://infos.length - 1].getTimestamp().getTime().toString() + "\n");

for (int vi = 0; vi < vals.length; ++vi) {

System.out.println("PerfCounterInfo : " + vi);

PerfCounterInfo pci = counterInfoMap.get(new Integer(vals[vi].getId().getCounterId()));

System.out.println("Counter ID: " + pci.getKey()+ "\nCounter Instance: "

+ vals[vi].getId().getInstance()+ "\nCounter Info: "+ pci.getGroupInfo().getKey() + "."

+ pci.getNameInfo().getKey() + "."+ pci.getRollupType().getValue() + " - "+ pci.getUnitInfo().getKey());

if (vals[vi] instanceof PerfMetricIntSeries) {

PerfMetricIntSeries val = (PerfMetricIntSeries) vals[vi];

long[] longs = val.getValue();

for (int k = 0; k < longs.length; ++k) {

System.out.print("Stats value: " + longs[k]+ "\n");

}

System.out.println();

}

}

j++;

}

}

Regards,

Karthika

Reply
0 Kudos
5 Replies
admin
Immortal
Immortal

Hi Karthika,

You could try modifying your code as follows:

// Your code snippet

for (int r=0; r<perfQSpecs.length; r++)

{

PerfQuerySpec[] qSpecs = new PerfQuerySpec[1];

qSpecs[0] = perfQSpecs[r];

PerfEntityMetricBase[] retVal = _service.queryPerf(pmRef,qSpecs);

....

}

qSpecs = new PerfQuerySpec[];

for (int r=0; r<perfQSpecs.length; r++)

{

PerfQuerySpec pqs = new PerfQuerySpec( ... );

qSpecs[r] = pqs;

}

PerfEntityMetricBase[ ] retVal = _service.queryPerf(pmRef,qSpecs);

The point here to mention is that to collect data only what you will use and use everything that you collect. Hence, calling queryPerf a single time by passing the querySpec array instead of calling the API multiple times passing a single querySpec item.

Hope this would help you and lessen the time to fetch the data.

- Angela

Reply
0 Kudos
jeyakarthika
Contributor
Contributor

Hi AngelaS,

Thanks for Your response.

As per your suggestion i modified the code.it hangs for 10 mins before we get a response.

so overall, the issue is the same.

Previously we call queryPerf in loop in that we are able to know which rp is taking time.

Can u please tell me why it is taking this much of time ?

Modified code:

PerfQuerySpec[] perfQSpecs = new PerfQuerySpec[http://resourcePoolRefs.size()|http://resourcePoolRefs.size()];

try

{

while(rps.hasMoreElements())

{

ManagedObjectReference rpRef = (ManagedObjectReference) rps.nextElement();

String rpName = (String) resourcePoolRefs.get(rpRef);

perfQSpecs[numPQSs] = new PerfQuerySpec();

perfQSpecs[numPQSs].setEntity(rpRef);

perfQSpecs[numPQSs].setMetricId(metricIds);

perfQSpecs[numPQSs].setStartTime(previous);

perfQSpecs[numPQSs].setEndTime(current);

perfQSpecs[numPQSs].setMaxSample(new Integer(1));

perfQSpecs[numPQSs].setIntervalId(null);

numPQSs++;

}

}

catch (Exception exce)

{

exce.printStackTrace();

}

PerfQuerySpec[] qSpecs =perfQSpecs;

PerfEntityMetricBase[ ] retVal = _service.queryPerf(pmRef,qSpecs);

int j = 1;

for (PerfEntityMetricBase pemb : retVal) {

System.out.println("PerfEntityMetricBase : " + j);

PerfMetricSeries[] vals = ((PerfEntityMetric) pemb).getValue();

PerfSampleInfo[] infos = ((PerfEntityMetric) pemb).getSampleInfo();

System.out.println("Sample time range: "+ infos[0].getTimestamp().getTime().toString() + " - "

+ infos[http://infos.length - 1|http://infos.length - 1].getTimestamp().getTime().toString() + "\n");

for (int vi = 0; vi < vals.length; ++vi) {

System.out.println("PerfCounterInfo : " + vi);

PerfCounterInfo pci = counterInfoMap.get(new Integer(vals[vi].getId().getCounterId()));

System.out.println("Counter ID: " + pci.getKey()+ "\nCounter Instance: "

+ vals[vi].getId().getInstance()+ "\nCounter Info: "+ pci.getGroupInfo().getKey() + "."

+ pci.getNameInfo().getKey() + "."+ pci.getRollupType().getValue() + " - "+ pci.getUnitInfo().getKey());

if (vals[vi] instanceof PerfMetricIntSeries) {

PerfMetricIntSeries val = (PerfMetricIntSeries) vals[vi];

long[] longs = val.getValue();

for (int k = 0; k < longs.length; ++k) {

System.out.print("Stats value: " + longs[k]+ "\n");

}

System.out.println();

}

}

j++;

}

Reply
0 Kudos
admin
Immortal
Immortal

You could try referring to http://communities.vmware.com/docs/DOC-9840 which illustrates the best practices while monitoring performance.

Hope this would help.

Reply
0 Kudos
jeyakarthika
Contributor
Contributor

Hi AngelaS,

Thanks for the pointer.

i can see that using CSV option might speed up the query. If there is anything else that is obvious to you,

please let me know.

-karthika

Reply
0 Kudos
dmitrif
Enthusiast
Enthusiast

Iif you ask for one 5 min sample, why is your start time set to one day back? set to to currentTime less 300...

If you specify start/end time then you don't need to specify interval id

I suppose you copied your code from RealTime sample, it is not appliocable to resource pool as they do not provide real-time performance data.

Also it is unclear from your code where you get metric Ids, IMO the easiest way is to retrive them once and cache (by mor and interval), reusing for this spec

BTW, retriveing all of them at once as suggested is good when you know your data center size, it you pack too much into it ESX server will timeouts in 30 min.

D.
Reply
0 Kudos