Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client: implement qos based on leakybucket algorithm #268

Merged
merged 1 commit into from
Mar 26, 2021

Conversation

wu-hanqing
Copy link
Contributor

What problem does this PR solve?

Issue Number: close #xxx

Problem Summary:

What is changed and how it works?

What's Changed:

How it Works:

Side effects(Breaking backward compatibility? Performance regression?):

Check List

  • Relevant documentation/comments is changed or added
  • I acknowledge that all my contributions will be made under the project's license

@wu-hanqing
Copy link
Contributor Author

recheck

1 similar comment
@wu-hanqing
Copy link
Contributor Author

recheck

@wu-hanqing
Copy link
Contributor Author

recheck

7 similar comments
@wu-hanqing
Copy link
Contributor Author

recheck

@wu-hanqing
Copy link
Contributor Author

recheck

@wu-hanqing
Copy link
Contributor Author

recheck

@wu-hanqing
Copy link
Contributor Author

recheck

@wu-hanqing
Copy link
Contributor Author

recheck

@wu-hanqing
Copy link
Contributor Author

recheck

@wu-hanqing
Copy link
Contributor Author

recheck

@wu-hanqing
Copy link
Contributor Author

recheck

conf/mds.conf Outdated
#### throttle options ####
#
# iops
mds.throttle.iopsMin=1800
Copy link
Contributor

Choose a reason for hiding this comment

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

Basis for the default value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

refer to the configuration of similar products of Ali Cloud and Tencent Cloud.

also, these configurations exceed the parameters of cinder.

@@ -40,6 +40,12 @@ topo_file_path=/etc/curve/topo.json
target_leader_range=3
check_leader_range_times=100
check_leader_range_interval=10
throttle_iops_min=1800
Copy link
Contributor

Choose a reason for hiding this comment

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

The default value can be set here: curve-ansible/roles/generate_config/templates/main.yml

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

BPS_WRITE = 5;
}

message ThrottleParams {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is it not directly included ThrottleType

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

@@ -72,6 +72,32 @@ enum class FileStatus {
BeingCloned,
};

struct ThrottleParams {
uint64_t limit;
Copy link
Contributor

Choose a reason for hiding this comment

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

Note the meaning of these parameters:
limit, burst, burstLength

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


FileThrottleParams throttleParams_;
uint64_t enabledThrottleFlag_;
std::vector<std::pair<uint64_t, common::TokenBucketThrottle*>> throttles_;
Copy link
Contributor

Choose a reason for hiding this comment

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

why not shared_ptr?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no need to use shared_ptr, because those TokenBucketThrottle's lifetime is simple

void UpdateThrottleParams(const FileThrottleParams& params);

private:
void ApplyThrottleLimit(uint64_t flag, uint64_t limit, uint64_t burst,
Copy link
Contributor

Choose a reason for hiding this comment

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

Annotation

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


void Get(uint64_t tokens);
bool Get(uint64_t tokens, google::protobuf::Closure* done);
int SetLimit(uint64_t average, uint64_t burst, uint64_t burstLength);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why the previous parameters is limit instead of average?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Limit in the previous parameter represents a value, abut for a token bucket, it needs to have an average generation rate to reach this limit. So, name this parameter and member value as average.

return TokensFilled(currentTick_) - TokensFilled(currentTick_ - 1);
}

private:
Copy link
Contributor

Choose a reason for hiding this comment

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

Appropriate notes

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

~TokenBucketThrottle();

void Get(uint64_t tokens);
bool Get(uint64_t tokens, google::protobuf::Closure* done);
Copy link
Contributor

Choose a reason for hiding this comment

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

When are the two get called?add notes please

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

@@ -0,0 +1,122 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

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

src/client/throttle.h not tested?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

add some test cases

void IOTracker::DoRead(MDSClient* mdsclient, const FInfo_t* fileInfo,
Throttle* throttle) {
if (throttle) {
throttle->Get(true, length_);
Copy link
Member

Choose a reason for hiding this comment

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

Will blocking here cause a deadlock ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If tokens is not enough, this call will block until tokens is available. And, when close a file, in throttle's destructor it will let a blocked requests pass.

@@ -184,6 +192,10 @@ void IOTracker::DoWrite(MDSClient* mdsclient, const FInfo_t* fileInfo) {
break;
}

if (throttle) {
throttle->Get(false, length_);
Copy link
Member

Choose a reason for hiding this comment

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

Have you tested performance after throttle here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tested.
For IOPS throttle, the Get operation can exceed 100,000 qps.
and if disable all throttle, the performance is basically unchanged

@@ -37,6 +39,18 @@ inline uint64_t MaxPowerTimesLessEqualValue(uint64_t value) {
return pow;
}

template <typename T, typename Compare>
Copy link
Member

Choose a reason for hiding this comment

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

Annotation

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

@wu-hanqing wu-hanqing force-pushed the feature/tokenbucket branch 2 times, most recently from 192dc9e to 32d8cd5 Compare March 9, 2021 06:53
void Get(uint64_t tokens);

/**
* @brief Get tokens, return false if the available token is not enough,
Copy link
Member

Choose a reason for hiding this comment

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

return True if the available token is not enough ?

* and when the requirment is met, it will call done->Run()
* @return return true if got enough tokens, otherwise return false
*/
bool Get(uint64_t tokens, google::protobuf::Closure* done);
Copy link
Member

Choose a reason for hiding this comment

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

If this function is only called in the class 'TokenBucketThrottle', it can be 'private'.

@wu-hanqing wu-hanqing force-pushed the feature/tokenbucket branch 3 times, most recently from 9d63087 to 5636d22 Compare March 24, 2021 08:57
@wu-hanqing wu-hanqing changed the title client: implement qos based on tokenbucket algorithm client: implement qos based on leakybucket algorithm Mar 24, 2021
@xu-chaojie xu-chaojie self-requested a review March 25, 2021 12:00
@ilixiaocui ilixiaocui merged commit ff8d9da into opencurve:master Mar 26, 2021
@wu-hanqing wu-hanqing deleted the feature/tokenbucket branch March 29, 2021 08:52
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.

None yet

3 participants