This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
The following commit(s) were added to refs/heads/master by this push: new 6c098e4 [Optimize][Cache]Implementation of Separated Page Cache (#5008) 6c098e4 is described below commit 6c098e45fc33342da6bb47dbdc34dda1e40a3cec Author: Skysheepwang <wangt...@163.com> AuthorDate: Mon Jan 4 12:19:24 2021 +0800 [Optimize][Cache]Implementation of Separated Page Cache (#5008) #4995 **Implementation of Separated Page Cache** - Add config "index_page_cache_ratio" to set the ratio of capacity of index page cache - Change the member of StoragePageCache to maintain two type of cache - Change the interface of StoragePageCache for selecting type of cache - Change the usage of page cache in read_and_decompress_page in page_io.cpp - add page type as argument - check if current page type is available in StoragePageCache (cover the situation of ratio == 0 or 1) - Add type as argument in superior call of read_and_decompress_page - Change Unit Test --- be/src/common/config.h | 3 + be/src/olap/page_cache.cpp | 33 ++-- be/src/olap/page_cache.h | 33 +++- be/src/olap/rowset/segment_v2/column_reader.cpp | 3 + be/src/olap/rowset/segment_v2/column_reader.h | 4 + .../rowset/segment_v2/indexed_column_reader.cpp | 7 +- .../olap/rowset/segment_v2/indexed_column_reader.h | 2 +- .../olap/rowset/segment_v2/ordinal_page_index.cpp | 1 + be/src/olap/rowset/segment_v2/page_io.cpp | 6 +- be/src/olap/rowset/segment_v2/page_io.h | 4 + be/src/olap/rowset/segment_v2/segment.cpp | 1 + be/src/runtime/exec_env_init.cpp | 3 +- be/test/olap/page_cache_test.cpp | 180 +++++++++++++++++++-- be/test/olap/rowset/beta_rowset_test.cpp | 2 +- be/test/olap/rowset/rowset_converter_test.cpp | 2 +- .../olap/rowset/segment_v2/bitmap_index_test.cpp | 2 +- .../bloom_filter_index_reader_writer_test.cpp | 2 +- .../segment_v2/column_reader_writer_test.cpp | 2 +- .../rowset/segment_v2/ordinal_page_index_test.cpp | 2 +- be/test/olap/rowset/segment_v2/segment_test.cpp | 2 +- .../olap/rowset/segment_v2/zone_map_index_test.cpp | 2 +- docs/en/administrator-guide/config/be_config.md | 5 + docs/zh-CN/administrator-guide/config/be_config.md | 5 + 23 files changed, 266 insertions(+), 40 deletions(-) diff --git a/be/src/common/config.h b/be/src/common/config.h index 6bef85a..4c5df68 100644 --- a/be/src/common/config.h +++ b/be/src/common/config.h @@ -260,6 +260,9 @@ CONF_Int64(index_stream_cache_capacity, "10737418240"); // Cache for storage page size CONF_String(storage_page_cache_limit, "20%"); +// Percentage for index page cache +// all storage page cache will be divided into data_page_cache and index_page_cache +CONF_Int32(index_page_cache_percentage, "10"); // whether to disable page cache feature in storage CONF_Bool(disable_storage_page_cache, "false"); diff --git a/be/src/olap/page_cache.cpp b/be/src/olap/page_cache.cpp index aceb663..787ef1c 100644 --- a/be/src/olap/page_cache.cpp +++ b/be/src/olap/page_cache.cpp @@ -21,26 +21,38 @@ namespace doris { StoragePageCache* StoragePageCache::_s_instance = nullptr; -void StoragePageCache::create_global_cache(size_t capacity) { +void StoragePageCache::create_global_cache(size_t capacity, int32_t index_cache_percentage) { DCHECK(_s_instance == nullptr); - static StoragePageCache instance(capacity); + static StoragePageCache instance(capacity, index_cache_percentage); _s_instance = &instance; } -StoragePageCache::StoragePageCache(size_t capacity) - : _cache(new_lru_cache("StoragePageCache", capacity)) {} +StoragePageCache::StoragePageCache(size_t capacity, int32_t index_cache_percentage) + : _index_cache_percentage(index_cache_percentage) { + if (index_cache_percentage == 0) { + _data_page_cache = std::unique_ptr<Cache>(new_lru_cache("DataPageCache", capacity)); + } else if (index_cache_percentage == 100) { + _index_page_cache = std::unique_ptr<Cache>(new_lru_cache("IndexPageCache", capacity)); + } else if (index_cache_percentage > 0 && index_cache_percentage < 100) { + _data_page_cache = std::unique_ptr<Cache>(new_lru_cache("DataPageCache", capacity * (100 - index_cache_percentage) / 100)); + _index_page_cache = std::unique_ptr<Cache>(new_lru_cache("IndexPageCache", capacity * index_cache_percentage / 100)); + } else { + CHECK(false) << "invalid index page cache percentage"; + } +} -bool StoragePageCache::lookup(const CacheKey& key, PageCacheHandle* handle) { - auto lru_handle = _cache->lookup(key.encode()); +bool StoragePageCache::lookup(const CacheKey& key, PageCacheHandle* handle, segment_v2::PageTypePB page_type) { + auto cache = _get_page_cache(page_type); + auto lru_handle = cache->lookup(key.encode()); if (lru_handle == nullptr) { return false; } - *handle = PageCacheHandle(_cache.get(), lru_handle); + *handle = PageCacheHandle(cache, lru_handle); return true; } void StoragePageCache::insert(const CacheKey& key, const Slice& data, PageCacheHandle* handle, - bool in_memory) { + segment_v2::PageTypePB page_type, bool in_memory) { auto deleter = [](const doris::CacheKey& key, void* value) { delete[](uint8_t*) value; }; CachePriority priority = CachePriority::NORMAL; @@ -48,8 +60,9 @@ void StoragePageCache::insert(const CacheKey& key, const Slice& data, PageCacheH priority = CachePriority::DURABLE; } - auto lru_handle = _cache->insert(key.encode(), data.data, data.size, deleter, priority); - *handle = PageCacheHandle(_cache.get(), lru_handle); + auto cache = _get_page_cache(page_type); + auto lru_handle = cache->insert(key.encode(), data.data, data.size, deleter, priority); + *handle = PageCacheHandle(cache, lru_handle); } } // namespace doris diff --git a/be/src/olap/page_cache.h b/be/src/olap/page_cache.h index e48a2c9..aa3a600 100644 --- a/be/src/olap/page_cache.h +++ b/be/src/olap/page_cache.h @@ -23,6 +23,7 @@ #include "gutil/macros.h" // for DISALLOW_COPY_AND_ASSIGN #include "olap/lru_cache.h" +#include "gen_cpp/segment_v2.pb.h" // for cache allocation namespace doris { @@ -53,13 +54,13 @@ public: }; // Create global instance of this class - static void create_global_cache(size_t capacity); + static void create_global_cache(size_t capacity, int32_t index_cache_percentage); // Return global instance. // Client should call create_global_cache before. static StoragePageCache* instance() { return _s_instance; } - StoragePageCache(size_t capacity); + StoragePageCache(size_t capacity, int32_t index_cache_percentage); // Lookup the given page in the cache. // @@ -67,8 +68,10 @@ public: // PageCacheHandle will release cache entry to cache when it // destructs. // + // Cache type selection is determined by page_type argument + // // Return true if entry is found, otherwise return false. - bool lookup(const CacheKey& key, PageCacheHandle* handle); + bool lookup(const CacheKey& key, PageCacheHandle* handle, segment_v2::PageTypePB page_type); // Insert a page with key into this cache. // Given handle will be set to valid reference. @@ -76,13 +79,33 @@ public: // concurrently, this function can assure that only one page is cached. // The in_memory page will have higher priority. void insert(const CacheKey& key, const Slice& data, PageCacheHandle* handle, - bool in_memory = false); + segment_v2::PageTypePB page_type, bool in_memory = false); + + // Page cache available check. + // When percentage is set to 0 or 100, the index or data cache will not be allocated. + bool is_cache_available(segment_v2::PageTypePB page_type) { + return _get_page_cache(page_type) != nullptr; + } private: StoragePageCache(); static StoragePageCache* _s_instance; - std::unique_ptr<Cache> _cache = nullptr; + int32_t _index_cache_percentage = 0; + std::unique_ptr<Cache> _data_page_cache = nullptr; + std::unique_ptr<Cache> _index_page_cache = nullptr; + + Cache* _get_page_cache(segment_v2::PageTypePB page_type) { + switch (page_type) + { + case segment_v2::DATA_PAGE: + return _data_page_cache.get(); + case segment_v2::INDEX_PAGE: + return _index_page_cache.get(); + default: + return nullptr; + } + } }; // A handle for StoragePageCache entry. This class make it easy to handle diff --git a/be/src/olap/rowset/segment_v2/column_reader.cpp b/be/src/olap/rowset/segment_v2/column_reader.cpp index b2d382e..cfe213f 100644 --- a/be/src/olap/rowset/segment_v2/column_reader.cpp +++ b/be/src/olap/rowset/segment_v2/column_reader.cpp @@ -130,6 +130,7 @@ Status ColumnReader::read_page(const ColumnIteratorOptions& iter_opts, const Pag opts.verify_checksum = _opts.verify_checksum; opts.use_page_cache = iter_opts.use_page_cache; opts.kept_in_memory = _opts.kept_in_memory; + opts.type = iter_opts.type; return PageIO::read_and_decompress_page(opts, handle, page_body, footer); } @@ -569,6 +570,7 @@ Status FileColumnIterator::_read_data_page(const OrdinalPageIndexIterator& iter) PageHandle handle; Slice page_body; PageFooterPB footer; + _opts.type = DATA_PAGE; RETURN_IF_ERROR(_reader->read_page(_opts, iter.page(), &handle, &page_body, &footer)); // parse data page RETURN_IF_ERROR(ParsedPage::create(std::move(handle), page_body, footer.data_page_footer(), @@ -587,6 +589,7 @@ Status FileColumnIterator::_read_data_page(const OrdinalPageIndexIterator& iter) // read dictionary page Slice dict_data; PageFooterPB dict_footer; + _opts.type = INDEX_PAGE; RETURN_IF_ERROR(_reader->read_page(_opts, _reader->get_dict_page_pointer(), &_dict_page_handle, &dict_data, &dict_footer)); // ignore dict_footer.dict_page_footer().encoding() due to only diff --git a/be/src/olap/rowset/segment_v2/column_reader.h b/be/src/olap/rowset/segment_v2/column_reader.h index c6a8b33..7384fa9 100644 --- a/be/src/olap/rowset/segment_v2/column_reader.h +++ b/be/src/olap/rowset/segment_v2/column_reader.h @@ -67,6 +67,10 @@ struct ColumnIteratorOptions { // reader statistics OlapReaderStatistics* stats = nullptr; bool use_page_cache = false; + // for page cache allocation + // page types are divided into DATA_PAGE & INDEX_PAGE + // INDEX_PAGE including index_page, dict_page and short_key_page + PageTypePB type; void sanity_check() const { CHECK_NOTNULL(rblock); diff --git a/be/src/olap/rowset/segment_v2/indexed_column_reader.cpp b/be/src/olap/rowset/segment_v2/indexed_column_reader.cpp index 427bb9e..1ac6692 100644 --- a/be/src/olap/rowset/segment_v2/indexed_column_reader.cpp +++ b/be/src/olap/rowset/segment_v2/indexed_column_reader.cpp @@ -72,13 +72,13 @@ Status IndexedColumnReader::load_index_page(fs::ReadableBlock* rblock, const Pag PageHandle* handle, IndexPageReader* reader) { Slice body; PageFooterPB footer; - RETURN_IF_ERROR(read_page(rblock, PagePointer(pp), handle, &body, &footer)); + RETURN_IF_ERROR(read_page(rblock, PagePointer(pp), handle, &body, &footer, INDEX_PAGE)); RETURN_IF_ERROR(reader->parse(body, footer.index_page_footer())); return Status::OK(); } Status IndexedColumnReader::read_page(fs::ReadableBlock* rblock, const PagePointer& pp, - PageHandle* handle, Slice* body, PageFooterPB* footer) const { + PageHandle* handle, Slice* body, PageFooterPB* footer, PageTypePB type) const { PageReadOptions opts; opts.rblock = rblock; opts.page_pointer = pp; @@ -87,6 +87,7 @@ Status IndexedColumnReader::read_page(fs::ReadableBlock* rblock, const PagePoint opts.stats = &tmp_stats; opts.use_page_cache = _use_page_cache; opts.kept_in_memory = _kept_in_memory; + opts.type = type; return PageIO::read_and_decompress_page(opts, handle, body, footer); } @@ -97,7 +98,7 @@ Status IndexedColumnIterator::_read_data_page(const PagePointer& pp) { PageHandle handle; Slice body; PageFooterPB footer; - RETURN_IF_ERROR(_reader->read_page(_rblock.get(), pp, &handle, &body, &footer)); + RETURN_IF_ERROR(_reader->read_page(_rblock.get(), pp, &handle, &body, &footer, DATA_PAGE)); // parse data page // note that page_index is not used in IndexedColumnIterator, so we pass 0 return ParsedPage::create(std::move(handle), body, footer.data_page_footer(), diff --git a/be/src/olap/rowset/segment_v2/indexed_column_reader.h b/be/src/olap/rowset/segment_v2/indexed_column_reader.h index 1951cb1..1cd42d8 100644 --- a/be/src/olap/rowset/segment_v2/indexed_column_reader.h +++ b/be/src/olap/rowset/segment_v2/indexed_column_reader.h @@ -51,7 +51,7 @@ public: // read a page specified by `pp' from `file' into `handle' Status read_page(fs::ReadableBlock* rblock, const PagePointer& pp, PageHandle* handle, - Slice* body, PageFooterPB* footer) const; + Slice* body, PageFooterPB* footer, PageTypePB type) const; int64_t num_values() const { return _num_values; } const EncodingInfo* encoding_info() const { return _encoding_info; } diff --git a/be/src/olap/rowset/segment_v2/ordinal_page_index.cpp b/be/src/olap/rowset/segment_v2/ordinal_page_index.cpp index 8d3a63b..6c4d94c 100644 --- a/be/src/olap/rowset/segment_v2/ordinal_page_index.cpp +++ b/be/src/olap/rowset/segment_v2/ordinal_page_index.cpp @@ -80,6 +80,7 @@ Status OrdinalIndexReader::load(bool use_page_cache, bool kept_in_memory) { opts.stats = &tmp_stats; opts.use_page_cache = use_page_cache; opts.kept_in_memory = kept_in_memory; + opts.type = INDEX_PAGE; // read index page PageHandle page_handle; diff --git a/be/src/olap/rowset/segment_v2/page_io.cpp b/be/src/olap/rowset/segment_v2/page_io.cpp index 31a7ac2..f59174c 100644 --- a/be/src/olap/rowset/segment_v2/page_io.cpp +++ b/be/src/olap/rowset/segment_v2/page_io.cpp @@ -112,7 +112,7 @@ Status PageIO::read_and_decompress_page(const PageReadOptions& opts, PageHandle* auto cache = StoragePageCache::instance(); PageCacheHandle cache_handle; StoragePageCache::CacheKey cache_key(opts.rblock->path(), opts.page_pointer.offset); - if (opts.use_page_cache && cache->lookup(cache_key, &cache_handle)) { + if (opts.use_page_cache && cache->is_cache_available(opts.type) && cache->lookup(cache_key, &cache_handle, opts.type)) { // we find page in cache, use it *handle = PageHandle(std::move(cache_handle)); opts.stats->cached_pages_num++; @@ -189,9 +189,9 @@ Status PageIO::read_and_decompress_page(const PageReadOptions& opts, PageHandle* } *body = Slice(page_slice.data, page_slice.size - 4 - footer_size); - if (opts.use_page_cache) { + if (opts.use_page_cache && cache->is_cache_available(opts.type)) { // insert this page into cache and return the cache handle - cache->insert(cache_key, page_slice, &cache_handle, opts.kept_in_memory); + cache->insert(cache_key, page_slice, &cache_handle, opts.type, opts.kept_in_memory); *handle = PageHandle(std::move(cache_handle)); } else { *handle = PageHandle(page_slice); diff --git a/be/src/olap/rowset/segment_v2/page_io.h b/be/src/olap/rowset/segment_v2/page_io.h index e9cce2a..2cd79f3 100644 --- a/be/src/olap/rowset/segment_v2/page_io.h +++ b/be/src/olap/rowset/segment_v2/page_io.h @@ -54,6 +54,10 @@ struct PageReadOptions { // if true, use DURABLE CachePriority in page cache // currently used for in memory olap table bool kept_in_memory = false; + // for page cache allocation + // page types are divided into DATA_PAGE & INDEX_PAGE + // INDEX_PAGE including index_page, dict_page and short_key_page + PageTypePB type; void sanity_check() const { CHECK_NOTNULL(rblock); diff --git a/be/src/olap/rowset/segment_v2/segment.cpp b/be/src/olap/rowset/segment_v2/segment.cpp index 68ddb6d..db610a9 100644 --- a/be/src/olap/rowset/segment_v2/segment.cpp +++ b/be/src/olap/rowset/segment_v2/segment.cpp @@ -143,6 +143,7 @@ Status Segment::_load_index() { opts.codec = nullptr; // short key index page uses NO_COMPRESSION for now OlapReaderStatistics tmp_stats; opts.stats = &tmp_stats; + opts.type = INDEX_PAGE; Slice body; PageFooterPB footer; diff --git a/be/src/runtime/exec_env_init.cpp b/be/src/runtime/exec_env_init.cpp index 1f725b9..d3a8bf4 100644 --- a/be/src/runtime/exec_env_init.cpp +++ b/be/src/runtime/exec_env_init.cpp @@ -192,7 +192,8 @@ Status ExecEnv::_init_mem_tracker() { LOG(WARNING) << "Config storage_page_cache_limit is greater than memory size, config=" << config::storage_page_cache_limit << ", memory=" << MemInfo::physical_mem(); } - StoragePageCache::create_global_cache(storage_cache_limit); + int32_t index_page_cache_percentage = config::index_page_cache_percentage; + StoragePageCache::create_global_cache(storage_cache_limit, index_page_cache_percentage); // TODO(zc): The current memory usage configuration is a bit confusing, // we need to sort out the use of memory diff --git a/be/test/olap/page_cache_test.cpp b/be/test/olap/page_cache_test.cpp index cdd12a3..0abd074 100644 --- a/be/test/olap/page_cache_test.cpp +++ b/be/test/olap/page_cache_test.cpp @@ -27,22 +27,25 @@ public: virtual ~StoragePageCacheTest() {} }; -TEST(StoragePageCacheTest, normal) { - StoragePageCache cache(kNumShards * 2048); +// All cache space is allocated to data pages +TEST(StoragePageCacheTest, data_page_only) { + StoragePageCache cache(kNumShards * 2048, 0); StoragePageCache::CacheKey key("abc", 0); StoragePageCache::CacheKey memory_key("mem", 0); + segment_v2::PageTypePB page_type = segment_v2::DATA_PAGE; + { // insert normal page char* buf = new char[1024]; PageCacheHandle handle; Slice data(buf, 1024); - cache.insert(key, data, &handle, false); + cache.insert(key, data, &handle, page_type, false); ASSERT_EQ(handle.data().data, buf); - auto found = cache.lookup(key, &handle); + auto found = cache.lookup(key, &handle, page_type); ASSERT_TRUE(found); ASSERT_EQ(buf, handle.data().data); } @@ -52,11 +55,11 @@ TEST(StoragePageCacheTest, normal) { char* buf = new char[1024]; PageCacheHandle handle; Slice data(buf, 1024); - cache.insert(memory_key, data, &handle, true); + cache.insert(memory_key, data, &handle, page_type, true); ASSERT_EQ(handle.data().data, buf); - auto found = cache.lookup(memory_key, &handle); + auto found = cache.lookup(memory_key, &handle, page_type); ASSERT_TRUE(found); } @@ -65,23 +68,182 @@ TEST(StoragePageCacheTest, normal) { StoragePageCache::CacheKey key("bcd", i); PageCacheHandle handle; Slice data(new char[1024], 1024); - cache.insert(key, data, &handle, false); + cache.insert(key, data, &handle, page_type, false); } // cache miss { PageCacheHandle handle; StoragePageCache::CacheKey miss_key("abc", 1); - auto found = cache.lookup(miss_key, &handle); + auto found = cache.lookup(miss_key, &handle, page_type); ASSERT_FALSE(found); } // cache miss for eliminated key { PageCacheHandle handle; - auto found = cache.lookup(key, &handle); + auto found = cache.lookup(key, &handle, page_type); ASSERT_FALSE(found); } + +} + +// All cache space is allocated to index pages +TEST(StoragePageCacheTest, index_page_only) { + StoragePageCache cache(kNumShards * 2048, 100); + + StoragePageCache::CacheKey key("abc", 0); + StoragePageCache::CacheKey memory_key("mem", 0); + + segment_v2::PageTypePB page_type = segment_v2::INDEX_PAGE; + + { + // insert normal page + char* buf = new char[1024]; + PageCacheHandle handle; + Slice data(buf, 1024); + cache.insert(key, data, &handle, page_type, false); + + ASSERT_EQ(handle.data().data, buf); + + auto found = cache.lookup(key, &handle, page_type); + ASSERT_TRUE(found); + ASSERT_EQ(buf, handle.data().data); + } + + { + // insert in_memory page + char* buf = new char[1024]; + PageCacheHandle handle; + Slice data(buf, 1024); + cache.insert(memory_key, data, &handle, page_type, true); + + ASSERT_EQ(handle.data().data, buf); + + auto found = cache.lookup(memory_key, &handle, page_type); + ASSERT_TRUE(found); + } + + // put too many page to eliminate first page + for (int i = 0; i < 10 * kNumShards; ++i) { + StoragePageCache::CacheKey key("bcd", i); + PageCacheHandle handle; + Slice data(new char[1024], 1024); + cache.insert(key, data, &handle, page_type, false); + } + + // cache miss + { + PageCacheHandle handle; + StoragePageCache::CacheKey miss_key("abc", 1); + auto found = cache.lookup(miss_key, &handle, page_type); + ASSERT_FALSE(found); + } + + // cache miss for eliminated key + { + PageCacheHandle handle; + auto found = cache.lookup(key, &handle, page_type); + ASSERT_FALSE(found); + } + +} + +// Cache space is allocated by index_page_cache_ratio +TEST(StoragePageCacheTest, mixed_pages) { + StoragePageCache cache(kNumShards * 2048, 10); + + StoragePageCache::CacheKey data_key("data", 0); + StoragePageCache::CacheKey index_key("index", 0); + StoragePageCache::CacheKey data_key_mem("data_mem", 0); + StoragePageCache::CacheKey index_key_mem("index_mem", 0); + + segment_v2::PageTypePB page_type_data = segment_v2::DATA_PAGE; + segment_v2::PageTypePB page_type_index = segment_v2::INDEX_PAGE; + + { + // insert both normal pages + char* buf_data = new char[1024]; + char* buf_index = new char[1024]; + PageCacheHandle data_handle, index_handle; + Slice data(buf_data, 1024), index(buf_index, 1024); + cache.insert(data_key, data, &data_handle, page_type_data, false); + cache.insert(index_key, index, &index_handle, page_type_index, false); + + ASSERT_EQ(data_handle.data().data, buf_data); + ASSERT_EQ(index_handle.data().data, buf_index); + + auto found_data = cache.lookup(data_key, &data_handle, page_type_data); + auto found_index = cache.lookup(index_key, &index_handle, page_type_index); + ASSERT_TRUE(found_data); + ASSERT_TRUE(found_index); + ASSERT_EQ(buf_data, data_handle.data().data); + ASSERT_EQ(buf_index, index_handle.data().data); + } + + { + // insert both in_memory pages + char* buf_data = new char[1024]; + char* buf_index = new char[1024]; + PageCacheHandle data_handle, index_handle; + Slice data(buf_data, 1024), index(buf_index, 1024); + cache.insert(data_key_mem, data, &data_handle, page_type_data, true); + cache.insert(index_key_mem, index, &index_handle, page_type_index, true); + + ASSERT_EQ(data_handle.data().data, buf_data); + ASSERT_EQ(index_handle.data().data, buf_index); + + auto found_data = cache.lookup(data_key_mem, &data_handle, page_type_data); + auto found_index = cache.lookup(index_key_mem, &index_handle, page_type_index); + ASSERT_TRUE(found_data); + ASSERT_TRUE(found_index); + } + + // put too many page to eliminate first page of both cache + for (int i = 0; i < 10 * kNumShards; ++i) { + StoragePageCache::CacheKey key("bcd", i); + PageCacheHandle handle; + Slice data(new char[1024], 1024), index(new char[1024], 1024); + cache.insert(key, data, &handle, page_type_data, false); + cache.insert(key, index, &handle, page_type_index, false); + } + + // cache miss by key + { + PageCacheHandle data_handle, index_handle; + StoragePageCache::CacheKey miss_key("abc", 1); + auto found_data = cache.lookup(miss_key, &data_handle, page_type_data); + auto found_index = cache.lookup(miss_key, &index_handle, page_type_index); + ASSERT_FALSE(found_data); + ASSERT_FALSE(found_index); + } + + // cache miss by page type + { + PageCacheHandle data_handle, index_handle; + StoragePageCache::CacheKey miss_key_data("data_miss", 1); + StoragePageCache::CacheKey miss_key_index("index_miss", 1); + char* buf_data = new char[1024]; + char* buf_index = new char[1024]; + Slice data(buf_data, 1024), index(buf_index, 1024); + cache.insert(miss_key_data, data, &data_handle, page_type_data, false); + cache.insert(miss_key_index, index, &index_handle, page_type_index, false); + + auto found_data = cache.lookup(miss_key_data, &data_handle, page_type_index); + auto found_index = cache.lookup(miss_key_index, &index_handle, page_type_data); + ASSERT_FALSE(found_data); + ASSERT_FALSE(found_index); + } + + // cache miss for eliminated key + { + PageCacheHandle data_handle, index_handle; + auto found_data = cache.lookup(data_key, &data_handle, page_type_data); + auto found_index = cache.lookup(index_key, &index_handle, page_type_index); + ASSERT_FALSE(found_data); + ASSERT_FALSE(found_index); + } + } } // namespace doris diff --git a/be/test/olap/rowset/beta_rowset_test.cpp b/be/test/olap/rowset/beta_rowset_test.cpp index ec864b9..6191e6f 100644 --- a/be/test/olap/rowset/beta_rowset_test.cpp +++ b/be/test/olap/rowset/beta_rowset_test.cpp @@ -353,7 +353,7 @@ TEST_F(BetaRowsetTest, BasicFunctionTest) { } // namespace doris int main(int argc, char** argv) { - doris::StoragePageCache::create_global_cache(1 << 30); + doris::StoragePageCache::create_global_cache(1 << 30, 0.1); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/be/test/olap/rowset/rowset_converter_test.cpp b/be/test/olap/rowset/rowset_converter_test.cpp index 47c8e69..867c711 100644 --- a/be/test/olap/rowset/rowset_converter_test.cpp +++ b/be/test/olap/rowset/rowset_converter_test.cpp @@ -298,7 +298,7 @@ TEST_F(RowsetConverterTest, TestConvertBetaRowsetToAlpha) { } // namespace doris int main(int argc, char** argv) { - doris::StoragePageCache::create_global_cache(1 << 30); + doris::StoragePageCache::create_global_cache(1 << 30, 0.1); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/be/test/olap/rowset/segment_v2/bitmap_index_test.cpp b/be/test/olap/rowset/segment_v2/bitmap_index_test.cpp index a04c21e..8603e4c 100644 --- a/be/test/olap/rowset/segment_v2/bitmap_index_test.cpp +++ b/be/test/olap/rowset/segment_v2/bitmap_index_test.cpp @@ -238,7 +238,7 @@ TEST_F(BitmapIndexTest, test_null) { } // namespace doris int main(int argc, char** argv) { - doris::StoragePageCache::create_global_cache(1 << 30); + doris::StoragePageCache::create_global_cache(1 << 30, 0.1); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/be/test/olap/rowset/segment_v2/bloom_filter_index_reader_writer_test.cpp b/be/test/olap/rowset/segment_v2/bloom_filter_index_reader_writer_test.cpp index 8795699..ee82e0d 100644 --- a/be/test/olap/rowset/segment_v2/bloom_filter_index_reader_writer_test.cpp +++ b/be/test/olap/rowset/segment_v2/bloom_filter_index_reader_writer_test.cpp @@ -291,7 +291,7 @@ TEST_F(BloomFilterIndexReaderWriterTest, test_decimal) { } // namespace doris int main(int argc, char** argv) { - doris::StoragePageCache::create_global_cache(1 << 30); + doris::StoragePageCache::create_global_cache(1 << 30, 0.1); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/be/test/olap/rowset/segment_v2/column_reader_writer_test.cpp b/be/test/olap/rowset/segment_v2/column_reader_writer_test.cpp index 057ccfb..bf2e7dad 100644 --- a/be/test/olap/rowset/segment_v2/column_reader_writer_test.cpp +++ b/be/test/olap/rowset/segment_v2/column_reader_writer_test.cpp @@ -673,7 +673,7 @@ TEST_F(ColumnReaderWriterTest, test_default_value) { } // namespace doris int main(int argc, char** argv) { - doris::StoragePageCache::create_global_cache(1 << 30); + doris::StoragePageCache::create_global_cache(1 << 30, 0.1); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/be/test/olap/rowset/segment_v2/ordinal_page_index_test.cpp b/be/test/olap/rowset/segment_v2/ordinal_page_index_test.cpp index caa3ab7..9c4fd85 100644 --- a/be/test/olap/rowset/segment_v2/ordinal_page_index_test.cpp +++ b/be/test/olap/rowset/segment_v2/ordinal_page_index_test.cpp @@ -158,7 +158,7 @@ TEST_F(OrdinalPageIndexTest, one_data_page) { } // namespace doris int main(int argc, char** argv) { - doris::StoragePageCache::create_global_cache(1 << 30); + doris::StoragePageCache::create_global_cache(1 << 30, 0.1); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/be/test/olap/rowset/segment_v2/segment_test.cpp b/be/test/olap/rowset/segment_v2/segment_test.cpp index f4971b6..34291ea 100644 --- a/be/test/olap/rowset/segment_v2/segment_test.cpp +++ b/be/test/olap/rowset/segment_v2/segment_test.cpp @@ -1160,7 +1160,7 @@ TEST_F(SegmentReaderWriterTest, TestBloomFilterIndexUniqueModel) { } // namespace doris int main(int argc, char** argv) { - doris::StoragePageCache::create_global_cache(1 << 30); + doris::StoragePageCache::create_global_cache(1 << 30, 0.1); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/be/test/olap/rowset/segment_v2/zone_map_index_test.cpp b/be/test/olap/rowset/segment_v2/zone_map_index_test.cpp index f2f49fc..e795fb5 100644 --- a/be/test/olap/rowset/segment_v2/zone_map_index_test.cpp +++ b/be/test/olap/rowset/segment_v2/zone_map_index_test.cpp @@ -175,7 +175,7 @@ TEST_F(ColumnZoneMapTest, NormalTestCharPage) { } // namespace doris int main(int argc, char** argv) { - doris::StoragePageCache::create_global_cache(1 << 30); + doris::StoragePageCache::create_global_cache(1 << 30, 0.1); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/docs/en/administrator-guide/config/be_config.md b/docs/en/administrator-guide/config/be_config.md index 2a9096f..79e8813 100644 --- a/docs/en/administrator-guide/config/be_config.md +++ b/docs/en/administrator-guide/config/be_config.md @@ -720,6 +720,11 @@ Indicates how many tablets in this data directory failed to load. At the same ti ### `storage_page_cache_limit` +### `index_page_cache_percentage` +* Type: int32 +* Description: Index page cache as a percentage of total storage page cache, value range is [0, 100] +* Default value: 10 + ### `storage_root_path` * Type: string diff --git a/docs/zh-CN/administrator-guide/config/be_config.md b/docs/zh-CN/administrator-guide/config/be_config.md index 0bc0d38..3f6345b 100644 --- a/docs/zh-CN/administrator-guide/config/be_config.md +++ b/docs/zh-CN/administrator-guide/config/be_config.md @@ -720,6 +720,11 @@ load tablets from header failed, failed tablets size: xxx, path=xxx ### `storage_page_cache_limit` +### `index_page_cache_percentage` +* 类型:int32 +* 描述:索引页缓存占总页面缓存的百分比,取值为[0, 100]。 +* 默认值:10 + ### `storage_root_path` * 类型:string --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org