This is an automated email from the ASF dual-hosted git repository.
dataroaring 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 4e06f136f00 [fix](segment cache) estimate momory consumed by segment
(#35647) (#35751)
4e06f136f00 is described below
commit 4e06f136f0096a8348678a56f0300851fc7034bb
Author: Yongqiang YANG <[email protected]>
AuthorDate: Sat Jun 1 09:34:32 2024 +0800
[fix](segment cache) estimate momory consumed by segment (#35647) (#35751)
The memory consumed in segment cache is 0 after
https://github.com/apache/doris/pull/35432/files.
The pr also tracks memory usage of column readers.
---
be/src/olap/base_tablet.cpp | 4 ++++
be/src/olap/primary_key_index.cpp | 2 ++
be/src/olap/rowset/rowset.cpp | 7 +++++++
be/src/olap/rowset/rowset.h | 2 +-
be/src/olap/rowset/segment_v2/column_reader.cpp | 11 ++++++++++-
be/src/olap/rowset/segment_v2/column_reader.h | 2 +-
.../olap/rowset/segment_v2/indexed_column_reader.cpp | 8 ++++++++
be/src/olap/rowset/segment_v2/indexed_column_reader.h | 2 ++
be/src/olap/rowset/segment_v2/ordinal_page_index.cpp | 14 ++++++++++++++
be/src/olap/rowset/segment_v2/ordinal_page_index.h | 2 ++
be/src/olap/rowset/segment_v2/segment.cpp | 18 ++++++++++++++----
be/src/olap/rowset/segment_v2/segment.h | 1 +
be/src/olap/rowset/segment_v2/zone_map_index.cpp | 11 +++++++++++
be/src/olap/rowset/segment_v2/zone_map_index.h | 2 ++
be/src/olap/short_key_index.cpp | 16 ++++++++++++++++
be/src/olap/short_key_index.h | 1 +
be/src/olap/tablet_schema.cpp | 10 ++++++++++
be/src/olap/tablet_schema.h | 4 +++-
18 files changed, 109 insertions(+), 8 deletions(-)
diff --git a/be/src/olap/base_tablet.cpp b/be/src/olap/base_tablet.cpp
index 43f514906cf..8901aee0e5a 100644
--- a/be/src/olap/base_tablet.cpp
+++ b/be/src/olap/base_tablet.cpp
@@ -33,6 +33,8 @@ extern MetricPrototype METRIC_query_scan_count;
DEFINE_COUNTER_METRIC_PROTOTYPE_2ARG(flush_bytes, MetricUnit::BYTES);
DEFINE_COUNTER_METRIC_PROTOTYPE_2ARG(flush_finish_count,
MetricUnit::OPERATIONS);
+static bvar::Adder<size_t> g_total_tablet_num("doris_total_tablet_num");
+
BaseTablet::BaseTablet(TabletMetaSharedPtr tablet_meta) :
_tablet_meta(std::move(tablet_meta)) {
_metric_entity =
DorisMetrics::instance()->metric_registry()->register_entity(
fmt::format("Tablet.{}", tablet_id()), {{"tablet_id",
std::to_string(tablet_id())}},
@@ -42,10 +44,12 @@ BaseTablet::BaseTablet(TabletMetaSharedPtr tablet_meta) :
_tablet_meta(std::move
INT_COUNTER_METRIC_REGISTER(_metric_entity, query_scan_count);
INT_COUNTER_METRIC_REGISTER(_metric_entity, flush_bytes);
INT_COUNTER_METRIC_REGISTER(_metric_entity, flush_finish_count);
+ g_total_tablet_num << 1;
}
BaseTablet::~BaseTablet() {
DorisMetrics::instance()->metric_registry()->deregister_entity(_metric_entity);
+ g_total_tablet_num << -1;
}
Status BaseTablet::set_tablet_state(TabletState state) {
diff --git a/be/src/olap/primary_key_index.cpp
b/be/src/olap/primary_key_index.cpp
index 6d1b1772a91..6ea4bc30d0a 100644
--- a/be/src/olap/primary_key_index.cpp
+++ b/be/src/olap/primary_key_index.cpp
@@ -32,6 +32,8 @@
namespace doris {
+static bvar::Adder<size_t>
g_primary_key_index_memory_bytes("doris_primary_key_index_memory_bytes");
+
Status PrimaryKeyIndexBuilder::init() {
// TODO(liaoxin) using the column type directly if there's only one column
in unique key columns
const auto* type_info =
get_scalar_type_info<FieldType::OLAP_FIELD_TYPE_VARCHAR>();
diff --git a/be/src/olap/rowset/rowset.cpp b/be/src/olap/rowset/rowset.cpp
index c9fa1c6a3b9..f4667d3fb63 100644
--- a/be/src/olap/rowset/rowset.cpp
+++ b/be/src/olap/rowset/rowset.cpp
@@ -26,6 +26,8 @@
namespace doris {
+static bvar::Adder<size_t> g_total_rowset_num("doris_total_rowset_num");
+
Rowset::Rowset(const TabletSchemaSPtr& schema, const RowsetMetaSharedPtr&
rowset_meta)
: _rowset_meta(rowset_meta), _refs_by_reader(0) {
_is_pending = !_rowset_meta->has_version();
@@ -37,6 +39,11 @@ Rowset::Rowset(const TabletSchemaSPtr& schema, const
RowsetMetaSharedPtr& rowset
}
// build schema from RowsetMeta.tablet_schema or Tablet.tablet_schema
_schema = _rowset_meta->tablet_schema() ? _rowset_meta->tablet_schema() :
schema;
+ g_total_rowset_num << 1;
+}
+
+Rowset::~Rowset() {
+ g_total_rowset_num << -1;
}
Status Rowset::load(bool use_cache) {
diff --git a/be/src/olap/rowset/rowset.h b/be/src/olap/rowset/rowset.h
index dffa4a7a3ee..6194703176f 100644
--- a/be/src/olap/rowset/rowset.h
+++ b/be/src/olap/rowset/rowset.h
@@ -118,7 +118,7 @@ private:
class Rowset : public std::enable_shared_from_this<Rowset> {
public:
- virtual ~Rowset() = default;
+ virtual ~Rowset();
// Open all segment files in this rowset and load necessary metadata.
// - `use_cache` : whether to use fd cache, only applicable to alpha
rowset now
diff --git a/be/src/olap/rowset/segment_v2/column_reader.cpp
b/be/src/olap/rowset/segment_v2/column_reader.cpp
index 6d5c28b8d6d..24b755d70cd 100644
--- a/be/src/olap/rowset/segment_v2/column_reader.cpp
+++ b/be/src/olap/rowset/segment_v2/column_reader.cpp
@@ -76,6 +76,9 @@
namespace doris {
namespace segment_v2 {
+static bvar::Adder<size_t>
g_column_reader_memory_bytes("doris_column_reader_memory_bytes");
+static bvar::Adder<size_t> g_column_reader_num("doris_column_reader_num");
+
Status ColumnReader::create(const ColumnReaderOptions& opts, const
ColumnMetaPB& meta,
uint64_t num_rows, const io::FileReaderSPtr&
file_reader,
std::unique_ptr<ColumnReader>* reader) {
@@ -205,9 +208,15 @@ ColumnReader::ColumnReader(const ColumnReaderOptions&
opts, const ColumnMetaPB&
_meta_is_nullable = meta.is_nullable();
_meta_dict_page = meta.dict_page();
_meta_compression = meta.compression();
+
+ g_column_reader_memory_bytes << sizeof(*this);
+ g_column_reader_num << 1;
}
-ColumnReader::~ColumnReader() = default;
+ColumnReader::~ColumnReader() {
+ g_column_reader_memory_bytes << -sizeof(*this);
+ g_column_reader_num << -1;
+}
Status ColumnReader::init(const ColumnMetaPB* meta) {
_type_info = get_type_info(meta);
diff --git a/be/src/olap/rowset/segment_v2/column_reader.h
b/be/src/olap/rowset/segment_v2/column_reader.h
index 30f916d00cd..f7330b1727b 100644
--- a/be/src/olap/rowset/segment_v2/column_reader.h
+++ b/be/src/olap/rowset/segment_v2/column_reader.h
@@ -116,7 +116,7 @@ public:
enum DictEncodingType { UNKNOWN_DICT_ENCODING, PARTIAL_DICT_ENCODING,
ALL_DICT_ENCODING };
- ~ColumnReader();
+ virtual ~ColumnReader();
// create a new column iterator. Client should delete returned iterator
Status new_iterator(ColumnIterator** iterator);
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 b5f974fb8a0..59251b5595d 100644
--- a/be/src/olap/rowset/segment_v2/indexed_column_reader.cpp
+++ b/be/src/olap/rowset/segment_v2/indexed_column_reader.cpp
@@ -56,6 +56,8 @@ static bvar::Adder<uint64_t>
g_index_reader_pk_pages("doris_pk", "index_reader_p
static bvar::PerSecond<bvar::Adder<uint64_t>>
g_index_reader_pk_bytes_per_second(
"doris_pk", "index_reader_pk_pages_per_second",
&g_index_reader_pk_pages, 60);
+static bvar::Adder<uint64_t>
g_index_reader_memory_bytes("doris_index_reader_memory_bytes");
+
using strings::Substitute;
Status IndexedColumnReader::load(bool use_page_cache, bool kept_in_memory) {
@@ -91,6 +93,8 @@ Status IndexedColumnReader::load(bool use_page_cache, bool
kept_in_memory) {
}
}
_num_values = _meta.num_values();
+
+ g_index_reader_memory_bytes << sizeof(*this);
return Status::OK();
}
@@ -134,6 +138,10 @@ Status IndexedColumnReader::read_page(const PagePointer&
pp, PageHandle* handle,
return st;
}
+IndexedColumnReader::~IndexedColumnReader() {
+ g_index_reader_memory_bytes << -sizeof(*this);
+}
+
///////////////////////////////////////////////////////////////////////////////
Status IndexedColumnIterator::_read_data_page(const PagePointer& pp) {
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 ef6e2754609..d156643a21c 100644
--- a/be/src/olap/rowset/segment_v2/indexed_column_reader.h
+++ b/be/src/olap/rowset/segment_v2/indexed_column_reader.h
@@ -51,6 +51,8 @@ public:
explicit IndexedColumnReader(io::FileReaderSPtr file_reader, const
IndexedColumnMetaPB& meta)
: _file_reader(std::move(file_reader)), _meta(meta) {}
+ ~IndexedColumnReader();
+
Status load(bool use_page_cache, bool kept_in_memory);
// read a page specified by `pp' from `file' into `handle'
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 5761cc42b9d..b93d461d8c7 100644
--- a/be/src/olap/rowset/segment_v2/ordinal_page_index.cpp
+++ b/be/src/olap/rowset/segment_v2/ordinal_page_index.cpp
@@ -29,9 +29,13 @@
#include "olap/olap_common.h"
#include "olap/rowset/segment_v2/page_handle.h"
#include "olap/rowset/segment_v2/page_io.h"
+#include "ordinal_page_index.h"
#include "util/slice.h"
namespace doris {
+
+static bvar::Adder<size_t>
g_ordinal_index_memory_bytes("doris_ordinal_index_memory_bytes");
+
namespace segment_v2 {
void OrdinalIndexWriter::append_entry(ordinal_t ordinal, const PagePointer&
data_pp) {
@@ -122,6 +126,10 @@ Status OrdinalIndexReader::_load(bool use_page_cache, bool
kept_in_memory,
_pages[i] = reader.get_value(i);
}
_ordinals[_num_pages] = _num_values;
+
+ g_ordinal_index_memory_bytes << sizeof(*this) + _ordinals.size() *
sizeof(ordinal_t) +
+ _pages.size() *
sizeof(PagePointer) +
+ sizeof(OrdinalIndexReader);
return Status::OK();
}
@@ -146,5 +154,11 @@ OrdinalPageIndexIterator
OrdinalIndexReader::seek_at_or_before(ordinal_t ordinal
return OrdinalPageIndexIterator(this, left);
}
+OrdinalIndexReader::~OrdinalIndexReader() {
+ g_ordinal_index_memory_bytes << -sizeof(*this) - _ordinals.size() *
sizeof(ordinal_t) -
+ _pages.size() *
sizeof(PagePointer) -
+ sizeof(OrdinalIndexReader);
+}
+
} // namespace segment_v2
} // namespace doris
diff --git a/be/src/olap/rowset/segment_v2/ordinal_page_index.h
b/be/src/olap/rowset/segment_v2/ordinal_page_index.h
index 77f0b851816..8f9e0afe1bf 100644
--- a/be/src/olap/rowset/segment_v2/ordinal_page_index.h
+++ b/be/src/olap/rowset/segment_v2/ordinal_page_index.h
@@ -72,6 +72,8 @@ public:
_meta_pb.reset(new OrdinalIndexPB(meta_pb));
}
+ virtual ~OrdinalIndexReader();
+
// load and parse the index page into memory
Status load(bool use_page_cache, bool kept_in_memory);
diff --git a/be/src/olap/rowset/segment_v2/segment.cpp
b/be/src/olap/rowset/segment_v2/segment.cpp
index c18eec3ad6e..e121639ac9e 100644
--- a/be/src/olap/rowset/segment_v2/segment.cpp
+++ b/be/src/olap/rowset/segment_v2/segment.cpp
@@ -113,6 +113,17 @@ Status Segment::_open() {
// DCHECK(footer.has_short_key_index_page());
_sk_index_page = _footer_pb->short_key_index_page();
_num_rows = _footer_pb->num_rows();
+
+ // An estimated memory usage of a segment
+ _meta_mem_usage += _footer_pb->ByteSizeLong();
+ _meta_mem_usage += sizeof(*this);
+ _meta_mem_usage += _tablet_schema->num_columns() *
config::estimated_mem_per_column_reader;
+
+ // 1024 comes from SegmentWriterOptions
+ _meta_mem_usage += (_num_rows + 1023) / 1024 * (36 + 4);
+ // 0.01 comes from PrimaryKeyIndexBuilder::init
+ _meta_mem_usage += BloomFilter::optimal_bit_num(_num_rows, 0.01) / 8;
+
return Status::OK();
}
@@ -301,7 +312,7 @@ Status Segment::_load_pk_bloom_filter() {
auto status = [this]() {
return _load_pk_bf_once.call([this] {
RETURN_IF_ERROR(_pk_index_reader->parse_bf(_file_reader,
*_pk_index_meta));
- _meta_mem_usage += _pk_index_reader->get_bf_memory_size();
+ // _meta_mem_usage += _pk_index_reader->get_bf_memory_size();
return Status::OK();
});
}();
@@ -338,7 +349,7 @@ Status Segment::_load_index_impl() {
if (_tablet_schema->keys_type() == UNIQUE_KEYS && _pk_index_meta !=
nullptr) {
_pk_index_reader.reset(new PrimaryKeyIndexReader());
RETURN_IF_ERROR(_pk_index_reader->parse_index(_file_reader,
*_pk_index_meta));
- _meta_mem_usage += _pk_index_reader->get_memory_size();
+ // _meta_mem_usage += _pk_index_reader->get_memory_size();
return Status::OK();
} else {
// read and parse short key index page
@@ -360,7 +371,7 @@ Status Segment::_load_index_impl() {
DCHECK_EQ(footer.type(), SHORT_KEY_PAGE);
DCHECK(footer.has_short_key_page_footer());
- _meta_mem_usage += body.get_size();
+ // _meta_mem_usage += body.get_size();
_sk_index_decoder.reset(new ShortKeyIndexDecoder);
return _sk_index_decoder->parse(body,
footer.short_key_page_footer());
}
@@ -430,7 +441,6 @@ Status Segment::_create_column_readers(const
SegmentFooterPB& footer) {
RETURN_IF_ERROR(ColumnReader::create(opts,
footer.columns(iter->second), footer.num_rows(),
_file_reader, &reader));
_column_readers.emplace(column.unique_id(), std::move(reader));
- _meta_mem_usage += config::estimated_mem_per_column_reader;
}
// init by column path
diff --git a/be/src/olap/rowset/segment_v2/segment.h
b/be/src/olap/rowset/segment_v2/segment.h
index 269d5f86364..1afe0311ffe 100644
--- a/be/src/olap/rowset/segment_v2/segment.h
+++ b/be/src/olap/rowset/segment_v2/segment.h
@@ -256,6 +256,7 @@ private:
// used to hold short key index page in memory
PageHandle _sk_index_handle;
// short key index decoder
+ // all content is in memory
std::unique_ptr<ShortKeyIndexDecoder> _sk_index_decoder;
// primary key index reader
std::unique_ptr<PrimaryKeyIndexReader> _pk_index_reader;
diff --git a/be/src/olap/rowset/segment_v2/zone_map_index.cpp
b/be/src/olap/rowset/segment_v2/zone_map_index.cpp
index e232e448ff6..6a1dee39cd7 100644
--- a/be/src/olap/rowset/segment_v2/zone_map_index.cpp
+++ b/be/src/olap/rowset/segment_v2/zone_map_index.cpp
@@ -39,6 +39,8 @@
namespace doris {
struct uint24_t;
+static bvar::Adder<size_t>
g_zone_map_memory_bytes("doris_zone_map_memory_bytes");
+
namespace segment_v2 {
template <PrimitiveType Type>
@@ -173,9 +175,18 @@ Status ZoneMapIndexReader::_load(bool use_page_cache, bool
kept_in_memory,
return Status::Corruption("Failed to parse zone map");
}
}
+
+ g_zone_map_memory_bytes << sizeof(*this) + sizeof(ZoneMapPB) *
_page_zone_maps.size() +
+ sizeof(IndexedColumnMetaPB);
+
return Status::OK();
}
+ZoneMapIndexReader::~ZoneMapIndexReader() {
+ // Maybe wrong due to load failures.
+ g_zone_map_memory_bytes << -sizeof(*this) - sizeof(ZoneMapPB) *
_page_zone_maps.size() -
+ sizeof(IndexedColumnMetaPB);
+}
#define APPLY_FOR_PRIMITITYPE(M) \
M(TYPE_TINYINT) \
M(TYPE_SMALLINT) \
diff --git a/be/src/olap/rowset/segment_v2/zone_map_index.h
b/be/src/olap/rowset/segment_v2/zone_map_index.h
index eeb87eb7da7..923bd2c2046 100644
--- a/be/src/olap/rowset/segment_v2/zone_map_index.h
+++ b/be/src/olap/rowset/segment_v2/zone_map_index.h
@@ -151,6 +151,8 @@ public:
_page_zone_maps_meta.reset(new IndexedColumnMetaPB(page_zone_maps));
}
+ virtual ~ZoneMapIndexReader();
+
// load all page zone maps into memory
Status load(bool use_page_cache, bool kept_in_memory);
diff --git a/be/src/olap/short_key_index.cpp b/be/src/olap/short_key_index.cpp
index 69622cee454..3ef235e3018 100644
--- a/be/src/olap/short_key_index.cpp
+++ b/be/src/olap/short_key_index.cpp
@@ -22,12 +22,16 @@
#include <ostream>
#include "gutil/strings/substitute.h"
+#include "short_key_index.h"
+#include "util/bvar_helper.h"
#include "util/coding.h"
using strings::Substitute;
namespace doris {
+static bvar::Adder<size_t>
g_short_key_index_memory_bytes("doris_short_key_index_memory_bytes");
+
Status ShortKeyIndexBuilder::add_item(const Slice& key) {
put_varint32(&_offset_buf, _key_buf.size());
_key_buf.append(key.data, key.size);
@@ -85,7 +89,19 @@ Status ShortKeyIndexDecoder::parse(const Slice& body, const
segment_v2::ShortKey
return Status::Corruption("Still has data after parse all key offset");
}
_parsed = true;
+
+ g_short_key_index_memory_bytes << sizeof(_footer) + _key_data.size +
+ _offsets.size() *
sizeof(uint32_t) + sizeof(*this);
+
return Status::OK();
}
+ShortKeyIndexDecoder::~ShortKeyIndexDecoder() {
+ if (_parsed) {
+ g_short_key_index_memory_bytes << -sizeof(_footer) - _key_data.size -
+ _offsets.size() *
sizeof(uint32_t) -
+ sizeof(*this);
+ }
+}
+
} // namespace doris
diff --git a/be/src/olap/short_key_index.h b/be/src/olap/short_key_index.h
index 79303a3edbb..93f4b614908 100644
--- a/be/src/olap/short_key_index.h
+++ b/be/src/olap/short_key_index.h
@@ -135,6 +135,7 @@ private:
class ShortKeyIndexDecoder {
public:
ShortKeyIndexDecoder() : _parsed(false) {}
+ virtual ~ShortKeyIndexDecoder();
// client should assure that body is available when this class is used
Status parse(const Slice& body, const segment_v2::ShortKeyFooterPB&
footer);
diff --git a/be/src/olap/tablet_schema.cpp b/be/src/olap/tablet_schema.cpp
index a44abedc354..99bdf5a8973 100644
--- a/be/src/olap/tablet_schema.cpp
+++ b/be/src/olap/tablet_schema.cpp
@@ -53,6 +53,8 @@
namespace doris {
+static bvar::Adder<size_t>
g_total_tablet_schema_num("doris_total_tablet_schema_num");
+
FieldType TabletColumn::get_field_type_by_type(PrimitiveType primitiveType) {
switch (primitiveType) {
case PrimitiveType::INVALID_TYPE:
@@ -809,6 +811,14 @@ void TabletIndex::to_schema_pb(TabletIndexPB* index) const
{
}
}
+TabletSchema::TabletSchema() {
+ g_total_tablet_schema_num << 1;
+}
+
+TabletSchema::~TabletSchema() {
+ g_total_tablet_schema_num << -1;
+}
+
void TabletSchema::append_column(TabletColumn column, ColumnType col_type) {
if (column.is_key()) {
_num_key_columns++;
diff --git a/be/src/olap/tablet_schema.h b/be/src/olap/tablet_schema.h
index c9e8fdce54e..c6fc428195d 100644
--- a/be/src/olap/tablet_schema.h
+++ b/be/src/olap/tablet_schema.h
@@ -269,7 +269,9 @@ public:
// TODO(yingchun): better to make constructor as private to avoid
// manually init members incorrectly, and define a new function like
// void create_from_pb(const TabletSchemaPB& schema, TabletSchema*
tablet_schema).
- TabletSchema() = default;
+ TabletSchema();
+ virtual ~TabletSchema();
+
void init_from_pb(const TabletSchemaPB& schema, bool
ignore_extracted_columns = false);
// Notice: Use deterministic way to serialize protobuf,
// since serialize Map in protobuf may could lead to un-deterministic by
default
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]