blob: 3200f83f1508bb376c6f498a02f1db732ba3662e [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "io/cache/async_cache_write_manager_metrics.h"
#include "util/time.h"
namespace doris::io {
AsyncCacheWriteManager::Metrics::Metrics(AsyncCacheWriteManager& manager, const char* prefix) {
// Keep the per-disk scrape surface limited to capacity, lifecycle, and outcome metrics. The
// unnamed bvars below retain focused test and benchmark diagnostics without multiplying
// Prometheus series for every file-cache instance.
_running_worker_count_metric = std::make_shared<bvar::PassiveStatus<size_t>>(
prefix, "async_cache_write_running_worker_count",
[](void* manager) {
return static_cast<AsyncCacheWriteManager*>(manager)->running_worker_count();
},
&manager);
_buffer_memory_metric = std::make_shared<bvar::PassiveStatus<int64_t>>(
prefix, "async_cache_write_buffer_memory_bytes",
[](void* manager) {
return static_cast<AsyncCacheWriteManager*>(manager)->buffer_memory_bytes();
},
&manager);
_submitted_metric = std::make_shared<bvar::Adder<uint64_t>>(
prefix, "async_cache_write_submitted_task_count");
_submitted_bytes_metric = std::make_shared<bvar::Adder<uint64_t>>();
_finished_metric = std::make_shared<bvar::Adder<uint64_t>>();
_finished_bytes_metric = std::make_shared<bvar::Adder<uint64_t>>();
_worker_finished_metric = std::make_shared<bvar::Adder<uint64_t>>();
_worker_finished_bytes_metric = std::make_shared<bvar::Adder<uint64_t>>();
_evicted_oldest_metric = std::make_shared<bvar::Adder<uint64_t>>(
prefix, "async_cache_write_evicted_oldest_task_count");
_evicted_oldest_bytes_metric = std::make_shared<bvar::Adder<uint64_t>>();
_evicted_oldest_age_metric = std::make_shared<bvar::LatencyRecorder>();
_rejected_metric = std::make_shared<bvar::Adder<uint64_t>>();
_reject_not_running_metric = std::make_shared<bvar::Adder<uint64_t>>();
_reject_backpressure_metric = std::make_shared<bvar::Adder<uint64_t>>();
_buffer_alloc_fail_metric = std::make_shared<bvar::Adder<uint64_t>>();
_submit_latency_metric = std::make_shared<bvar::LatencyRecorder>();
_buffer_alloc_latency_metric = std::make_shared<bvar::LatencyRecorder>();
_queue_wait_latency_metric = std::make_shared<bvar::LatencyRecorder>();
_queue_lock_wait_latency_metric = std::make_shared<bvar::LatencyRecorder>();
_queue_lock_hold_latency_metric = std::make_shared<bvar::LatencyRecorder>();
_worker_task_latency_metric = std::make_shared<bvar::LatencyRecorder>();
_get_or_set_latency_metric = std::make_shared<bvar::LatencyRecorder>();
_append_latency_metric = std::make_shared<bvar::LatencyRecorder>();
_finalize_latency_metric = std::make_shared<bvar::LatencyRecorder>();
_skip_downloaded_metric = std::make_shared<bvar::Adder<uint64_t>>();
_skip_downloading_metric = std::make_shared<bvar::Adder<uint64_t>>();
_skip_partial_overlap_metric = std::make_shared<bvar::Adder<uint64_t>>();
_drop_stale_epoch_metric = std::make_shared<bvar::Adder<uint64_t>>();
_drop_stale_cache_epoch_metric = std::make_shared<bvar::Adder<uint64_t>>();
_drop_stale_key_epoch_metric = std::make_shared<bvar::Adder<uint64_t>>();
_cache_epoch_invalidate_metric = std::make_shared<bvar::Adder<uint64_t>>();
_key_epoch_invalidate_metric = std::make_shared<bvar::Adder<uint64_t>>();
_skip_deleting_metric = std::make_shared<bvar::Adder<uint64_t>>();
_append_fail_metric = std::make_shared<bvar::Adder<uint64_t>>();
_finalize_fail_metric = std::make_shared<bvar::Adder<uint64_t>>();
}
void AsyncCacheWriteManager::Metrics::record_stale_epoch(StaleEpochReason reason) {
*_drop_stale_epoch_metric << 1;
if (reason == StaleEpochReason::CACHE) {
*_drop_stale_cache_epoch_metric << 1;
} else {
*_drop_stale_key_epoch_metric << 1;
}
}
void AsyncCacheWriteManager::Metrics::record_epoch_invalidation(EpochInvalidationScope scope) {
if (scope == EpochInvalidationScope::CACHE) {
*_cache_epoch_invalidate_metric << 1;
} else {
*_key_epoch_invalidate_metric << 1;
}
}
void AsyncCacheWriteManager::Metrics::record_task_submitted(size_t bytes) {
*_submitted_metric << 1;
*_submitted_bytes_metric << bytes;
}
void AsyncCacheWriteManager::Metrics::record_task_rejected(RejectionReason reason) {
*_rejected_metric << 1;
if (reason == RejectionReason::NOT_RUNNING) {
*_reject_not_running_metric << 1;
} else {
*_reject_backpressure_metric << 1;
}
}
void AsyncCacheWriteManager::Metrics::record_task_finalized(const AsyncCacheWriteTask& task,
TaskFinalizationReason reason) {
const size_t bytes = task.buffer_size();
if (reason == TaskFinalizationReason::WORKER_FINISHED) {
*_worker_finished_metric << 1;
*_worker_finished_bytes_metric << bytes;
} else {
*_evicted_oldest_metric << 1;
*_evicted_oldest_bytes_metric << bytes;
*_evicted_oldest_age_metric << (MonotonicMicros() - task.submit_ts_us);
}
*_finished_metric << 1;
*_finished_bytes_metric << bytes;
}
void AsyncCacheWriteManager::Metrics::record_buffer_allocation_failure() {
*_buffer_alloc_fail_metric << 1;
}
void AsyncCacheWriteManager::Metrics::record_submit_latency(int64_t latency_us) {
*_submit_latency_metric << latency_us;
}
void AsyncCacheWriteManager::Metrics::record_buffer_allocation_latency(int64_t latency_us) {
*_buffer_alloc_latency_metric << latency_us;
}
void AsyncCacheWriteManager::Metrics::record_queue_wait_latency(int64_t latency_us) {
*_queue_wait_latency_metric << latency_us;
}
void AsyncCacheWriteManager::Metrics::record_worker_task_latency(int64_t latency_us) {
*_worker_task_latency_metric << latency_us;
}
void AsyncCacheWriteManager::Metrics::record_get_or_set_latency(int64_t latency_us) {
*_get_or_set_latency_metric << latency_us;
}
void AsyncCacheWriteManager::Metrics::record_block_operation_latency(BlockOperation operation,
int64_t latency_us) {
if (operation == BlockOperation::APPEND) {
*_append_latency_metric << latency_us;
} else {
*_finalize_latency_metric << latency_us;
}
}
void AsyncCacheWriteManager::Metrics::record_block_operation_failure(BlockOperation operation) {
if (operation == BlockOperation::APPEND) {
*_append_fail_metric << 1;
} else {
*_finalize_fail_metric << 1;
}
}
void AsyncCacheWriteManager::Metrics::record_skipped_block(SkippedBlockReason reason) {
switch (reason) {
case SkippedBlockReason::DOWNLOADED:
*_skip_downloaded_metric << 1;
break;
case SkippedBlockReason::DOWNLOADING:
*_skip_downloading_metric << 1;
break;
case SkippedBlockReason::PARTIAL_OVERLAP:
*_skip_partial_overlap_metric << 1;
break;
case SkippedBlockReason::DELETING:
*_skip_deleting_metric << 1;
break;
}
}
int64_t AsyncCacheWriteManager::Metrics::queue_lock_wait_p99_us() const {
return _queue_lock_wait_latency_metric->latency_percentile(0.99);
}
int64_t AsyncCacheWriteManager::Metrics::queue_lock_hold_p99_us() const {
return _queue_lock_hold_latency_metric->latency_percentile(0.99);
}
uint64_t AsyncCacheWriteManager::Metrics::evicted_oldest_count() const {
return _evicted_oldest_metric->get_value();
}
AsyncCacheWriteManager::Metrics::Snapshot AsyncCacheWriteManager::Metrics::snapshot() const {
return Snapshot {
.submitted = _submitted_metric->get_value(),
.submitted_bytes = _submitted_bytes_metric->get_value(),
.finished = _finished_metric->get_value(),
.finished_bytes = _finished_bytes_metric->get_value(),
.worker_finished = _worker_finished_metric->get_value(),
.worker_finished_bytes = _worker_finished_bytes_metric->get_value(),
.evicted_oldest = _evicted_oldest_metric->get_value(),
.evicted_oldest_bytes = _evicted_oldest_bytes_metric->get_value(),
.evicted_oldest_age_count = _evicted_oldest_age_metric->count(),
.rejected = _rejected_metric->get_value(),
.reject_backpressure = _reject_backpressure_metric->get_value(),
.buffer_alloc_fail = _buffer_alloc_fail_metric->get_value(),
.submit_latency_count = _submit_latency_metric->count(),
.buffer_alloc_latency_count = _buffer_alloc_latency_metric->count(),
.queue_wait_latency_count = _queue_wait_latency_metric->count(),
.worker_task_latency_count = _worker_task_latency_metric->count(),
.get_or_set_latency_count = _get_or_set_latency_metric->count(),
.append_latency_count = _append_latency_metric->count(),
.finalize_latency_count = _finalize_latency_metric->count(),
.skip_downloaded = _skip_downloaded_metric->get_value(),
.skip_downloading = _skip_downloading_metric->get_value(),
.skip_partial_overlap = _skip_partial_overlap_metric->get_value(),
.drop_stale_key_epoch = _drop_stale_key_epoch_metric->get_value(),
.cache_epoch_invalidate = _cache_epoch_invalidate_metric->get_value(),
.key_epoch_invalidate = _key_epoch_invalidate_metric->get_value(),
.skip_deleting = _skip_deleting_metric->get_value(),
};
}
} // namespace doris::io