Skip to content

Commit

Permalink
[webui] KUDU-844 and other /tablet-rowsetlayout-svg improvements
Browse files Browse the repository at this point in the history
This patch addresses KUDU-844, an issue where rowsets unavailable for
compaction weren't shown in the rowset SVG layout. These rowsets aren't
displayed because the rowset SVG is built from compaction policy output,
and the compaction policy obviously does not consider rowsets that
aren't available for compaction. There are two kinds of rowsets that
will be excluded: the memrowset, which doesn't belong in the SVG output,
and rowsets currently being compacted. The latter are tricky to
integrate into the SVG because there is a race with the compaction
finishing, and after a compaction the rowset may no longer be
relevant (merge compaction), or its bounds may have changed (major delta
compaction). Working around this problem would be a lot of effort, just
to add dubiously useful information to the layout diagram. Instead, I
opted just to disclose the issue: there's a note saying how many rowsets
are currently being compacted included under the layout diagram.

I also made a couple of quality of life improvements to the rowset
layout page.
1. I removed the size label from the rowsets rectangles in the SVG. They
   didn't add so much individually, but they did make it really hard to
   see what was going in once there were a lot of rowsets.
2. I added a table with the 5-number summary of rowset sizes, to make up
   for taking away the individual sizes in the diagram. I chose the
   summary because in my experience it's the best way to get a quick
   idea what a distribution looks like (better than, e.g., the mean and
   standard deviation.)

Here's the original way a busy layout diagram looks with the sizes:

https://github.com/wdberkeley/kudu/blob/svg_screenshots/layout.png

And here's how it looks without them:

https://github.com/wdberkeley/kudu/blob/svg_screenshots/layout_no_text.png

Here's an example summary table:

https://github.com/wdberkeley/kudu/blob/svg_screenshots/new_layout_page.png

Finally, I added some <tr> pairs that were missing from the /tablets
template.

Change-Id: I7475f14093a187fde1329546b10c314da49fe08a
Reviewed-on: http://gerrit.cloudera.org:8080/11613
Tested-by: Kudu Jenkins
Reviewed-by: Andrew Wong <[email protected]>
  • Loading branch information
wdberkeley authored and andrwng committed Oct 9, 2018
1 parent 9ec8d28 commit 91faf2a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 9 deletions.
4 changes: 0 additions & 4 deletions src/kudu/tablet/svg_dump.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,6 @@ void DumpSVG(const vector<RowSetInfo>& candidates,
R"(<rect x="$0" y="$1" width="$2" height="$3" stroke="#000" fill="$4"/>)",
x, y, width, kRowHeight, color)
<< endl;
out << Substitute(R"+(<text x="$0" y="$1" width="$2" height="$3" )+"
R"+(fill="rgb(0,0,0)">$4MB</text>)+",
x, y + kRowHeight, width, kRowHeight, cand->size_mb())
<< endl;
}
}

Expand Down
70 changes: 67 additions & 3 deletions src/kudu/tablet/tablet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ using kudu::MaintenanceManager;
using kudu::clock::HybridClock;
using kudu::fs::IOContext;
using kudu::log::LogAnchorRegistry;
using std::endl;
using std::ostream;
using std::pair;
using std::shared_ptr;
Expand Down Expand Up @@ -2299,13 +2300,76 @@ void Tablet::PrintRSLayout(ostream* o) {
RowSetInfo::CollectOrdered(*rowsets_copy, &min, &max);
DumpCompactionSVG(min, picked, o, /*print_xml_header=*/false);

*o << "<h2>Compaction policy log</h2>" << std::endl;
// Compaction policy ignores rowsets unavailable for compaction. This is good,
// except it causes the SVG to be potentially missing rowsets. It's hard to
// take these presently-compacting rowsets into account because we are racing
// against the compaction finishing, and at the end of the compaction the
// rowsets might no longer exist (merge compaction) or their bounds may have
// changed (major delta compaction). So, let's just disclose how many of these
// rowsets there are.
int num_rowsets_unavailable_for_compaction = std::count_if(
rowsets_copy->all_rowsets().begin(),
rowsets_copy->all_rowsets().end(),
[](const shared_ptr<RowSet>& rowset) {
// The first condition excludes the memrowset.
return rowset->metadata() && !rowset->IsAvailableForCompaction();
});
*o << Substitute("<div><p>In addition to the rowsets pictured and listed, "
"there are $0 rowset(s) currently undergoing compactions."
"</p></div>",
num_rowsets_unavailable_for_compaction)
<< endl;

// Compute some summary statistics for the tablet's rowsets.
const auto num_rowsets = min.size();
if (num_rowsets > 0) {
vector<int64_t> rowset_sizes;
rowset_sizes.reserve(num_rowsets);
for (const auto& rsi : min) {
rowset_sizes.push_back(rsi.size_bytes());
}
*o << "<table class=\"table tablet-striped table-hover\">" << endl;
// Compute the stats quick'n'dirty by sorting and looking at approximately
// the right spot.
// TODO(wdberkeley): Could use an O(n) quickselect-based algorithm.
// TODO(wdberkeley): A bona fide box-and-whisker plot would be nice.
// d3.js can make really nice ones: https://bl.ocks.org/mbostock/4061502.
std::sort(rowset_sizes.begin(), rowset_sizes.end());
const auto size_bytes_min = rowset_sizes[0];
const auto size_bytes_first_quartile = rowset_sizes[num_rowsets / 4];
const auto size_bytes_median = rowset_sizes[num_rowsets / 2];
const auto size_bytes_third_quartile = rowset_sizes[3 * num_rowsets / 4];
const auto size_bytes_max = rowset_sizes[num_rowsets - 1];
*o << Substitute("<thead><tr>"
" <th>Statistic</th>"
" <th>Approximate Value</th>"
"<tr></thead>"
"<tbody>"
" <tr><td>Count</td><td>$0</td></tr>"
" <tr><td>Min</td><td>$1</td></tr>"
" <tr><td>First quartile</td><td>$2</td></tr>"
" <tr><td>Median</td><td>$3</td></tr>"
" <tr><td>Third quartile</td><td>$4</td></tr>"
" <tr><td>Max</td><td>$5</td></tr>"
"<tbody>",
num_rowsets,
HumanReadableNumBytes::ToString(size_bytes_min),
HumanReadableNumBytes::ToString(size_bytes_first_quartile),
HumanReadableNumBytes::ToString(size_bytes_median),
HumanReadableNumBytes::ToString(size_bytes_third_quartile),
HumanReadableNumBytes::ToString(size_bytes_max));
*o << "</table>" << endl;
}

// TODO(wdberkeley): Should we even display this? It's one line per rowset
// and doesn't contain any useful information except each rowset's size.
*o << "<h2>Compaction policy log</h2>" << endl;

*o << "<pre>" << std::endl;
for (const string& s : log) {
*o << EscapeForHtmlToString(s) << std::endl;
*o << EscapeForHtmlToString(s) << endl;
}
*o << "</pre>" << std::endl;
*o << "</pre>" << endl;
}

string Tablet::LogPrefix() const {
Expand Down
4 changes: 2 additions & 2 deletions www/tablets.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ There are no tablet replicas.
<thead><tr><th>Status</th><th>Count</th><th>Percentage</th></tr></thead>
<tbody>
{{#statuses}}
<td>{{status}}</td><td>{{count}}</td><td>{{percentage}}</td>
<tr><td>{{status}}</td><td>{{count}}</td><td>{{percentage}}</td></tr>
{{/statuses}}
</tbody>
<tfoot><tr><td>Total</td><td>{{total_count}}</td><td></td></tfoot>
Expand Down Expand Up @@ -70,7 +70,7 @@ There are no tablet replicas.
<thead><tr><th>Status</th><th>Count</th><th>Percentage</th></tr></thead>
<tbody>
{{#replica_statuses}}
<td>{{status}}</td><td>{{count}}</td><td>{{percentage}}</td>
<tr><td>{{status}}</td><td>{{count}}</td><td>{{percentage}}</td></tr>
{{/replica_statuses}}
</tbody>
<tfoot><tr><td>Total</td><td>{{total_count}}</td><td></td></tfoot>
Expand Down

0 comments on commit 91faf2a

Please sign in to comment.