Skip to content

Commit fac7d6d

Browse files
[Feature](Cloud) Support session variable disable_file_cache and enable_segment_cache in query (#37141)
Currently, whether to read from file cache or remote storage is controlled by the BE config `enable_file_cache` in cloud mode. This PR proposed to control the file cache behavior via session variables when executing queries in cloud mode. It's more convenient when have such a session variable, cache behavior could be controlled per query/session without changing BE configs, such as: 1. **Performance test**. Test the query performance when read from local file cache or remote storage for queries. 2. **Data correctness**. Check if it's file cache issue for certain tables or queries. The read path has three kinds of caches: segment cache, page cache and file cache. | module | cache| BE config | session variable| |------------|------|----------| ---- | | Segment | segment cache | disable_segment_cache | **enable_segment_cache** (supportted by this PR) | | PageIO | page cache | disable_storage_page_cache | enable_page_cache | | FileReader | file cache | enable_file_cache | **disable_file_cache** (supportted by this PR) | The modification of the PR: - **enable_segment_cache**: add a new session variable enable_segment_cache to control use segment cache or not. - **disable_file_cache**: disable_file_cache was for write path in cloud mode. It's supported for read path when executing queries in the PR. With this PR, data is read from remote storage without cache: ```sql set enable_segment_cache=false; set enable_page_cache=false; set disable_file_cache=true; ``` Co-authored-by: Gavin Chou <[email protected]>
1 parent 4244287 commit fac7d6d

File tree

9 files changed

+78
-18
lines changed

9 files changed

+78
-18
lines changed

be/src/exec/rowid_fetcher.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ Status RowIdStorageReader::read_by_rowids(const PMultiGetRequest& request,
381381
<< ", row_size:" << row_size;
382382
*response->add_row_locs() = row_loc;
383383
});
384+
// TODO: supoort session variable enable_page_cache and disable_file_cache if necessary.
384385
SegmentCacheHandle segment_cache;
385386
RETURN_IF_ERROR(scope_timer_run(
386387
[&]() {

be/src/olap/parallel_scanner_builder.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,20 @@ Status ParallelScannerBuilder::_load() {
179179
RETURN_IF_ERROR(tablet->capture_consistent_rowsets_unlocked({0, version}, &rowsets));
180180
}
181181

182+
bool enable_segment_cache = _state->query_options().__isset.enable_segment_cache
183+
? _state->query_options().enable_segment_cache
184+
: true;
185+
bool disable_file_cache = _state->query_options().__isset.disable_file_cache
186+
? _state->query_options().disable_file_cache
187+
: false;
182188
for (auto& rowset : rowsets) {
183189
RETURN_IF_ERROR(rowset->load());
184190
const auto rowset_id = rowset->rowset_id();
185191
auto& segment_cache_handle = _segment_cache_handles[rowset_id];
186192

187193
RETURN_IF_ERROR(SegmentLoader::instance()->load_segments(
188-
std::dynamic_pointer_cast<BetaRowset>(rowset), &segment_cache_handle, true));
194+
std::dynamic_pointer_cast<BetaRowset>(rowset), &segment_cache_handle,
195+
enable_segment_cache, false, disable_file_cache));
189196
_total_rows += rowset->num_rows();
190197
}
191198
}

be/src/olap/rowset/beta_rowset.cpp

+12-7
Original file line numberDiff line numberDiff line change
@@ -147,23 +147,26 @@ Status BetaRowset::get_segments_size(std::vector<size_t>* segments_size) {
147147
return Status::OK();
148148
}
149149

150-
Status BetaRowset::load_segments(std::vector<segment_v2::SegmentSharedPtr>* segments) {
151-
return load_segments(0, num_segments(), segments);
150+
Status BetaRowset::load_segments(std::vector<segment_v2::SegmentSharedPtr>* segments,
151+
bool disable_file_cache) {
152+
return load_segments(0, num_segments(), segments, disable_file_cache);
152153
}
153154

154155
Status BetaRowset::load_segments(int64_t seg_id_begin, int64_t seg_id_end,
155-
std::vector<segment_v2::SegmentSharedPtr>* segments) {
156+
std::vector<segment_v2::SegmentSharedPtr>* segments,
157+
bool disable_file_cache) {
156158
int64_t seg_id = seg_id_begin;
157159
while (seg_id < seg_id_end) {
158160
std::shared_ptr<segment_v2::Segment> segment;
159-
RETURN_IF_ERROR(load_segment(seg_id, &segment));
161+
RETURN_IF_ERROR(load_segment(seg_id, &segment, disable_file_cache));
160162
segments->push_back(std::move(segment));
161163
seg_id++;
162164
}
163165
return Status::OK();
164166
}
165167

166-
Status BetaRowset::load_segment(int64_t seg_id, segment_v2::SegmentSharedPtr* segment) {
168+
Status BetaRowset::load_segment(int64_t seg_id, segment_v2::SegmentSharedPtr* segment,
169+
bool disable_file_cache) {
167170
auto fs = _rowset_meta->fs();
168171
if (!fs) {
169172
return Status::Error<INIT_FAILED>("get fs failed");
@@ -172,12 +175,14 @@ Status BetaRowset::load_segment(int64_t seg_id, segment_v2::SegmentSharedPtr* se
172175
DCHECK(seg_id >= 0);
173176
auto seg_path = DORIS_TRY(segment_path(seg_id));
174177
io::FileReaderOptions reader_options {
175-
.cache_type = config::enable_file_cache ? io::FileCachePolicy::FILE_BLOCK_CACHE
176-
: io::FileCachePolicy::NO_CACHE,
178+
.cache_type = !disable_file_cache && config::enable_file_cache
179+
? io::FileCachePolicy::FILE_BLOCK_CACHE
180+
: io::FileCachePolicy::NO_CACHE,
177181
.is_doris_table = true,
178182
.cache_base_path = "",
179183
.file_size = _rowset_meta->segment_file_size(seg_id),
180184
};
185+
181186
auto s = segment_v2::Segment::open(fs, seg_path, seg_id, rowset_id(), _schema, reader_options,
182187
segment);
183188
if (!s.ok()) {

be/src/olap/rowset/beta_rowset.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,15 @@ class BetaRowset final : public Rowset {
7171

7272
Status check_file_exist() override;
7373

74-
Status load_segments(std::vector<segment_v2::SegmentSharedPtr>* segments);
74+
Status load_segments(std::vector<segment_v2::SegmentSharedPtr>* segments,
75+
bool disable_file_cache = false);
7576

7677
Status load_segments(int64_t seg_id_begin, int64_t seg_id_end,
77-
std::vector<segment_v2::SegmentSharedPtr>* segments);
78+
std::vector<segment_v2::SegmentSharedPtr>* segments,
79+
bool disable_file_cache = false);
7880

79-
Status load_segment(int64_t seg_id, segment_v2::SegmentSharedPtr* segment);
81+
Status load_segment(int64_t seg_id, segment_v2::SegmentSharedPtr* segment,
82+
bool disable_file_cache = false);
8083

8184
Status get_segments_size(std::vector<size_t>* segments_size);
8285

be/src/olap/rowset/beta_rowset_reader.cpp

+17-3
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,24 @@ Status BetaRowsetReader::get_segment_iterators(RowsetReaderContext* read_context
249249
}
250250

251251
// load segments
252-
bool should_use_cache = use_cache || _read_context->reader_type == ReaderType::READER_QUERY;
252+
bool disable_file_cache = false;
253+
bool enable_segment_cache = true;
254+
auto* state = read_context->runtime_state;
255+
if (state != nullptr) {
256+
disable_file_cache = state->query_options().__isset.disable_file_cache
257+
? state->query_options().disable_file_cache
258+
: false;
259+
enable_segment_cache = state->query_options().__isset.enable_segment_cache
260+
? state->query_options().enable_segment_cache
261+
: true;
262+
}
263+
// When reader type is for query, session variable `enable_segment_cache` should be respected.
264+
bool should_use_cache = use_cache || (_read_context->reader_type == ReaderType::READER_QUERY &&
265+
enable_segment_cache);
253266
SegmentCacheHandle segment_cache_handle;
254-
RETURN_IF_ERROR(SegmentLoader::instance()->load_segments(_rowset, &segment_cache_handle,
255-
should_use_cache));
267+
RETURN_IF_ERROR(SegmentLoader::instance()->load_segments(
268+
_rowset, &segment_cache_handle, should_use_cache,
269+
/*need_load_pk_index_and_bf*/ false, disable_file_cache));
256270

257271
// create iterator for each segment
258272
auto& segments = segment_cache_handle.get_segments();

be/src/olap/segment_loader.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void SegmentCache::erase(const SegmentCache::CacheKey& key) {
5252

5353
Status SegmentLoader::load_segments(const BetaRowsetSharedPtr& rowset,
5454
SegmentCacheHandle* cache_handle, bool use_cache,
55-
bool need_load_pk_index_and_bf) {
55+
bool need_load_pk_index_and_bf, bool disable_file_cache) {
5656
if (cache_handle->is_inited()) {
5757
return Status::OK();
5858
}
@@ -62,7 +62,7 @@ Status SegmentLoader::load_segments(const BetaRowsetSharedPtr& rowset,
6262
continue;
6363
}
6464
segment_v2::SegmentSharedPtr segment;
65-
RETURN_IF_ERROR(rowset->load_segment(i, &segment));
65+
RETURN_IF_ERROR(rowset->load_segment(i, &segment, disable_file_cache));
6666
if (need_load_pk_index_and_bf) {
6767
RETURN_IF_ERROR(segment->load_pk_index_and_bf());
6868
}

be/src/olap/segment_loader.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ class SegmentLoader {
118118
// Load segments of "rowset", return the "cache_handle" which contains segments.
119119
// If use_cache is true, it will be loaded from _cache.
120120
Status load_segments(const BetaRowsetSharedPtr& rowset, SegmentCacheHandle* cache_handle,
121-
bool use_cache = false, bool need_load_pk_index_and_bf = false);
121+
bool use_cache = false, bool need_load_pk_index_and_bf = false,
122+
bool disable_file_cache = false);
122123

123124
void erase_segment(const SegmentCache::CacheKey& key);
124125

fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java

+16
Original file line numberDiff line numberDiff line change
@@ -1920,6 +1920,8 @@ public void setIgnoreRuntimeFilterIds(String ignoreRuntimeFilterIds) {
19201920

19211921
public static final String IGNORE_SHAPE_NODE = "ignore_shape_nodes";
19221922

1923+
public static final String ENABLE_SEGMENT_CACHE = "enable_segment_cache";
1924+
19231925
public Set<String> getIgnoreShapePlanNodes() {
19241926
return Arrays.stream(ignoreShapePlanNodes.split(",[\\s]*")).collect(ImmutableSet.toImmutableSet());
19251927
}
@@ -2037,6 +2039,11 @@ public void setIgnoreShapePlanNodes(String ignoreShapePlanNodes) {
20372039
})
20382040
public boolean useMaxLengthOfVarcharInCtas = true;
20392041

2042+
// Whether enable segment cache. Segment cache only works when FE's query options sets enableSegmentCache true
2043+
// along with BE's config `disable_segment_cache` false
2044+
@VariableMgr.VarAttr(name = ENABLE_SEGMENT_CACHE, needForward = true)
2045+
public boolean enableSegmentCache = true;
2046+
20402047
/**
20412048
* When enabling shard scroll, FE will plan scan ranges by shards of ES indices.
20422049
* Otherwise, FE will plan a single query to ES.
@@ -3492,6 +3499,14 @@ public void setLoadStreamPerNode(int loadStreamPerNode) {
34923499
this.loadStreamPerNode = loadStreamPerNode;
34933500
}
34943501

3502+
public void setEnableSegmentCache(boolean value) {
3503+
this.enableSegmentCache = value;
3504+
}
3505+
3506+
public boolean isEnableSegmentCache() {
3507+
return this.enableSegmentCache;
3508+
}
3509+
34953510
/**
34963511
* Serialize to thrift object.
34973512
* Used for rest api.
@@ -3623,6 +3638,7 @@ public TQueryOptions toThrift() {
36233638
tResult.setEnableMatchWithoutInvertedIndex(enableMatchWithoutInvertedIndex);
36243639
tResult.setEnableFallbackOnMissingInvertedIndex(enableFallbackOnMissingInvertedIndex);
36253640

3641+
tResult.setEnableSegmentCache(enableSegmentCache);
36263642
return tResult;
36273643
}
36283644

gensrc/thrift/PaloInternalService.thrift

+14-1
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ struct TQueryOptions {
308308
113: optional bool enable_local_merge_sort = false;
309309

310310
114: optional bool enable_parallel_result_sink = false;
311-
311+
312312
115: optional bool enable_short_circuit_query_access_column_store = false;
313313

314314
116: optional bool enable_no_need_read_data_opt = true;
@@ -321,7 +321,20 @@ struct TQueryOptions {
321321

322322
120: optional bool enable_fallback_on_missing_inverted_index = true;
323323

324+
121: optional bool keep_carriage_return = false; // \n,\r\n split line in CSV.
325+
326+
122: optional i32 runtime_bloom_filter_min_size = 1048576;
327+
328+
//Access Parquet/ORC columns by name by default. Set this property to `false` to access columns
329+
//by their ordinal position in the Hive table definition.
330+
123: optional bool hive_parquet_use_column_names = true;
331+
124: optional bool hive_orc_use_column_names = true;
332+
333+
125: optional bool enable_segment_cache = true;
334+
324335
// For cloud, to control if the content would be written into file cache
336+
// In write path, to control if the content would be written into file cache.
337+
// In read path, read from file cache or remote storage when execute query.
325338
1000: optional bool disable_file_cache = false
326339
}
327340

0 commit comments

Comments
 (0)