This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.1 by this push:
new 8a244d2bd2c branch-3.1: [Opt](mow) Move `DeleteBitmapAggCache` to
`ExecEnv` #52649 (#52705)
8a244d2bd2c is described below
commit 8a244d2bd2cab2e89c6970b756694cdc388286fd
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Jul 4 11:28:11 2025 +0800
branch-3.1: [Opt](mow) Move `DeleteBitmapAggCache` to `ExecEnv` #52649
(#52705)
Cherry-picked from #52649
Co-authored-by: bobhan1 <[email protected]>
---
be/src/olap/tablet_meta.cpp | 57 +++++++++++++++++++-------------------
be/src/olap/tablet_meta.h | 51 ++++++++++------------------------
be/src/runtime/exec_env.h | 5 ++++
be/src/runtime/exec_env_init.cpp | 12 ++++++++
be/test/testutil/run_all_tests.cpp | 4 +++
5 files changed, 63 insertions(+), 66 deletions(-)
diff --git a/be/src/olap/tablet_meta.cpp b/be/src/olap/tablet_meta.cpp
index f1c1213c0c4..ab225d1fcdb 100644
--- a/be/src/olap/tablet_meta.cpp
+++ b/be/src/olap/tablet_meta.cpp
@@ -1099,21 +1099,21 @@ bool operator!=(const TabletMeta& a, const TabletMeta&
b) {
return !(a == b);
}
-DeleteBitmap::DeleteBitmap(int64_t tablet_id) : _tablet_id(tablet_id) {
- // The default delete bitmap cache is set to 100MB,
- // which can be insufficient and cause performance issues when the amount
of user data is large.
- // To mitigate the problem of an inadequate cache,
- // we will take the larger of 0.5% of the total memory and 100MB as the
delete bitmap cache size.
- bool is_percent = false;
- int64_t delete_bitmap_agg_cache_cache_limit =
-
ParseUtil::parse_mem_spec(config::delete_bitmap_dynamic_agg_cache_limit,
- MemInfo::mem_limit(),
MemInfo::physical_mem(), &is_percent);
- _agg_cache.reset(new AggCache(delete_bitmap_agg_cache_cache_limit >
-
config::delete_bitmap_agg_cache_capacity
- ? delete_bitmap_agg_cache_cache_limit
- :
config::delete_bitmap_agg_cache_capacity));
+DeleteBitmapAggCache::DeleteBitmapAggCache(size_t capacity)
+ : LRUCachePolicy(CachePolicy::CacheType::DELETE_BITMAP_AGG_CACHE,
capacity,
+ LRUCacheType::SIZE,
config::delete_bitmap_agg_cache_stale_sweep_time_sec,
+ 256) {}
+
+DeleteBitmapAggCache* DeleteBitmapAggCache::instance() {
+ return ExecEnv::GetInstance()->delete_bitmap_agg_cache();
+}
+
+DeleteBitmapAggCache* DeleteBitmapAggCache::create_instance(size_t capacity) {
+ return new DeleteBitmapAggCache(capacity);
}
+DeleteBitmap::DeleteBitmap(int64_t tablet_id) : _tablet_id(tablet_id) {}
+
DeleteBitmap::DeleteBitmap(const DeleteBitmap& o) {
delete_bitmap = o.delete_bitmap; // just copy data
_tablet_id = o._tablet_id;
@@ -1407,20 +1407,20 @@ static std::string agg_cache_key(int64_t tablet_id,
const DeleteBitmap::BitmapKe
std::shared_ptr<roaring::Roaring> DeleteBitmap::get_agg(const BitmapKey& bmk)
const {
std::string key_str = agg_cache_key(_tablet_id, bmk); // Cache key
container
CacheKey key(key_str);
- Cache::Handle* handle = _agg_cache->repr()->lookup(key);
+ Cache::Handle* handle = DeleteBitmapAggCache::instance()->lookup(key);
- AggCache::Value* val =
- handle == nullptr
- ? nullptr
- :
reinterpret_cast<AggCache::Value*>(_agg_cache->repr()->value(handle));
+ DeleteBitmapAggCache::Value* val =
+ handle == nullptr ? nullptr
+ : reinterpret_cast<DeleteBitmapAggCache::Value*>(
+
DeleteBitmapAggCache::instance()->value(handle));
// FIXME: do we need a mutex here to get rid of duplicated initializations
// of cache entries in some cases?
if (val == nullptr) { // Renew if needed, put a new Value to cache
- val = new AggCache::Value();
+ val = new DeleteBitmapAggCache::Value();
Version start_version =
config::enable_mow_get_agg_by_cache ?
_get_rowset_cache_version(bmk) : 0;
if (start_version > 0) {
- Cache::Handle* handle2 = _agg_cache->repr()->lookup(
+ Cache::Handle* handle2 = DeleteBitmapAggCache::instance()->lookup(
agg_cache_key(_tablet_id, {std::get<0>(bmk),
std::get<1>(bmk), start_version}));
DBUG_EXECUTE_IF("DeleteBitmap::get_agg.cache_miss", {
@@ -1438,10 +1438,10 @@ std::shared_ptr<roaring::Roaring>
DeleteBitmap::get_agg(const BitmapKey& bmk) co
if (handle2 == nullptr || start_version > std::get<2>(bmk)) {
start_version = 0;
} else {
- val->bitmap |=
-
reinterpret_cast<AggCache::Value*>(_agg_cache->repr()->value(handle2))
- ->bitmap;
- _agg_cache->repr()->release(handle2);
+ val->bitmap |= reinterpret_cast<DeleteBitmapAggCache::Value*>(
+
DeleteBitmapAggCache::instance()->value(handle2))
+ ->bitmap;
+ DeleteBitmapAggCache::instance()->release(handle2);
VLOG_DEBUG << "get agg cache version=" << start_version
<< " for tablet=" << _tablet_id
<< ", rowset=" << std::get<0>(bmk).to_string()
@@ -1461,8 +1461,9 @@ std::shared_ptr<roaring::Roaring>
DeleteBitmap::get_agg(const BitmapKey& bmk) co
val->bitmap |= bm;
}
}
- size_t charge = val->bitmap.getSizeInBytes() + sizeof(AggCache::Value);
- handle = _agg_cache->repr()->insert(key, val, charge, charge,
CachePriority::NORMAL);
+ size_t charge = val->bitmap.getSizeInBytes() +
sizeof(DeleteBitmapAggCache::Value);
+ handle = DeleteBitmapAggCache::instance()->insert(key, val, charge,
charge,
+
CachePriority::NORMAL);
if (config::enable_mow_get_agg_by_cache && !val->bitmap.isEmpty()) {
std::lock_guard l(_rowset_cache_version_lock);
// this version is already agg
@@ -1489,7 +1490,7 @@ std::shared_ptr<roaring::Roaring>
DeleteBitmap::get_agg(const BitmapKey& bmk) co
// It is natural for the cache to reclaim the underlying memory
return std::shared_ptr<roaring::Roaring>(
- &val->bitmap, [this, handle](...) {
_agg_cache->repr()->release(handle); });
+ &val->bitmap, [handle](...) {
DeleteBitmapAggCache::instance()->release(handle); });
}
std::shared_ptr<roaring::Roaring> DeleteBitmap::get_agg_without_cache(
@@ -1508,8 +1509,6 @@ std::shared_ptr<roaring::Roaring>
DeleteBitmap::get_agg_without_cache(
return bitmap;
}
-std::atomic<DeleteBitmap::AggCachePolicy*> DeleteBitmap::AggCache::s_repr
{nullptr};
-
std::string tablet_state_name(TabletState state) {
switch (state) {
case TABLET_NOTREADY:
diff --git a/be/src/olap/tablet_meta.h b/be/src/olap/tablet_meta.h
index a086e82e4a3..6e4b6719a20 100644
--- a/be/src/olap/tablet_meta.h
+++ b/be/src/olap/tablet_meta.h
@@ -364,6 +364,20 @@ private:
mutable std::shared_mutex _meta_lock;
};
+class DeleteBitmapAggCache : public LRUCachePolicy {
+public:
+ DeleteBitmapAggCache(size_t capacity);
+
+ static DeleteBitmapAggCache* instance();
+
+ static DeleteBitmapAggCache* create_instance(size_t capacity);
+
+ class Value : public LRUCacheValueBase {
+ public:
+ roaring::Roaring bitmap;
+ };
+};
+
/**
* Wraps multiple bitmaps for recording rows (row id) that are deleted or
* overwritten. For now, it's only used when unique key merge-on-write property
@@ -565,46 +579,9 @@ public:
std::set<RowsetId> get_rowset_cache_version();
- class AggCachePolicy : public LRUCachePolicy {
- public:
- AggCachePolicy(size_t capacity)
- :
LRUCachePolicy(CachePolicy::CacheType::DELETE_BITMAP_AGG_CACHE, capacity,
- LRUCacheType::SIZE,
-
config::delete_bitmap_agg_cache_stale_sweep_time_sec, 256) {}
- };
-
- class AggCache {
- public:
- class Value : public LRUCacheValueBase {
- public:
- roaring::Roaring bitmap;
- };
-
- AggCache(size_t size_in_bytes) {
- static std::once_flag once;
- std::call_once(once, [size_in_bytes] {
- auto* tmp = new AggCachePolicy(size_in_bytes);
- AggCache::s_repr.store(tmp, std::memory_order_release);
-
- // release the sigleton instance at program exit
- std::atexit([] {
- auto* ptr = AggCache::s_repr.exchange(nullptr,
std::memory_order_acquire);
- delete ptr;
- });
- });
-
- while (!s_repr.load(std::memory_order_acquire)) {
- }
- }
-
- static LRUCachePolicy* repr() { return
s_repr.load(std::memory_order_acquire); }
- static std::atomic<AggCachePolicy*> s_repr;
- };
-
private:
DeleteBitmap::Version _get_rowset_cache_version(const BitmapKey& bmk)
const;
- mutable std::shared_ptr<AggCache> _agg_cache;
int64_t _tablet_id;
mutable std::shared_mutex _rowset_cache_version_lock;
mutable std::map<RowsetId, std::map<SegmentId, Version>>
_rowset_cache_version;
diff --git a/be/src/runtime/exec_env.h b/be/src/runtime/exec_env.h
index f3255be9291..4dae6f66122 100644
--- a/be/src/runtime/exec_env.h
+++ b/be/src/runtime/exec_env.h
@@ -126,6 +126,7 @@ class WalManager;
class DNSCache;
class IndexPolicyMgr;
struct SyncRowsetStats;
+class DeleteBitmapAggCache;
inline bool k_doris_exit = false;
@@ -305,6 +306,7 @@ public:
void set_cache_manager(CacheManager* cm) { this->_cache_manager = cm; }
void set_process_profile(ProcessProfile* pp) { this->_process_profile =
pp; }
void set_tablet_schema_cache(TabletSchemaCache* c) {
this->_tablet_schema_cache = c; }
+ void set_delete_bitmap_agg_cache(DeleteBitmapAggCache* c) {
_delete_bitmap_agg_cache = c; }
void set_tablet_column_object_pool(TabletColumnObjectPool* c) {
this->_tablet_column_object_pool = c;
}
@@ -372,6 +374,8 @@ public:
bool check_auth_token(const std::string& auth_token);
+ DeleteBitmapAggCache* delete_bitmap_agg_cache() { return
_delete_bitmap_agg_cache; }
+
private:
ExecEnv();
@@ -501,6 +505,7 @@ private:
QueryCache* _query_cache = nullptr;
std::shared_ptr<DummyLRUCache> _dummy_lru_cache = nullptr;
std::unique_ptr<io::FDCache> _file_cache_open_fd_cache;
+ DeleteBitmapAggCache* _delete_bitmap_agg_cache {nullptr};
pipeline::RuntimeFilterTimerQueue* _runtime_filter_timer_queue = nullptr;
diff --git a/be/src/runtime/exec_env_init.cpp b/be/src/runtime/exec_env_init.cpp
index ce841afc1d3..0fbc1e7af8a 100644
--- a/be/src/runtime/exec_env_init.cpp
+++ b/be/src/runtime/exec_env_init.cpp
@@ -55,6 +55,7 @@
#include "olap/segment_loader.h"
#include "olap/storage_engine.h"
#include "olap/tablet_column_object_pool.h"
+#include "olap/tablet_meta.h"
#include "olap/tablet_schema_cache.h"
#include "olap/wal/wal_manager.h"
#include "pipeline/pipeline_tracing.h"
@@ -581,6 +582,16 @@ Status ExecEnv::_init_mem_env() {
_query_cache = QueryCache::create_global_cache(config::query_cache_size *
1024L * 1024L);
LOG(INFO) << "query cache memory limit: " << config::query_cache_size <<
"MB";
+ // The default delete bitmap cache is set to 100MB,
+ // which can be insufficient and cause performance issues when the amount
of user data is large.
+ // To mitigate the problem of an inadequate cache,
+ // we will take the larger of 0.5% of the total memory and 100MB as the
delete bitmap cache size.
+ int64_t delete_bitmap_agg_cache_cache_limit =
+
ParseUtil::parse_mem_spec(config::delete_bitmap_dynamic_agg_cache_limit,
+ MemInfo::mem_limit(),
MemInfo::physical_mem(), &is_percent);
+ _delete_bitmap_agg_cache = DeleteBitmapAggCache::create_instance(std::max(
+ delete_bitmap_agg_cache_cache_limit,
config::delete_bitmap_agg_cache_capacity));
+
return Status::OK();
}
@@ -735,6 +746,7 @@ void ExecEnv::destroy() {
SAFE_DELETE(_segment_loader);
SAFE_DELETE(_row_cache);
SAFE_DELETE(_query_cache);
+ SAFE_DELETE(_delete_bitmap_agg_cache);
// Free resource after threads are stopped.
// Some threads are still running, like threads created by
_new_load_stream_mgr ...
diff --git a/be/test/testutil/run_all_tests.cpp
b/be/test/testutil/run_all_tests.cpp
index 810f3e0c28f..253d1729780 100644
--- a/be/test/testutil/run_all_tests.cpp
+++ b/be/test/testutil/run_all_tests.cpp
@@ -32,6 +32,7 @@
#include "olap/segment_loader.h"
#include "olap/storage_engine.h"
#include "olap/tablet_column_object_pool.h"
+#include "olap/tablet_meta.h"
#include "olap/tablet_schema_cache.h"
#include "runtime/exec_env.h"
#include "runtime/memory/cache_manager.h"
@@ -77,6 +78,9 @@ int main(int argc, char** argv) {
doris::ExecEnv::GetInstance()->set_tablet_schema_cache(
doris::TabletSchemaCache::create_global_schema_cache(
doris::config::tablet_schema_cache_capacity));
+ doris::ExecEnv::GetInstance()->set_delete_bitmap_agg_cache(
+ doris::DeleteBitmapAggCache::create_instance(
+ doris::config::delete_bitmap_agg_cache_capacity));
doris::ExecEnv::GetInstance()->set_tablet_column_object_pool(
doris::TabletColumnObjectPool::create_global_column_cache(
doris::config::tablet_schema_cache_capacity));
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]