Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 3.9k
[enhancement](compaction) optimizing memory usage for compaction#36492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
0bc4f1c9a5cffcbc4ac9901f22e8da2c8f3a93005e3ac366e358983f69e584dFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -24,6 +24,7 @@ | ||
| #include <algorithm> | ||
| #include <iterator> | ||
| #include <memory> | ||
| #include <mutex> | ||
| #include <numeric> | ||
| #include <ostream> | ||
| #include <shared_mutex> | ||
| @@ -33,7 +34,9 @@ | ||
| #include "common/config.h" | ||
| #include "common/logging.h" | ||
| #include "common/status.h" | ||
| #include "olap/base_tablet.h" | ||
| #include "olap/iterators.h" | ||
| #include "olap/olap_common.h" | ||
| #include "olap/olap_define.h" | ||
| #include "olap/rowid_conversion.h" | ||
| @@ -43,6 +46,7 @@ | ||
| #include "olap/rowset/segment_v2/segment_writer.h" | ||
| #include "olap/storage_engine.h" | ||
| #include "olap/tablet.h" | ||
| #include "olap/tablet_fwd.h" | ||
| #include "olap/tablet_reader.h" | ||
| #include "olap/utils.h" | ||
| #include "util/slice.h" | ||
| @@ -241,7 +245,8 @@ Status Merger::vertical_compact_one_group( | ||
| vectorized::RowSourcesBuffer* row_source_buf, | ||
| const std::vector<RowsetReaderSharedPtr>& src_rowset_readers, | ||
| RowsetWriter* dst_rowset_writer, int64_t max_rows_per_segment, Statistics* stats_output, | ||
| std::vector<uint32_t> key_group_cluster_key_idxes) { | ||
| std::vector<uint32_t> key_group_cluster_key_idxes, int64_t batch_size, | ||
| CompactionSampleInfo* sample_info) { | ||
| // build tablet reader | ||
| VLOG_NOTICE << "vertical compact one group, max_rows_per_segment=" << max_rows_per_segment; | ||
| vectorized::VerticalBlockReader reader(row_source_buf); | ||
| @@ -279,7 +284,8 @@ Status Merger::vertical_compact_one_group( | ||
| reader_params.return_columns = column_group; | ||
| reader_params.origin_return_columns = &reader_params.return_columns; | ||
| RETURN_IF_ERROR(reader.init(reader_params)); | ||
| reader_params.batch_size = batch_size; | ||
| RETURN_IF_ERROR(reader.init(reader_params, sample_info)); | ||
| if (reader_params.record_rowids) { | ||
| stats_output->rowid_conversion->set_dst_rowset_id(dst_rowset_writer->rowset_id()); | ||
| @@ -385,6 +391,55 @@ Status Merger::vertical_compact_one_group(int64_t tablet_id, ReaderType reader_t | ||
| return Status::OK(); | ||
| } | ||
| int64_t estimate_batch_size(int group_index, BaseTabletSPtr tablet, int64_t way_cnt) { | ||
| std::unique_lock<std::mutex> lock(tablet->sample_info_lock); | ||
| CompactionSampleInfo info = tablet->sample_infos[group_index]; | ||
| if (way_cnt <= 0) { | ||
| LOG(INFO) << "estimate batch size for vertical compaction, tablet id: " | ||
| << tablet->tablet_id() << " way cnt: " << way_cnt; | ||
| return 4096 - 32; | ||
| } | ||
| int64_t block_mem_limit = config::compaction_memory_bytes_limit / way_cnt; | ||
| if (tablet->last_compaction_status.is<ErrorCode::MEM_LIMIT_EXCEEDED>()) { | ||
| block_mem_limit /= 4; | ||
| } | ||
| int64_t group_data_size = 0; | ||
| if (info.group_data_size > 0 && info.bytes > 0 && info.rows > 0) { | ||
| float smoothing_factor = 0.5; | ||
| group_data_size = int64_t(info.group_data_size * (1 - smoothing_factor) + | ||
| info.bytes / info.rows * smoothing_factor); | ||
| tablet->sample_infos[group_index].group_data_size = group_data_size; | ||
| } else if (info.group_data_size > 0 && (info.bytes <= 0 || info.rows <= 0)) { | ||
| group_data_size = info.group_data_size; | ||
| } else if (info.group_data_size <= 0 && info.bytes > 0 && info.rows > 0) { | ||
| group_data_size = info.bytes / info.rows; | ||
| tablet->sample_infos[group_index].group_data_size = group_data_size; | ||
| } else { | ||
| LOG(INFO) << "estimate batch size for vertical compaction, tablet id: " | ||
| << tablet->tablet_id() << " group data size: " << info.group_data_size | ||
| << " row num: " << info.rows << " consume bytes: " << info.bytes; | ||
| return 1024 - 32; | ||
| } | ||
| if (group_data_size <= 0) { | ||
| LOG(WARNING) << "estimate batch size for vertical compaction, tablet id: " | ||
| << tablet->tablet_id() << " unexpected group data size: " << group_data_size; | ||
| return 4096 - 32; | ||
| } | ||
| tablet->sample_infos[group_index].bytes = 0; | ||
| tablet->sample_infos[group_index].rows = 0; | ||
| int64_t batch_size = block_mem_limit / group_data_size; | ||
| int64_t res = std::max(std::min(batch_size, int64_t(4096 - 32)), 32L); | ||
| LOG(INFO) << "estimate batch size for vertical compaction, tablet id: " << tablet->tablet_id() | ||
| << " group data size: " << info.group_data_size << " row num: " << info.rows | ||
| << " consume bytes: " << info.bytes << " way cnt: " << way_cnt | ||
| << " batch size: " << res; | ||
| return res; | ||
| } | ||
| // steps to do vertical merge: | ||
| // 1. split columns into column groups | ||
| // 2. compact groups one by one, generate a row_source_buf when compact key group | ||
| @@ -394,7 +449,7 @@ Status Merger::vertical_merge_rowsets(BaseTabletSPtr tablet, ReaderType reader_t | ||
| const TabletSchema& tablet_schema, | ||
| const std::vector<RowsetReaderSharedPtr>& src_rowset_readers, | ||
| RowsetWriter* dst_rowset_writer, int64_t max_rows_per_segment, | ||
| Statistics* stats_output) { | ||
| int64_t merge_way_num, Statistics* stats_output) { | ||
| LOG(INFO) << "Start to do vertical compaction, tablet_id: " << tablet->tablet_id(); | ||
| std::vector<std::vector<uint32_t>> column_groups; | ||
| vertical_split_columns(tablet_schema, &column_groups); | ||
| @@ -405,14 +460,18 @@ Status Merger::vertical_merge_rowsets(BaseTabletSPtr tablet, ReaderType reader_t | ||
| vectorized::RowSourcesBuffer row_sources_buf( | ||
| tablet->tablet_id(), dst_rowset_writer->context().tablet_path, reader_type); | ||
| tablet->sample_infos.resize(column_groups.size(), {0, 0, 0}); | ||
| // compact group one by one | ||
| for (auto i = 0; i < column_groups.size(); ++i) { | ||
| VLOG_NOTICE << "row source size: " << row_sources_buf.total_size(); | ||
| bool is_key = (i == 0); | ||
| int64_t batch_size = config::compaction_batch_size != -1 | ||
| ? config::compaction_batch_size | ||
| : estimate_batch_size(i, tablet, merge_way_num); | ||
| RETURN_IF_ERROR(vertical_compact_one_group( | ||
| tablet, reader_type, tablet_schema, is_key, column_groups[i], &row_sources_buf, | ||
| src_rowset_readers, dst_rowset_writer, max_rows_per_segment, stats_output, | ||
| key_group_cluster_key_idxes)); | ||
| key_group_cluster_key_idxes, batch_size, &(tablet->sample_infos[i]))); | ||
| if (is_key) { | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When memlimit happens, we should adjust batch_size. ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done | ||
| RETURN_IF_ERROR(row_sources_buf.flush()); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are meta consuming memory too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR temporarily does not calculate the memory consumption of metadata