This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.1 by this push:
new 560097e491a branch-2.1: [Opt](mow) Move `DeleteBitmapAggCache` to
`ExecEnv` (#52649) (#52738)
560097e491a is described below
commit 560097e491aa843889e4035a33ac208e085436c3
Author: bobhan1 <[email protected]>
AuthorDate: Wed Jul 9 10:59:19 2025 +0800
branch-2.1: [Opt](mow) Move `DeleteBitmapAggCache` to `ExecEnv` (#52649)
(#52738)
pick https://github.com/apache/doris/pull/52649
---
be/src/olap/tablet_meta.cpp | 47 +++++++++++++++++----------------
be/src/olap/tablet_meta.h | 53 ++++++++++----------------------------
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, 58 insertions(+), 63 deletions(-)
diff --git a/be/src/olap/tablet_meta.cpp b/be/src/olap/tablet_meta.cpp
index c5fdb21479d..e83b4c697ec 100644
--- a/be/src/olap/tablet_meta.cpp
+++ b/be/src/olap/tablet_meta.cpp
@@ -972,21 +972,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)
+ :
LRUCachePolicyTrackingManual(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;
@@ -1201,16 +1201,16 @@ 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();
{
std::shared_lock l(lock);
DeleteBitmap::BitmapKey start {std::get<0>(bmk), std::get<1>(bmk),
0};
@@ -1223,17 +1223,16 @@ 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);
}
// 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::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 efc4558f7bb..9b089bb0584 100644
--- a/be/src/olap/tablet_meta.h
+++ b/be/src/olap/tablet_meta.h
@@ -339,6 +339,20 @@ private:
mutable std::shared_mutex _meta_lock;
};
+class DeleteBitmapAggCache : public LRUCachePolicyTrackingManual {
+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
@@ -515,45 +529,6 @@ public:
const std::function<void(const DeleteBitmap&, const RowsetId&
rowsetId)>& func) const;
uint64_t count_key_with_rowset_id_unlocked(const RowsetId& rowset_id)
const;
- class AggCachePolicy : public LRUCachePolicyTrackingManual {
- public:
- AggCachePolicy(size_t capacity)
- :
LRUCachePolicyTrackingManual(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:
- mutable std::shared_ptr<AggCache> _agg_cache;
int64_t _tablet_id;
};
diff --git a/be/src/runtime/exec_env.h b/be/src/runtime/exec_env.h
index 6e97e78768b..d427444c2f2 100644
--- a/be/src/runtime/exec_env.h
+++ b/be/src/runtime/exec_env.h
@@ -112,6 +112,7 @@ class CacheManager;
class HeapProfiler;
class WalManager;
class DNSCache;
+class DeleteBitmapAggCache;
inline bool k_doris_exit = false;
@@ -275,6 +276,7 @@ public:
void set_storage_engine(StorageEngine* se) { this->_storage_engine = se; }
void set_cache_manager(CacheManager* cm) { this->_cache_manager = cm; }
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;
}
@@ -337,6 +339,8 @@ public:
orc::MemoryPool* orc_memory_pool() { return _orc_memory_pool; }
arrow::MemoryPool* arrow_memory_pool() { return _arrow_memory_pool; }
+ DeleteBitmapAggCache* delete_bitmap_agg_cache() { return
_delete_bitmap_agg_cache; }
+
private:
ExecEnv();
@@ -466,6 +470,7 @@ private:
std::shared_ptr<pipeline::BlockedTaskScheduler> _global_block_scheduler;
// used for query without workload group
std::shared_ptr<pipeline::BlockedTaskScheduler>
_without_group_block_scheduler;
+ 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 bcb01a6336f..63fafb7534f 100644
--- a/be/src/runtime/exec_env_init.cpp
+++ b/be/src/runtime/exec_env_init.cpp
@@ -46,6 +46,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"
@@ -521,6 +522,16 @@ Status ExecEnv::_init_mem_env() {
_orc_memory_pool = new doris::vectorized::ORCMemoryPool();
_arrow_memory_pool = new doris::vectorized::ArrowMemoryPool();
+ // 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();
}
@@ -633,6 +644,7 @@ void ExecEnv::destroy() {
// StorageEngine must be destoried before _page_no_cache_mem_tracker.reset
// StorageEngine must be destoried before _cache_manager destory
SAFE_DELETE(_storage_engine);
+ 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 272179fcb8f..776b8dc243d 100644
--- a/be/test/testutil/run_all_tests.cpp
+++ b/be/test/testutil/run_all_tests.cpp
@@ -27,6 +27,7 @@
#include "olap/page_cache.h"
#include "olap/segment_loader.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"
@@ -57,6 +58,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]