This is an automated email from the ASF dual-hosted git repository.
adar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git
commit ca957fb86736b1e07b18d80fdfa4e41c191e7072
Author: acelyc111 <405403881@qq.com>
AuthorDate: Mon Dec 16 12:21:34 2019 +0800
[tablet] Add new metrics to indicate the last read/write time
Add new metrics 'last_read_elapsed_seconds' and
'last_write_elapsed_seconds' for tablet to indicate the last read and
write operation on the tablet. We can judge whether a tablet is 'hot'
or 'cold' by these metrics.
Change-Id: I90738ba90eaa8f78c8d721dde2eed2b723d5572d
Reviewed-on: http://gerrit.cloudera.org:8080/14912
Tested-by: Kudu Jenkins
Reviewed-by: Adar Dembo <adar@cloudera.com>
---
src/kudu/tablet/tablet.cc | 44 +++++++++++++++++++++++++++++++++++++-
src/kudu/tablet/tablet.h | 19 +++++++++++++++-
src/kudu/tablet/tablet_metrics.h | 2 +-
src/kudu/tserver/tablet_service.cc | 29 ++++++++++++++-----------
4 files changed, 78 insertions(+), 16 deletions(-)
diff --git a/src/kudu/tablet/tablet.cc b/src/kudu/tablet/tablet.cc
index 3802a68..032ceb8 100644
--- a/src/kudu/tablet/tablet.cc
+++ b/src/kudu/tablet/tablet.cc
@@ -163,6 +163,18 @@ METRIC_DEFINE_gauge_size(tablet, num_rowsets_on_disk, "Tablet Number
of Rowsets
kudu::MetricUnit::kUnits,
"Number of diskrowsets in this tablet",
kudu::MetricLevel::kInfo);
+METRIC_DEFINE_gauge_uint64(tablet, last_read_elapsed_time, "Seconds Since Last Read",
+ kudu::MetricUnit::kSeconds,
+ "The elapsed time, in seconds, since the last read operation on
this "
+ "tablet, or since this Tablet object was created on current tserver
if "
+ "it hasn't been read since then.",
+ kudu::MetricLevel::kDebug);
+METRIC_DEFINE_gauge_uint64(tablet, last_write_elapsed_time, "Seconds Since Last Write",
+ kudu::MetricUnit::kSeconds,
+ "The elapsed time, in seconds, since the last write operation
on this "
+ "tablet, or since this Tablet object was created on current tserver
if "
+ "it hasn't been written to since then.",
+ kudu::MetricLevel::kDebug);
using kudu::MaintenanceManager;
using kudu::clock::HybridClock;
@@ -213,7 +225,9 @@ Tablet::Tablet(scoped_refptr<TabletMetadata> metadata,
next_mrs_id_(0),
clock_(std::move(clock)),
rowsets_flush_sem_(1),
- state_(kInitialized) {
+ state_(kInitialized),
+ last_write_time_(MonoTime::Now()),
+ last_read_time_(MonoTime::Now()) {
CHECK(schema()->has_column_ids());
compaction_policy_.reset(CreateCompactionPolicy());
@@ -234,6 +248,12 @@ Tablet::Tablet(scoped_refptr<TabletMetadata> metadata,
METRIC_num_rowsets_on_disk.InstantiateFunctionGauge(
metric_entity_, Bind(&Tablet::num_rowsets, Unretained(this)))
->AutoDetach(&metric_detacher_);
+ METRIC_last_read_elapsed_time.InstantiateFunctionGauge(
+ metric_entity_, Bind(&Tablet::LastReadElapsedSeconds, Unretained(this)), MergeType::kMin)
+ ->AutoDetach(&metric_detacher_);
+ METRIC_last_write_elapsed_time.InstantiateFunctionGauge(
+ metric_entity_, Bind(&Tablet::LastWriteElapsedSeconds, Unretained(this)), MergeType::kMin)
+ ->AutoDetach(&metric_detacher_);
METRIC_merged_entities_count_of_tablet.InstantiateHidden(metric_entity_, 1);
}
@@ -916,6 +936,11 @@ Status Tablet::ApplyRowOperations(WriteTransactionState* tx_state) {
DCHECK(row_op->has_result());
}
+ {
+ std::lock_guard<rw_spinlock> l(last_rw_time_lock_);
+ last_write_time_ = MonoTime::Now();
+ }
+
if (metrics_ && num_ops > 0) {
metrics_->AddProbeStats(tx_state->mutable_op_stats(0), num_ops, tx_state->arena());
}
@@ -1957,6 +1982,23 @@ size_t Tablet::OnDiskDataSize() const {
return ret;
}
+uint64_t Tablet::LastReadElapsedSeconds() const {
+ shared_lock<rw_spinlock> l(last_rw_time_lock_);
+ DCHECK(last_read_time_.Initialized());
+ return static_cast<uint64_t>((MonoTime::Now() - last_read_time_).ToSeconds());
+}
+
+void Tablet::UpdateLastReadTime() const {
+ std::lock_guard<rw_spinlock> l(last_rw_time_lock_);
+ last_read_time_ = MonoTime::Now();
+}
+
+uint64_t Tablet::LastWriteElapsedSeconds() const {
+ shared_lock<rw_spinlock> l(last_rw_time_lock_);
+ DCHECK(last_write_time_.Initialized());
+ return static_cast<uint64_t>((MonoTime::Now() - last_write_time_).ToSeconds());
+}
+
size_t Tablet::DeltaMemStoresSize() const {
scoped_refptr<TabletComponents> comps;
GetComponents(&comps);
diff --git a/src/kudu/tablet/tablet.h b/src/kudu/tablet/tablet.h
index bbf7edb..653ccf3 100644
--- a/src/kudu/tablet/tablet.h
+++ b/src/kudu/tablet/tablet.h
@@ -48,6 +48,7 @@
#include "kudu/util/bloom_filter.h"
#include "kudu/util/locks.h"
#include "kudu/util/metrics.h"
+#include "kudu/util/monotime.h"
#include "kudu/util/rw_semaphore.h"
#include "kudu/util/semaphore.h"
#include "kudu/util/status.h"
@@ -61,7 +62,6 @@ class MaintenanceManager;
class MaintenanceOp;
class MaintenanceOpStats;
class MemTracker;
-class MonoDelta;
class RowBlock;
class ScanSpec;
class Throttler;
@@ -458,6 +458,11 @@ class Tablet {
uint64 target_chunk_size,
std::vector<KeyRange>* ranges);
+ // Update the last read operation timestamp.
+ // NOTE: It's a const function, because we have to call it in Iterator, where Tablet is
a const
+ // variable there.
+ void UpdateLastReadTime() const;
+
private:
friend class kudu::AlterTableTest;
friend class Iterator;
@@ -659,6 +664,13 @@ class Tablet {
static int64_t GetReplaySizeForIndex(int64_t min_log_index,
const ReplaySizeMap& size_map);
+ // The elapsed time, in seconds, since the last read operation on this tablet, or since
this
+ // Tablet object was created on current tserver if it hasn't been read since then.
+ uint64_t LastReadElapsedSeconds() const;
+
+ // Same as LastReadElapsedSeconds(), but for write operation.
+ uint64_t LastWriteElapsedSeconds() const;
+
// Test-only lock that synchronizes access to AssignTimestampAndStartTransactionForTests().
// Tests that use LocalTabletWriter take this lock to synchronize timestamp assignment,
// transaction start and safe time adjustment.
@@ -752,6 +764,11 @@ class Tablet {
std::vector<MaintenanceOp*> maintenance_ops_;
+ // Lock protecting access to 'last_write_time_' and 'last_read_time_'.
+ mutable rw_spinlock last_rw_time_lock_;
+ MonoTime last_write_time_;
+ mutable MonoTime last_read_time_;
+
DISALLOW_COPY_AND_ASSIGN(Tablet);
};
diff --git a/src/kudu/tablet/tablet_metrics.h b/src/kudu/tablet/tablet_metrics.h
index b17098f..1295b69 100644
--- a/src/kudu/tablet/tablet_metrics.h
+++ b/src/kudu/tablet/tablet_metrics.h
@@ -17,8 +17,8 @@
#ifndef KUDU_TABLET_TABLET_METRICS_H
#define KUDU_TABLET_TABLET_METRICS_H
+#include <cstddef>
#include <cstdint>
-#include <stddef.h>
#include "kudu/gutil/ref_counted.h"
#include "kudu/util/metrics.h"
diff --git a/src/kudu/tserver/tablet_service.cc b/src/kudu/tserver/tablet_service.cc
index 97a4cdd..6621b5f 100644
--- a/src/kudu/tserver/tablet_service.cc
+++ b/src/kudu/tserver/tablet_service.cc
@@ -27,6 +27,7 @@
#include <string>
#include <type_traits>
#include <unordered_set>
+#include <utility>
#include <vector>
#include <boost/optional/optional.hpp>
@@ -2665,19 +2666,7 @@ Status TabletServiceImpl::HandleContinueScanRequest(const ScanRequestPB*
req,
return s;
}
- // Update metrics based on this scan request.
- if (tablet) {
- // First, the number of rows/cells/bytes actually returned to the user.
- tablet->metrics()->scanner_rows_returned->IncrementBy(
- result_collector->NumRowsReturned());
- tablet->metrics()->scanner_cells_returned->IncrementBy(
- result_collector->NumRowsReturned() *
- scanner->client_projection_schema()->num_columns());
- tablet->metrics()->scanner_bytes_returned->IncrementBy(
- result_collector->ResponseSize());
- }
-
- // Then the number of rows/cells/bytes actually processed. Here we have to dig
+ // Calculate the number of rows/cells/bytes actually processed. Here we have to dig
// into the per-column iterator stats, sum them up, and then subtract out the
// total that we already reported in a previous scan.
vector<IteratorStats> stats_by_col;
@@ -2690,10 +2679,24 @@ Status TabletServiceImpl::HandleContinueScanRequest(const ScanRequestPB*
req,
scanner->set_already_reported_stats(total_stats);
TRACE_COUNTER_INCREMENT(SCANNER_BYTES_READ_METRIC_NAME, delta_stats.bytes_read);
+ // Update metrics based on this scan request.
if (tablet) {
+ // The number of rows/cells/bytes actually returned to the user.
+ tablet->metrics()->scanner_rows_returned->IncrementBy(
+ result_collector->NumRowsReturned());
+ tablet->metrics()->scanner_cells_returned->IncrementBy(
+ result_collector->NumRowsReturned() *
+ scanner->client_projection_schema()->num_columns());
+ tablet->metrics()->scanner_bytes_returned->IncrementBy(
+ result_collector->ResponseSize());
+
+ // The number of rows/cells/bytes actually processed.
tablet->metrics()->scanner_rows_scanned->IncrementBy(rows_scanned);
tablet->metrics()->scanner_cells_scanned_from_disk->IncrementBy(delta_stats.cells_read);
tablet->metrics()->scanner_bytes_scanned_from_disk->IncrementBy(delta_stats.bytes_read);
+
+ // Last read timestamp.
+ tablet->UpdateLastReadTime();
}
*has_more_results = !req->close_scanner() && iter->HasNext() &&
|