Skip to content

[PR-4]Decision making module for automatic migration#793

Open
AmitRoushan wants to merge 6 commits into
amino-os:masterfrom
AmitRoushan:metricCollector
Open

[PR-4]Decision making module for automatic migration#793
AmitRoushan wants to merge 6 commits into
amino-os:masterfrom
AmitRoushan:metricCollector

Conversation

@AmitRoushan

@AmitRoushan AmitRoushan commented Jun 4, 2019

Copy link
Copy Markdown
Collaborator

@quinton-hoole

Copy link
Copy Markdown
Collaborator

Thanks. Please rebase before requesting a review.

@AmitRoushan AmitRoushan force-pushed the metricCollector branch 2 times, most recently from 844fc98 to 6a10160 Compare June 6, 2019 14:19
@quinton-hoole

Copy link
Copy Markdown
Collaborator

Please check that the comments describing this PR are correct (all the PR's mentioned there have been closed, so I assume it's out of date).
And please confirm that all of this PR needs to be reviewed? It's quite huge.
Then please self-review.
Then ask @VenuReddy2103 to review.
Then ask me to do a final review before merging.
Thanks.

@AmitRoushan

Copy link
Copy Markdown
Collaborator Author

Review comment fix from PR #745:

  1. General convention for package name is to use lowercase
    Status: "migrationDecision" module changed to "migrationdecision".
  2. Don't need logger for each instance of it. Make it private static final.
    Status: MetricWatcher logger changed to "private static final"
  3. Why transient volatile ?
    Status: Removed "transient" modifier from ResettableTimer in MetricWatcher
  4. Instead if timer != null, then simply return can be more clear ?
    Status: Timer instance creation moved to constructor. So removed null check from start method of MetricWatcher
  5. What we need was nodeMetric from client to the kernelserver. But we took from kernelserver to the client. Did we assume both to be same ? They both are not necessary to be same.
    Status: Updated code as per suggestion. Now rate and latency are used from kernelClient node metric.

@AmitRoushan

Copy link
Copy Markdown
Collaborator Author

@VenuReddy2103 , I have handled all review comments from PR #745. Please have a look.
@quinton-hoole #746 and #753 are closed and new PR #794, #795 and #796 are open respectively for microservice and node metric management. Same has been updated in PR description.

@quinton-hoole

Copy link
Copy Markdown
Collaborator

@AmitRoushan I still cannot review this PR until #794 , #795 and #796 have been reviewed. And I can't review those until #794 (comment) has been answered. So basically all of these PR's are blocked.

@AmitRoushan AmitRoushan changed the title Decision making module for automatic migration [PR-4]Decision making module for automatic migration Jul 25, 2019
@AmitRoushan AmitRoushan force-pushed the metricCollector branch 3 times, most recently from 4ffa543 to 9b5a943 Compare September 6, 2019 14:39
@AmitRoushan

AmitRoushan commented Sep 6, 2019

Copy link
Copy Markdown
Collaborator Author

@quinton-hoole
I have reverted KVstore code changes. Changes are made to test migration.
Also we fixed one bug , found during testing.
Please find the attached status report below:

  • Build report
    clean_build

  • KVStore App report
    kvstore

  • Hankstodo App report
    hankstodo

  • MinnieTwitter App report
    minnietwitter

  • HankstodoRuby App report
    Selection_027

  • KVstorejs App report
    Selection_028


// Register against OMS
ServerInfo srvInfo = createServerInfo(host, ksArgs.labels);
srvInfo.processorCount = Runtime.getRuntime().availableProcessors();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me why this initialization is not done in createServerInfo like all the other initialization?
Or better still, in the constructor of ServerInfo?
I'm uncomfortable with having an uninitialized processorCount in ServerInfo structure until someone remembers to initialize it.

} catch (Exception e) {
logger.warning("Failed to get replica dispatcher");
e.printStackTrace();
return false;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems it would be more appropriate to throw an exception here.
What does the return value of this method actually mean?

} catch (MicroServiceNotFoundException e) {
logger.warning(
String.format(
"Skipping Replica [%s] evaluation as micro service not available",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets improve this exception message. It's not the microservice that's unavailable. It's not found in OMS.

} catch (MicroServiceReplicaNotFoundException e) {
logger.warning(
String.format(
"Skipping Replica [%s] evaluation as micro service replica not available",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above.

KernelServerNotFoundException {
/*
To measure time consumption by vertex Vk we use the following formula
tk = Tk,posk+i + summation { (Ski+Sik)/Rposk,posi + Lposk,posi }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please explain what all these terms mean. tK, Tk, posk+i, Ski, Sik, Rposk? It's not at all clear what you mean here.

serverManager.getKernelServerMetric(replicaKernelServer);

// get metrics stat of RPC processing time from different kernel client
// TODO currently considering processing time from different kernel client for simplicity.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please clarify. It's not clear what you mean here.

// calculate time factor impact on RPC with latency and bandwidth
long averageExecutionTime = 0;
long summation = 0;
long data;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please call this dataSize. It's not data.


// calculate time factor impact on RPC with latency and bandwidth
long averageExecutionTime = 0;
long summation = 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a useful variable name. Do you mean the sum of the round trip times? Perhaps call it rttSum?

}

AbstractMap.SimpleEntry<InetSocketAddress, Long> bestTimeOptimization =
predictedTime.first();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be worth mentioning in a comment that you're relying on this set being sorted by time here. Sets are not usually sorted, so this is an unusual use of a set, and a bit confusing.

replicaMetrics = microServiceManager.getMicroServiceMetric(replicaID);
} catch (MicroServiceNotFoundException e) {
e.printStackTrace();
return 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exception should be thrown. This also answers my previous question above.

currentKernelServerMetrics = serverManager.getKernelServerMetric(currentKernelServer);
futureKernelServerMetrics = serverManager.getKernelServerMetric(futureKernelServer);
} catch (KernelServerNotFoundException e) {
e.printStackTrace();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throw this exception.

return bestTimeOptimization.getKey();
}

private long getOptimizedTime(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment to explain what this method does.

return bestTimeOptimization.getKey();
}

private long getOptimizedTime(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: It's not actually an optimization, it's a prediction of elapsed time on a different node.

private long getOptimizedTime(
ReplicaID replicaID,
InetSocketAddress currentKernelServer,
InetSocketAddress futureKernelServer)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: It's not actually a future kernel server. It's a prediction related to an potential alternative kernel server.

kernelClient,
futureKernelServer,
currentByteExchanged);
} catch (Exception e) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't just catch Exceptions and ignore them like this.

long currentProcessingTime;
long currentByteExchanged;
long futureProcessingTime;
double currentIOTime;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets avoid all double precision arithmetic. It's unnecessary. Just record times in a small enough unit (e.g. microseconds or nanoseconds) and just use integer arithmetic.

"Node metric not available between kernel client [%s] and kernel server [%s]",
kernelClient, KernelServer);
logger.warning(msg);
throw new Exception(msg);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please throw a more specific exception type. This is a not found exception.

/* Store these metrics to make them available for statistics and decision making module */
updateMetric(object.replicaId, object.metrics);
return;
} else if (notification instanceof MigrationNotification) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't understand why we're using notifications for all of these things.
Surely we should just have a method to receive metrics, and another one to receive migration instructions?
What's the benefit of using Notifications instead?

@quinton-hoole quinton-hoole left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See inline comments for requested changes. Amit, if you are otherwise occupied, I can make the required changes. Let me know.

@AmitRoushan

Copy link
Copy Markdown
Collaborator Author

@quinton-hoole
I have fixed most of review comments but still i need some more time to run some test scenario for migration.

@quinton-hoole

quinton-hoole commented Sep 9, 2019 via email

Copy link
Copy Markdown
Collaborator


public ServerInfo(InetSocketAddress addr) {
this.host = addr;
this.processorCount = Runtime.getRuntime().availableProcessors();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will only work correctly when this constructor is called on the machine to which the server info refers. Surely processorCount should be a parameter to the constructor, similar to addr?

private TreeSet<AbstractMap.SimpleEntry<ReplicaID, Long>> replicaHeap;
private TreeSet<AbstractMap.SimpleEntry<ReplicaID, Long>>
replicaHeap; // should only used in getBestCandidates for selecting best microservice
// replica for migration

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit - weird comment formatting. Use /* */ instead?

String.format(
"Skipping Replica [%s] for migration as micro service not found",
bestCandidateReplicaId));
e.printStackTrace();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to print the stack trace?

String.format(
"Skipping Replica [%s] for migration as micro service replica not found",
bestCandidateReplicaId));
e.printStackTrace();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above.

}

return averageExecutionTime + summation;
return avgElapsedTime + avgRtt;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems wrong. Don't you want to subtract the RTT from the elapsedTime to get the processing (computation) time? Also, a single inbound RPC may result in multiple "dowstream" outbound RPC's, some in serial, and some in parallel. Using the avgRtt here (even assuming your substract it as mentioned above) implies a single outbound RPC per inbound RPC, which is not correct? I think you need to keep track of the ratio of inbound:outbound (say 1:n) and subtract n times the avgRtt?

@quinton-hoole

Copy link
Copy Markdown
Collaborator

@AmitRoushan How is your testing going?

@quinton-hoole

Copy link
Copy Markdown
Collaborator

@AmitRoushan ?

@AmitRoushan AmitRoushan force-pushed the metricCollector branch 4 times, most recently from 6ce13b0 to 45045cf Compare September 18, 2019 12:57
@quinton-hoole

Copy link
Copy Markdown
Collaborator

@AmitRoushan @VenuReddy2103 What is the status with this PR please?

1 similar comment
@quinton-hoole

Copy link
Copy Markdown
Collaborator

@AmitRoushan @VenuReddy2103 What is the status with this PR please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants