blob: 84eab7ac7e6414245517197600ea1f3a29d3fda5 [file] [log] [blame]
// 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 "runtime/memory/memory_profile.h"
#include "bvar/reducer.h"
#include "olap/metadata_adder.h"
#include "olap/schema_cache.h"
#include "olap/tablet_schema_cache.h"
#include "runtime/exec_env.h"
#include "runtime/memory/global_memory_arbitrator.h"
#include "runtime/memory/jemalloc_control.h"
#include "runtime/memory/mem_tracker_limiter.h"
#include "util/mem_info.h"
#include "util/runtime_profile.h"
namespace doris {
#include "common/compile_check_begin.h"
static bvar::Adder<int64_t> memory_all_tracked_sum_bytes("memory_all_tracked_sum_bytes");
static bvar::Adder<int64_t> memory_global_trackers_sum_bytes("memory_global_trackers_sum_bytes");
static bvar::Adder<int64_t> memory_metadata_trackers_sum_bytes(
"memory_metadata_trackers_sum_bytes");
static bvar::Adder<int64_t> memory_cache_trackers_sum_bytes("memory_cache_trackers_sum_bytes");
static bvar::Adder<int64_t> memory_query_trackers_sum_bytes("memory_query_trackers_sum_bytes");
static bvar::Adder<int64_t> memory_load_trackers_sum_bytes("memory_load_trackers_sum_bytes");
static bvar::Adder<int64_t> memory_compaction_trackers_sum_bytes(
"memory_compaction_trackers_sum_bytes");
static bvar::Adder<int64_t> memory_schema_change_trackers_sum_bytes(
"memory_schema_change_trackers_sum_bytes");
static bvar::Adder<int64_t> memory_other_trackers_sum_bytes("memory_other_trackers_sum_bytes");
static bvar::Adder<int64_t> memory_reserved_memory_bytes("memory_reserved_memory_bytes");
static bvar::Adder<int64_t> memory_all_tasks_memory_bytes("memory_all_tasks_memory_bytes");
static bvar::Adder<int64_t> memory_untracked_memory_bytes("memory_untracked_memory_bytes");
MemoryProfile::MemoryProfile() {
#ifdef ADDRESS_SANITIZER
_memory_overview_profile = std::make_unique<RuntimeProfile>("[ASAN]MemoryOverviewSnapshot");
#else
_memory_overview_profile = std::make_unique<RuntimeProfile>("MemoryOverviewSnapshot");
#endif
_global_memory_profile.set(std::make_unique<RuntimeProfile>("GlobalMemorySnapshot"));
_metadata_memory_profile.set(std::make_unique<RuntimeProfile>("MetadataMemorySnapshot"));
_cache_memory_profile.set(std::make_unique<RuntimeProfile>("CacheMemorySnapshot"));
_top_memory_tasks_profile.set(std::make_unique<RuntimeProfile>("TopMemoryTasksSnapshot"));
_tasks_memory_profile.set(std::make_unique<RuntimeProfile>("TasksMemorySnapshot"));
init_memory_overview_counter();
}
void MemoryProfile::init_memory_overview_counter() {
RuntimeProfile* untracked_memory_profile =
_memory_overview_profile->create_child("UntrackedMemory", true, false);
RuntimeProfile* tracked_memory_profile =
_memory_overview_profile->create_child("TrackedMemory", true, false);
RuntimeProfile* tasks_memory_overview_profile =
tracked_memory_profile->create_child("TasksMemory", true, false);
RuntimeProfile* tasks_memory_overview_details_profile =
tasks_memory_overview_profile->create_child("Details", true, false);
RuntimeProfile* memtable_overview_profile =
tracked_memory_profile->create_child("MemtableMemory", true, false);
RuntimeProfile* global_memory_overview_profile =
tracked_memory_profile->create_child("GlobalMemory", true, false);
RuntimeProfile* jvm_memory_overview_profile =
tracked_memory_profile->create_child("JvmMemory", true, false);
RuntimeProfile* metadata_memory_overview_profile =
tracked_memory_profile->create_child("MetadataMemory", true, false);
RuntimeProfile* cache_memory_overview_profile =
tracked_memory_profile->create_child("CacheMemory", true, false);
RuntimeProfile* jemalloc_memory_profile =
tracked_memory_profile->create_child("JemallocMemory", true, false);
RuntimeProfile* jemalloc_memory_details_profile =
jemalloc_memory_profile->create_child("Details", true, false);
// 1 add process memory counter
_process_physical_memory_usage_counter = _memory_overview_profile->AddHighWaterMarkCounter(
"PhysicalMemory(VmRSS)", TUnit::BYTES);
_process_virtual_memory_usage_counter = _memory_overview_profile->AddHighWaterMarkCounter(
"VirtualMemory(VmSize)", TUnit::BYTES);
// 2 add untracked/tracked memory counter
_untracked_memory_usage_counter =
untracked_memory_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
_tracked_memory_usage_counter =
tracked_memory_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
// 3 add Jemalloc memory counter
_jemalloc_memory_usage_counter =
jemalloc_memory_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
_jemalloc_cache_usage_counter =
jemalloc_memory_details_profile->AddHighWaterMarkCounter("Cache", TUnit::BYTES);
_jemalloc_metadata_usage_counter =
jemalloc_memory_details_profile->AddHighWaterMarkCounter("Metadata", TUnit::BYTES);
// 4 add global/metadata/cache/Jvm memory counter
_global_usage_counter =
global_memory_overview_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
_metadata_usage_counter =
metadata_memory_overview_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
_cache_usage_counter =
cache_memory_overview_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
_jvm_heap_memory_usage_counter =
jvm_memory_overview_profile->AddHighWaterMarkCounter("HeapMemory", TUnit::BYTES);
_jvm_non_heap_memory_usage_counter =
jvm_memory_overview_profile->AddHighWaterMarkCounter("NonHeapMemory", TUnit::BYTES);
// 5 add tasks memory counter
_tasks_memory_usage_counter =
tasks_memory_overview_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
// Reserved memory is the sum of all task reserved memory, is duplicated with all task memory counter.
_reserved_memory_usage_counter = tasks_memory_overview_profile->AddHighWaterMarkCounter(
"ReservedMemory", TUnit::BYTES, "Memory", 1);
// 6 add memtable memory counter
_memtable_memory_usage_counter =
memtable_overview_profile->AddHighWaterMarkCounter("MemtableMemory", TUnit::BYTES);
_query_usage_counter =
tasks_memory_overview_details_profile->AddHighWaterMarkCounter("Query", TUnit::BYTES);
_load_usage_counter =
tasks_memory_overview_details_profile->AddHighWaterMarkCounter("Load", TUnit::BYTES);
_compaction_usage_counter = tasks_memory_overview_details_profile->AddHighWaterMarkCounter(
"Compaction", TUnit::BYTES);
_schema_change_usage_counter = tasks_memory_overview_details_profile->AddHighWaterMarkCounter(
"SchemaChange", TUnit::BYTES);
_other_usage_counter =
tasks_memory_overview_details_profile->AddHighWaterMarkCounter("Other", TUnit::BYTES);
}
void MemoryProfile::refresh_memory_overview_profile() {
// 1 create profile
std::unique_ptr<RuntimeProfile> global_memory_profile =
std::make_unique<RuntimeProfile>("GlobalMemorySnapshot");
std::unique_ptr<RuntimeProfile> metadata_memory_profile =
std::make_unique<RuntimeProfile>("MetadataMemorySnapshot");
std::unique_ptr<RuntimeProfile> cache_memory_profile =
std::make_unique<RuntimeProfile>("CacheMemorySnapshot");
std::unique_ptr<RuntimeProfile> top_memory_tasks_profile =
std::make_unique<RuntimeProfile>("TopMemoryTasksSnapshot");
// 2 refresh process memory counter
COUNTER_SET(_process_physical_memory_usage_counter,
PerfCounters::get_vm_rss()); // from /proc VmRSS VmHWM
COUNTER_SET(_process_virtual_memory_usage_counter,
PerfCounters::get_vm_size()); // from /proc VmSize VmPeak
// 2 refresh metadata memory tracker
ExecEnv::GetInstance()->tablets_no_cache_mem_tracker()->set_consumption(
MetadataAdder<TabletMeta>::get_all_tablets_size() -
TabletSchemaCache::instance()->value_mem_consumption() -
SchemaCache::instance()->value_mem_consumption());
ExecEnv::GetInstance()->rowsets_no_cache_mem_tracker()->set_consumption(
MetadataAdder<RowsetMeta>::get_all_rowsets_size());
ExecEnv::GetInstance()->segments_no_cache_mem_tracker()->set_consumption(
MetadataAdder<segment_v2::Segment>::get_all_segments_estimate_size() -
SegmentLoader::instance()->cache_mem_usage());
// 4 refresh tracked memory counter
std::unordered_map<MemTrackerLimiter::Type, int64_t> type_mem_sum = {
{MemTrackerLimiter::Type::GLOBAL, 0}, {MemTrackerLimiter::Type::QUERY, 0},
{MemTrackerLimiter::Type::LOAD, 0}, {MemTrackerLimiter::Type::COMPACTION, 0},
{MemTrackerLimiter::Type::SCHEMA_CHANGE, 0}, {MemTrackerLimiter::Type::METADATA, 0},
{MemTrackerLimiter::Type::CACHE, 0}, {MemTrackerLimiter::Type::OTHER, 0}};
// always ExecEnv::ready(), because Daemon::_stop_background_threads_latch
for (auto& group : ExecEnv::GetInstance()->mem_tracker_limiter_pool) {
std::lock_guard<std::mutex> l(group.group_lock);
for (auto trackerWptr : group.trackers) {
auto tracker = trackerWptr.lock();
if (tracker != nullptr) {
type_mem_sum[tracker->type()] += tracker->consumption();
}
}
}
int64_t all_tracked_mem_sum = 0;
int64_t tasks_trackers_mem_sum = 0;
for (auto it : type_mem_sum) {
all_tracked_mem_sum += it.second;
switch (it.first) {
case MemTrackerLimiter::Type::GLOBAL:
COUNTER_SET(_global_usage_counter, it.second);
memory_global_trackers_sum_bytes
<< it.second - memory_global_trackers_sum_bytes.get_value();
break;
case MemTrackerLimiter::Type::QUERY:
COUNTER_SET(_query_usage_counter, it.second);
tasks_trackers_mem_sum += it.second;
memory_query_trackers_sum_bytes
<< it.second - memory_query_trackers_sum_bytes.get_value();
break;
case MemTrackerLimiter::Type::LOAD:
COUNTER_SET(_load_usage_counter, it.second);
tasks_trackers_mem_sum += it.second;
memory_load_trackers_sum_bytes
<< it.second - memory_load_trackers_sum_bytes.get_value();
break;
case MemTrackerLimiter::Type::COMPACTION:
COUNTER_SET(_compaction_usage_counter, it.second);
tasks_trackers_mem_sum += it.second;
memory_compaction_trackers_sum_bytes
<< it.second - memory_compaction_trackers_sum_bytes.get_value();
break;
case MemTrackerLimiter::Type::SCHEMA_CHANGE:
COUNTER_SET(_schema_change_usage_counter, it.second);
tasks_trackers_mem_sum += it.second;
memory_schema_change_trackers_sum_bytes
<< it.second - memory_schema_change_trackers_sum_bytes.get_value();
break;
case MemTrackerLimiter::Type::METADATA:
COUNTER_SET(_metadata_usage_counter, it.second);
memory_metadata_trackers_sum_bytes
<< it.second - memory_metadata_trackers_sum_bytes.get_value();
break;
case MemTrackerLimiter::Type::CACHE:
COUNTER_SET(_cache_usage_counter, it.second);
memory_cache_trackers_sum_bytes
<< it.second - memory_cache_trackers_sum_bytes.get_value();
break;
case MemTrackerLimiter::Type::OTHER:
COUNTER_SET(_other_usage_counter, it.second);
tasks_trackers_mem_sum += it.second;
memory_other_trackers_sum_bytes
<< it.second - memory_other_trackers_sum_bytes.get_value();
}
}
MemTrackerLimiter::make_type_trackers_profile(global_memory_profile.get(),
MemTrackerLimiter::Type::GLOBAL);
MemTrackerLimiter::make_type_trackers_profile(metadata_memory_profile.get(),
MemTrackerLimiter::Type::METADATA);
MemTrackerLimiter::make_type_trackers_profile(cache_memory_profile.get(),
MemTrackerLimiter::Type::CACHE);
MemTrackerLimiter::make_top_consumption_tasks_tracker_profile(top_memory_tasks_profile.get(),
15);
COUNTER_SET(_tasks_memory_usage_counter, tasks_trackers_mem_sum);
memory_all_tasks_memory_bytes << tasks_trackers_mem_sum -
memory_all_tasks_memory_bytes.get_value();
COUNTER_SET(_reserved_memory_usage_counter, GlobalMemoryArbitrator::process_reserved_memory());
memory_reserved_memory_bytes << GlobalMemoryArbitrator::process_reserved_memory() -
memory_reserved_memory_bytes.get_value();
all_tracked_mem_sum += JemallocControl::je_cache_bytes();
COUNTER_SET(_jemalloc_cache_usage_counter,
static_cast<int64_t>(JemallocControl::je_cache_bytes()));
all_tracked_mem_sum += JemallocControl::je_metadata_mem();
COUNTER_SET(_jemalloc_metadata_usage_counter,
static_cast<int64_t>(JemallocControl::je_metadata_mem()));
COUNTER_SET(_jemalloc_memory_usage_counter,
_jemalloc_cache_usage_counter->current_value() +
_jemalloc_metadata_usage_counter->current_value());
int64_t jvm_heap_bytes = 0;
int64_t jvm_non_heap_bytes = 0;
// JvmMetrics only inited when enable_java_support == true, or it is nullptr
if (DorisMetrics::instance()->jvm_metrics() != nullptr) {
DorisMetrics::instance()->jvm_metrics()->update();
jvm_heap_bytes =
DorisMetrics::instance()->jvm_metrics()->jvm_heap_size_bytes_committed->value();
jvm_non_heap_bytes =
DorisMetrics::instance()->jvm_metrics()->jvm_non_heap_size_bytes_committed->value();
}
all_tracked_mem_sum += jvm_heap_bytes + jvm_non_heap_bytes;
COUNTER_SET(_jvm_heap_memory_usage_counter, jvm_heap_bytes);
COUNTER_SET(_jvm_non_heap_memory_usage_counter, jvm_non_heap_bytes);
// Memtable memory is not included in the memory the load tasks. Because actually it is a buffer.
COUNTER_SET(_memtable_memory_usage_counter,
ExecEnv::GetInstance()->memtable_memory_limiter()->mem_tracker()->consumption());
all_tracked_mem_sum +=
ExecEnv::GetInstance()->memtable_memory_limiter()->mem_tracker()->consumption();
COUNTER_SET(_tracked_memory_usage_counter, all_tracked_mem_sum);
memory_all_tracked_sum_bytes << all_tracked_mem_sum - memory_all_tracked_sum_bytes.get_value();
// 5 refresh untracked memory counter
int64_t untracked_memory =
_process_physical_memory_usage_counter->current_value() - all_tracked_mem_sum;
COUNTER_SET(_untracked_memory_usage_counter, untracked_memory);
memory_untracked_memory_bytes << untracked_memory - memory_untracked_memory_bytes.get_value();
// 6. reset profile
_global_memory_profile.set(std::move(global_memory_profile));
_metadata_memory_profile.set(std::move(metadata_memory_profile));
_cache_memory_profile.set(std::move(cache_memory_profile));
_top_memory_tasks_profile.set(std::move(top_memory_tasks_profile));
}
void MemoryProfile::refresh_tasks_memory_profile() {
std::unique_ptr<RuntimeProfile> tasks_memory_profile =
std::make_unique<RuntimeProfile>("AllTasksMemorySnapshot");
MemTrackerLimiter::make_all_tasks_tracker_profile(tasks_memory_profile.get());
_tasks_memory_profile.set(std::move(tasks_memory_profile));
}
void MemoryProfile::make_memory_profile(RuntimeProfile* profile) const {
RuntimeProfile* memory_profile_snapshot = profile->create_child("MemoryProfile", true, false);
RuntimeProfile* memory_overview_profile =
memory_profile_snapshot->create_child(_memory_overview_profile->name(), true, false);
memory_overview_profile->merge(_memory_overview_profile.get());
auto global_memory_version_ptr = _global_memory_profile.get();
RuntimeProfile* global_memory_profile =
memory_profile_snapshot->create_child(global_memory_version_ptr->name(), true, false);
global_memory_profile->merge(global_memory_version_ptr.get());
auto metadata_memory_version_ptr = _metadata_memory_profile.get();
RuntimeProfile* metadata_memory_profile =
memory_profile_snapshot->create_child(metadata_memory_version_ptr->name(), true, false);
metadata_memory_profile->merge(metadata_memory_version_ptr.get());
auto cache_memory_version_ptr = _cache_memory_profile.get();
RuntimeProfile* cache_memory_profile =
memory_profile_snapshot->create_child(cache_memory_version_ptr->name(), true, false);
cache_memory_profile->merge(cache_memory_version_ptr.get());
auto top_memory_tasks_version_ptr = _top_memory_tasks_profile.get();
RuntimeProfile* top_memory_tasks_profile = memory_profile_snapshot->create_child(
top_memory_tasks_version_ptr->name(), true, false);
top_memory_tasks_profile->merge(top_memory_tasks_version_ptr.get());
auto tasks_memory_version_ptr = _tasks_memory_profile.get();
RuntimeProfile* tasks_memory_profile =
memory_profile_snapshot->create_child(tasks_memory_version_ptr->name(), true, false);
tasks_memory_profile->merge(tasks_memory_version_ptr.get());
}
int64_t MemoryProfile::query_current_usage() {
return memory_query_trackers_sum_bytes.get_value();
}
int64_t MemoryProfile::load_current_usage() {
return memory_load_trackers_sum_bytes.get_value();
}
int64_t MemoryProfile::compaction_current_usage() {
return memory_compaction_trackers_sum_bytes.get_value();
}
int64_t MemoryProfile::schema_change_current_usage() {
return memory_schema_change_trackers_sum_bytes.get_value();
}
int64_t MemoryProfile::other_current_usage() {
return memory_other_trackers_sum_bytes.get_value();
}
std::string MemoryProfile::process_memory_detail_str() const {
return fmt::format("Process Memory Summary: {}\n, {}\n, {}\n, {}\n, {}\n, {}\n",
GlobalMemoryArbitrator::process_mem_log_str(),
print_memory_overview_profile(), print_global_memory_profile(),
print_metadata_memory_profile(), print_cache_memory_profile(),
print_top_memory_tasks_profile());
}
void MemoryProfile::print_log_process_usage() {
if (_enable_print_log_process_usage) {
_enable_print_log_process_usage = false;
auto log_str = process_memory_detail_str();
LOG_LONG_STRING(INFO, log_str);
}
}
#include "common/compile_check_end.h"
} // namespace doris