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
os/bluestore: kvdb histogram #12620
os/bluestore: kvdb histogram #12620
Conversation
@@ -313,6 +313,8 @@ class RocksDBStore : public KeyValueDB { | |||
bufferlist value(); | |||
bufferptr value_as_ptr(); | |||
int status(); | |||
size_t key_size(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add 'override' keyword for this and the next declarations?
@@ -1770,6 +1770,7 @@ class BlueStore : public ObjectStore, | |||
} | |||
|
|||
void get_db_statistics(Formatter *f); | |||
void get_db_histogram(Formatter *f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'override' here?
@@ -150,6 +150,8 @@ class RocksDBStore : public KeyValueDB { | |||
|
|||
void close(); | |||
|
|||
void split(const std::string &s, char delim, std::vector<std::string> &elems); | |||
std::vector<std::string> split(const std::string &s, char delim); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we really need this form of split?
@@ -150,6 +150,8 @@ class RocksDBStore : public KeyValueDB { | |||
|
|||
void close(); | |||
|
|||
void split(const std::string &s, char delim, std::vector<std::string> &elems); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest to rename to split_stats or something to improve readability.
44bb025
to
4e56963
Compare
@ifed01 fixed the review comments, please review again. |
sample output of the histogram is below: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@varadakari sorry for splitting my review into 2 parts - didn't have enough time for complete review yesterday.
//histogram | ||
struct value_dist | ||
{ | ||
uint64_t count; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest to initialize struct members with 0 here and below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ifed01 these are part of the histogram, don't need to specifically initialize to 0, if the value doesn't exist in the map, it will be initialized to 0 by default.
uint64_t count; | ||
uint32_t max_len; | ||
}; | ||
typedef struct value_dist value_dist_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO one can simply define struct value_dist_t above - no need for duplicate type definitions(value_dist & value_dist_t) here.
uint32_t max_len; | ||
map<int, value_dist_t> val_map; // slab id to count and others | ||
}; | ||
typedef struct key_dist key_dist_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same here
pair<string,string> key(iter->raw_key()); | ||
|
||
if (key.first == PREFIX_SUPER) { | ||
key_hist[PREFIX_SUPER][key_slab].count++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest to introduce a helper func to update a specific key_hist entry in a single call.
e.g.
update_entry( key_hist, PREFIX_SUPER, key_size, value_size);
} | ||
else if (key.first == PREFIX_OBJ) { | ||
if (key.second.back() == ONODE_KEY_SUFFIX) { | ||
key_hist["o"][key_slab].count++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest to use symbolic names instead of explicit literals: "o", "x", etc
4e56963
to
e8c6d5c
Compare
@ifed01 addressed the comments, please review again. Have to move the local variables(maps for the histogram) to make the updates as a function. Otherwise rest of the logic is same. |
e8c6d5c
to
4344490
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM except code style violation for 'else' statements in void BlueStore::get_db_histogram
4344490
to
ad07526
Compare
@ifed01 Thanks for review, fixed the styling of if-else. |
i am not hitting this compilation error in my local copy. will rebase and try it again. |
ad07526
to
ae36aac
Compare
Fixed all the issues and all tests are passing now. |
ae36aac
to
07795bd
Compare
jenkins retest this please |
@liewegas could you please take look at this? |
|
||
const string PREFIX_ONODE = "o"; | ||
const string PREFIX_ONODE_SHARD = "x"; | ||
const string PREFIX_OTHER = "Z"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps instead of #defineing more of these we should just use strings ("onode", "other", etc.)?
|
||
map<string, map<int, struct key_dist> > key_hist; | ||
map<int, uint64_t> value_hist; // only value distribution histogram |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we put the histogram bits into a class? Should be able to include update_hist_entry?
@@ -1939,6 +1939,8 @@ bool OSD::asok_command(string command, cmdmap_t& cmdmap, string format, | |||
store->get_db_statistics(f); | |||
} else if (command == "dump_scrubs") { | |||
service.dumps_scrub(f); | |||
} else if (command == "dump_objectstore_db_histogram") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be a good idea to rename this something like "calculate_objectstore_db_histogram" to better suggest/convey that this is a very slow operation?
Signed-off-by: Varada Kari <varada.kari@sandisk.com>
Improves the presentation of rocksdb dump statistics Signed-off-by: Varada Kari <varada.kari@sandisk.com>
Avoids converting the key and value to string or bufferlist Signed-off-by: Varada Kari <varada.kari@sandisk.com>
07795bd
to
c877843
Compare
@liewegas Made the changes and repushed after rebasing, could you please review again? |
jenkins retest this please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few more nits, but otherwise looks good!
f->dump_unsigned("total_value_size", total_value_size); | ||
f->close_section(); | ||
|
||
f->open_object_section("rocksdb value distribution"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no spaces in formatter fields names please
f->open_object_section("rocksdb key-value histogram"); | ||
for (auto i : hist.key_hist) { | ||
f->dump_string("prefix", i.first); | ||
f->open_object_section("key-hist"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_ not -
f->close_section(); | ||
|
||
f->open_object_section("rocksdb key-value histogram"); | ||
for (auto i : hist.key_hist) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the dump of the histogram itself should be DBHistogram::dump()
@@ -1496,6 +1496,30 @@ class BlueStore : public ObjectStore, | |||
} | |||
}; | |||
|
|||
struct DBHistogram { | |||
struct value_dist | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{ on previous line
{ | ||
uint64_t count; | ||
uint32_t max_len; | ||
map<int, struct value_dist> val_map; // slab id to count and others |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these comments should be like ///< so the doc generation can do its thing
Adding a asok to command to dump the key value distribution in a histogram fashion. Signed-off-by: Varada Kari <varada.kari@sandisk.com>
c877843
to
64af217
Compare
@liewegas Addressed the comments. Please have relook at the changes. |
Can you add a test to store_test.cc that triggers this so that the code path is tested? |
@varadakari ping |
Signed-off-by: Varada Kari <varada.kari@sandisk.com>
Signed-off-by: Varada Kari <varada.kari@sandisk.com>
@liewegas Added the unit test cases for stats and histogram. Please have a look. |
submodules for project are unmodified |
@liewegas if the tests are complete, could you merge this please? |
Generates a histogram of key value distribution for kvdb(rocksdb for now)