Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

JVM decider #326

Merged
merged 11 commits into from
Sep 3, 2020
Merged

JVM decider #326

merged 11 commits into from
Sep 3, 2020

Conversation

rguo-aws
Copy link
Contributor

Issue #:

Description of changes:
Add JVM decider to RCA framework

Tests:
WIP

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@rguo-aws rguo-aws added the feature New feature label Jul 31, 2020
@codecov
Copy link

codecov bot commented Jul 31, 2020

Codecov Report

Merging #326 into master will decrease coverage by 0.96%.
The diff coverage is 16.85%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #326      +/-   ##
============================================
- Coverage     70.54%   69.57%   -0.97%     
- Complexity     2310     2371      +61     
============================================
  Files           307      318      +11     
  Lines         13686    14273     +587     
  Branches       1142     1199      +57     
============================================
+ Hits           9655     9931     +276     
- Misses         3669     3976     +307     
- Partials        362      366       +4     
Impacted Files Coverage Δ Complexity Δ
...rmanceanalyzer/decisionmaker/deciders/Decider.java 68.00% <ø> (+2.48%) 5.00 <0.00> (ø)
.../decisionmaker/deciders/jvm/HeapHealthDecider.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
...er/deciders/jvm/old_gen/LevelOneActionBuilder.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
.../deciders/jvm/old_gen/LevelThreeActionBuilder.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
...er/deciders/jvm/old_gen/LevelTwoActionBuilder.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
...ker/deciders/jvm/old_gen/OldGenDecisionPolicy.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
...erformanceanalyzer/rca/framework/core/RcaConf.java 51.96% <33.33%> (-0.26%) 32.00 <1.00> (-1.00)
...nfigs/decider/jvm/LevelTwoActionBuilderConfig.java 42.85% <42.85%> (ø) 1.00 <1.00> (?)
...onfigs/decider/jvm/OldGenDecisionPolicyConfig.java 45.00% <45.00%> (ø) 1.00 <1.00> (?)
...nfigs/decider/jvm/LevelOneActionBuilderConfig.java 50.00% <50.00%> (ø) 1.00 <1.00> (?)
... and 28 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2f6ba39...d7ef339. Read the comment docs.

@rguo-aws rguo-aws requested a review from yojs August 4, 2020 17:25
Copy link
Member

@yojs yojs left a comment

Choose a reason for hiding this comment

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

My two cents would be that we simplify the LevelAction classes further. I understand that once we have decided the level of jvm old-gen pressure we are in, the classes help us decide what we want to touch and in what order and how much of the knob we want to turn for it (decrease it in steps or wipe it clean).

It might make sense to define this in a yml and have just one level class that reads and takes actions. We may decide if the yml will be for code level config or something that operators can change but having it might make the logic more clear. What do you think ?

@rguo-aws rguo-aws requested review from sidheart and yojs August 5, 2020 21:03
Comment on lines 43 to 49
return LevelThreeActionBuilder.newBuilder(esNode, nodeConfigCache).build();
}
else if (oldGenUsage >= OLD_GEN_THRESHOLD_LEVEL_TWO) {
return LevelTwoActionBuilder.newBuilder(esNode, nodeConfigCache).build();
}
else if (oldGenUsage >= OLD_GEN_THRESHOLD_LEVEL_ONE) {
return LevelOneActionBuilder.newBuilder(esNode, nodeConfigCache).build();
Copy link
Contributor

Choose a reason for hiding this comment

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

This is very neat for this particular use case, but these actionbuilders aren't reusable

Copy link
Contributor

Choose a reason for hiding this comment

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

After rereading this my thoughts are the same. I don't understand what problem we were trying to solve by using the builder pattern here. We don't actually use the builders as legitimate builders, they're just wrappers around specific logic for generating a list of actions given a known bucket level. Why can't the static variables be held in this class with the List generated in actions() itself? Who would reuse these classes down the line?

Copy link
Contributor

Choose a reason for hiding this comment

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

The only moderately complex logic seems to live entirely in LevelTwoActionBuilder#actionPriorityForQueue(), but might not this just live in a function in this class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, the complex logic right now only sit in Level two but as I mention above, we need to collect more data from experiment and then make changes based on that. So now level 1 & 3 are more like placeholder with very simple logics in it and each bucket in JVM decider can be evolved independently in the future.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with Sid, I don't really see a need for the common base class here. We have different strategies for each level that we want to be able to evolve independently. A simple interface might be enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This base class approach was suggested by Joydeep because he though we can move those common code into base class. Yes, I agree with you. We don't necessarily need inheritance here and each level can evolve independently. Removed the base class

Comment on lines 43 to 49
return LevelThreeActionBuilder.newBuilder(esNode, nodeConfigCache).build();
}
else if (oldGenUsage >= OLD_GEN_THRESHOLD_LEVEL_TWO) {
return LevelTwoActionBuilder.newBuilder(esNode, nodeConfigCache).build();
}
else if (oldGenUsage >= OLD_GEN_THRESHOLD_LEVEL_ONE) {
return LevelOneActionBuilder.newBuilder(esNode, nodeConfigCache).build();
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with Sid, I don't really see a need for the common base class here. We have different strategies for each level that we want to be able to evolve independently. A simple interface might be enough.

Copy link
Contributor

@vigyasharma vigyasharma left a comment

Choose a reason for hiding this comment

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

There's some conflict across PRs. Will wait till we consolidate before approving.

// TODO : read priority from yml if customer wants to override default ordering
@Override
protected void actionPriorityFilter() {
actionFilter.put(ResourceEnum.FIELD_DATA_CACHE, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

I see. But from current changes, I don't see any action being added to actionFilter as false, so it seems like we just add actions to the actionFilter map as true, and pick all of them in build for each level*ActionBuilder. What am i missing?

Copy link
Contributor

@vigyasharma vigyasharma left a comment

Choose a reason for hiding this comment

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

Looks good. Will you add tests in a separate PR? If so, can you create an issue to track it?

Comment on lines +84 to +87
public double getStepSize(ResourceEnum cacheType) {
ThresholdConfig<Double> threshold = getThresholdConfig(cacheType);
return (threshold.upperBound() - threshold.lowerBound()) / (double) getTotalStepCount();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

// tie breaker
else {
if (workLoadTypeConfig.preferIngestOverSearch()) {
actionFilter.put(ResourceEnum.WRITE_THREADPOOL, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

if ingest is preferable, we should downsize search queue, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for catching this. Yes we should downsize search queue instead.

Comment on lines +38 to +39
priorityOrder = new Config(PRIORITY_ORDER_CONFIG_NAME, configs.getValue(),
DEFAULT_PRIORITY_ORDER, List.class);
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this work? I was having trouble casting with generics

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, casting to a raw list still works. it can still pass the UTs that Adithya wrote which overrides the config settings in rca.conf and read this object to verify the changes.

private Predicate<List<String>> listValidator;

public WorkLoadTypeConfig(NestedConfig configs) {
listValidator = (list) -> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since there is only search and ingest (2 values), we can make this simpler by renaming the config. Instead of taking a list, we can do things like:

{ "decider-config-settings": {
    "prefer-ingest-over-search": true
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done. changed the config to
"workload-type": {
"prefer-ingest": true,
"prefer-search": false
},

This will allow user to not assign workload preference to any queue type

Copy link
Contributor

@sidheart sidheart left a comment

Choose a reason for hiding this comment

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

lgtm thanks for cleaning this up

Comment on lines +84 to +87
public double getStepSize(ResourceEnum cacheType) {
ThresholdConfig<Double> threshold = getThresholdConfig(cacheType);
return (threshold.upperBound() - threshold.lowerBound()) / (double) getTotalStepCount();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

@rguo-aws rguo-aws merged commit 1decacb into master Sep 3, 2020
@rguo-aws rguo-aws deleted the rguo-jvm-decider branch September 3, 2020 21:35
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature New feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants