Skip to content

Commit 9e37b7f

Browse files
authored
support collect cross AZ network bytes for disagg tiflash (#10249)
close #10221 Signed-off-by: guo-shaoge <shaoge1994@163.com>
1 parent 59d30ee commit 9e37b7f

19 files changed

Lines changed: 275 additions & 29 deletions

dbms/src/Flash/Statistics/ConnectionProfileInfo.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#pragma once
1616

17+
#include <Common/Exception.h>
1718
#include <common/defines.h>
1819
#include <common/types.h>
1920

@@ -31,6 +32,16 @@ struct ConnectionProfileInfo
3132
InterZoneRemote = 2,
3233
};
3334
using ConnTypeVec = std::vector<ConnectionProfileInfo::ConnectionType>;
35+
36+
static ConnectionProfileInfo createForInterZone()
37+
{
38+
return ConnectionProfileInfo(ConnectionProfileInfo::ConnectionType::InterZoneRemote);
39+
}
40+
static ConnectionProfileInfo createForInnerZone()
41+
{
42+
return ConnectionProfileInfo(ConnectionProfileInfo::ConnectionType::InnerZoneRemote);
43+
}
44+
3445
static ALWAYS_INLINE ConnectionType inferConnectionType(bool is_local, bool same_zone)
3546
{
3647
if (is_local)
@@ -55,6 +66,12 @@ struct ConnectionProfileInfo
5566
{}
5667

5768
String getTypeString() const { return String(magic_enum::enum_name(type)); }
69+
void merge(const ConnectionProfileInfo & other)
70+
{
71+
RUNTIME_CHECK(type == other.type, magic_enum::enum_name(type), magic_enum::enum_name(other.type));
72+
packets += other.packets;
73+
bytes += other.bytes;
74+
}
5875

5976
Int64 packets = 0;
6077
Int64 bytes = 0;

dbms/src/Flash/Statistics/TableScanImpl.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <Flash/Statistics/ConnectionProfileInfo.h>
1717
#include <Flash/Statistics/TableScanImpl.h>
1818
#include <Interpreters/Join.h>
19+
#include <Storages/DeltaMerge/ReadThread/UnorderedInputStream.h>
20+
#include <Storages/DeltaMerge/Remote/RNSegmentInputStream.h>
1921
#include <Storages/DeltaMerge/ScanContext.h>
2022

2123
namespace DB
@@ -68,12 +70,22 @@ void TableScanStatistics::updateTableScanDetail(const std::vector<ConnectionProf
6870
remote_table_scan_detail.inter_zone_conn_profile_info.packets += connection_profile_info.packets;
6971
remote_table_scan_detail.inter_zone_conn_profile_info.bytes += connection_profile_info.bytes;
7072
}
71-
// Stats both send and receive bytes here, because remote execution summaries are not used now
73+
// Whether it's for remote read (non-disaggregated mode) or communication between CN and WN (disaggregated mode),
74+
// send bytes are always collected on the node that sends the request (i.e., the node where the table scan executor resides).
75+
// Therefore, both send bytes and receive bytes are collected here.
7276
base.updateSendConnectionInfo(connection_profile_info);
7377
base.updateReceiveConnectionInfo(connection_profile_info);
7478
}
7579
}
7680

81+
void TableScanStatistics::updateTableScanDetailForDisaggIfNecessary(const IProfilingBlockInputStream * stream)
82+
{
83+
if (const auto * unordered_stream = dynamic_cast<const DM::UnorderedInputStream *>(stream))
84+
updateTableScanDetail(unordered_stream->getConnectionProfileInfos());
85+
else if (const auto * rn_segment_stream = dynamic_cast<const DM::Remote::RNSegmentInputStream *>(stream))
86+
updateTableScanDetail(rn_segment_stream->getConnectionProfileInfos());
87+
}
88+
7789
void TableScanStatistics::collectExtraRuntimeDetail()
7890
{
7991
switch (dag_context.getExecutionMode())
@@ -91,6 +103,8 @@ void TableScanStatistics::collectExtraRuntimeDetail()
91103
else if (const auto * local_stream = dynamic_cast<const IProfilingBlockInputStream *>(&stream);
92104
local_stream)
93105
{
106+
updateTableScanDetailForDisaggIfNecessary(local_stream);
107+
94108
/// local read input stream also is IProfilingBlockInputStream
95109
const auto & prof = local_stream->getProfileInfo();
96110
local_table_scan_detail.bytes += prof.bytes;

dbms/src/Flash/Statistics/TableScanImpl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,6 @@ class TableScanStatistics : public TableScanStatisticsBase
7070

7171
private:
7272
void updateTableScanDetail(const std::vector<ConnectionProfileInfo> & connection_profile_infos);
73+
void updateTableScanDetailForDisaggIfNecessary(const IProfilingBlockInputStream * stream);
7374
};
7475
} // namespace DB

dbms/src/Operators/UnorderedSourceOp.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ UnorderedSourceOp::UnorderedSourceOp(
2626
int extra_table_id_index_,
2727
const String & req_id,
2828
const RuntimeFilteList & runtime_filter_list_,
29-
int max_wait_time_ms_)
29+
int max_wait_time_ms_,
30+
bool is_disagg_)
3031
: SourceOp(exec_context_, req_id)
3132
, task_pool(task_pool_)
3233
, ref_no(0)
@@ -35,6 +36,17 @@ UnorderedSourceOp::UnorderedSourceOp(
3536
{
3637
setHeader(AddExtraTableIDColumnTransformAction::buildHeader(columns_to_read_, extra_table_id_index_));
3738
ref_no = task_pool->increaseUnorderedInputStreamRefCount();
39+
40+
if (is_disagg_)
41+
{
42+
// One connection for inter zone, the other one for inner zone.
43+
const size_t connections = 2;
44+
io_profile_info = IOProfileInfo::createForRemote(profile_info_ptr, connections);
45+
}
46+
else
47+
{
48+
io_profile_info = IOProfileInfo::createForLocal(profile_info_ptr);
49+
}
3850
}
3951

4052
OperatorStatus UnorderedSourceOp::readImpl(Block & block)
@@ -98,4 +110,29 @@ void UnorderedSourceOp::operatePrefixImpl()
98110
}
99111
});
100112
}
113+
114+
void UnorderedSourceOp::operateSuffixImpl()
115+
{
116+
// If io_profile_info is local, it means this table scan only read local data.
117+
// So no need to update connection info, because connection info indicate it's a remote table scan,
118+
// like CoprocessorReader or read delta data from WN.
119+
if (!io_profile_info->is_local)
120+
{
121+
std::call_once(task_pool->getRemoteConnectionInfoFlag(), [&]() {
122+
auto & connection_infos = io_profile_info->connection_profile_infos;
123+
RUNTIME_CHECK(connection_infos.size() == 2, connection_infos.size());
124+
125+
auto pool_connection_info_opt = task_pool->getRemoteConnectionInfo();
126+
RUNTIME_CHECK(
127+
pool_connection_info_opt.has_value() || (task_pool->getTotalReadTasks() == 0),
128+
pool_connection_info_opt.has_value(),
129+
task_pool->getTotalReadTasks());
130+
if (pool_connection_info_opt)
131+
{
132+
connection_infos[0] = pool_connection_info_opt->first;
133+
connection_infos[1] = pool_connection_info_opt->second;
134+
}
135+
});
136+
}
137+
}
101138
} // namespace DB

dbms/src/Operators/UnorderedSourceOp.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class UnorderedSourceOp : public SourceOp
3434
int extra_table_id_index_,
3535
const String & req_id,
3636
const RuntimeFilteList & runtime_filter_list_ = std::vector<RuntimeFilterPtr>{},
37-
int max_wait_time_ms_ = 0);
37+
int max_wait_time_ms_ = 0,
38+
bool is_disagg_ = false);
3839

3940
~UnorderedSourceOp() override
4041
{
@@ -50,7 +51,7 @@ class UnorderedSourceOp : public SourceOp
5051

5152
String getName() const override { return "UnorderedSourceOp"; }
5253

53-
IOProfileInfoPtr getIOProfileInfo() const override { return IOProfileInfo::createForLocal(profile_info_ptr); }
54+
IOProfileInfoPtr getIOProfileInfo() const override { return io_profile_info; }
5455

5556
// only for unit test
5657
// The logic order of unit test is error, it will build source_op firstly and register rf secondly.
@@ -64,6 +65,7 @@ class UnorderedSourceOp : public SourceOp
6465

6566
protected:
6667
void operatePrefixImpl() override;
68+
void operateSuffixImpl() override;
6769

6870
OperatorStatus readImpl(Block & block) override;
6971

@@ -76,5 +78,6 @@ class UnorderedSourceOp : public SourceOp
7678
int max_wait_time_ms;
7779

7880
bool done = false;
81+
IOProfileInfoPtr io_profile_info;
7982
};
8083
} // namespace DB

dbms/src/Storages/DeltaMerge/ReadThread/UnorderedInputStream.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,16 @@ class UnorderedInputStream : public IProfilingBlockInputStream
3737
int extra_table_id_index_,
3838
const String & req_id,
3939
const RuntimeFilteList & runtime_filter_list_ = std::vector<RuntimeFilterPtr>{},
40-
int max_wait_time_ms_ = 0)
40+
int max_wait_time_ms_ = 0,
41+
bool is_disagg_ = false)
4142
: task_pool(task_pool_)
4243
, header(AddExtraTableIDColumnTransformAction::buildHeader(columns_to_read_, extra_table_id_index_))
4344
, log(Logger::get(req_id))
4445
, ref_no(0)
4546
, task_pool_added(false)
4647
, runtime_filter_list(runtime_filter_list_)
4748
, max_wait_time_ms(max_wait_time_ms_)
49+
, is_disagg(is_disagg_)
4850
{
4951
ref_no = task_pool->increaseUnorderedInputStreamRefCount();
5052
}
@@ -75,6 +77,8 @@ class UnorderedInputStream : public IProfilingBlockInputStream
7577
max_wait_time_ms = max_wait_time_ms_;
7678
}
7779

80+
std::vector<ConnectionProfileInfo> getConnectionProfileInfos() const { return connection_profile_infos; }
81+
7882
protected:
7983
Block readImpl() override
8084
{
@@ -116,6 +120,23 @@ class UnorderedInputStream : public IProfilingBlockInputStream
116120

117121
void readSuffixImpl() override
118122
{
123+
if (is_disagg)
124+
{
125+
std::call_once(task_pool->getRemoteConnectionInfoFlag(), [&]() {
126+
auto pool_connection_info_opt = task_pool->getRemoteConnectionInfo();
127+
RUNTIME_CHECK(
128+
pool_connection_info_opt.has_value() || (task_pool->getTotalReadTasks() == 0),
129+
pool_connection_info_opt.has_value(),
130+
task_pool->getTotalReadTasks());
131+
RUNTIME_CHECK(connection_profile_infos.empty(), connection_profile_infos.size());
132+
133+
if (pool_connection_info_opt)
134+
{
135+
connection_profile_infos.push_back(pool_connection_info_opt->first);
136+
connection_profile_infos.push_back(pool_connection_info_opt->second);
137+
}
138+
});
139+
}
119140
LOG_DEBUG(
120141
log,
121142
"Finish read from storage, pool_id={} ref_no={} rows={}",
@@ -156,6 +177,8 @@ class UnorderedInputStream : public IProfilingBlockInputStream
156177
std::vector<RuntimeFilterPtr> runtime_filter_list;
157178
int max_wait_time_ms;
158179

180+
std::vector<ConnectionProfileInfo> connection_profile_infos;
181+
const bool is_disagg;
159182
friend class tests::DeltaMergeStoreRWTest;
160183
};
161184
} // namespace DB::DM

dbms/src/Storages/DeltaMerge/Remote/RNSegmentInputStream.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,20 @@ Block RNSegmentInputStream::readImpl(FilterPtr & res_filter, bool return_filter)
8989

9090
if (!res)
9191
{
92+
static constexpr auto inter_type = ConnectionProfileInfo::ConnectionType::InterZoneRemote;
93+
static constexpr auto inner_type = ConnectionProfileInfo::ConnectionType::InnerZoneRemote;
94+
95+
RUNTIME_CHECK(connection_profile_infos.size() == 2, connection_profile_infos.size());
96+
RUNTIME_CHECK(current_seg_task->extra_remote_info.has_value());
97+
if (current_seg_task->extra_remote_info->connection_profile_info.type == inter_type)
98+
connection_profile_infos[INTER_ZONE_INDEX].merge(
99+
current_seg_task->extra_remote_info->connection_profile_info);
100+
else if (current_seg_task->extra_remote_info->connection_profile_info.type == inner_type)
101+
connection_profile_infos[INNER_ZONE_INDEX].merge(
102+
current_seg_task->extra_remote_info->connection_profile_info);
103+
else
104+
throw Exception("unexpected connection type");
105+
92106
// Current stream is drained, try read from next stream.
93107
current_seg_task = nullptr;
94108
continue;

dbms/src/Storages/DeltaMerge/Remote/RNSegmentInputStream.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class RNSegmentInputStream : public IProfilingBlockInputStream
3434

3535
Block getHeader() const override { return action.getHeader(); }
3636

37+
std::vector<ConnectionProfileInfo> getConnectionProfileInfos() const { return connection_profile_infos; }
38+
3739
protected:
3840
Block readImpl() override
3941
{
@@ -56,7 +58,11 @@ class RNSegmentInputStream : public IProfilingBlockInputStream
5658
: log(Logger::get(options.debug_tag))
5759
, workers(options.workers)
5860
, action(options.columns_to_read, options.extra_table_id_index)
59-
{}
61+
{
62+
connection_profile_infos.resize(2);
63+
connection_profile_infos[INTER_ZONE_INDEX] = ConnectionProfileInfo::createForInterZone();
64+
connection_profile_infos[INNER_ZONE_INDEX] = ConnectionProfileInfo::createForInnerZone();
65+
}
6066

6167
static BlockInputStreamPtr create(const Options & options)
6268
{
@@ -74,6 +80,10 @@ class RNSegmentInputStream : public IProfilingBlockInputStream
7480

7581
double duration_wait_ready_task_sec = 0;
7682
double duration_read_sec = 0;
83+
84+
static constexpr size_t INTER_ZONE_INDEX = 0;
85+
static constexpr size_t INNER_ZONE_INDEX = 1;
86+
std::vector<ConnectionProfileInfo> connection_profile_infos;
7787
};
7888

7989
} // namespace DB::DM::Remote

dbms/src/Storages/DeltaMerge/Remote/RNSegmentSourceOp.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,21 @@ OperatorStatus RNSegmentSourceOp::executeIOImpl()
137137
}
138138
else
139139
{
140+
static constexpr auto inter_type = ConnectionProfileInfo::ConnectionType::InterZoneRemote;
141+
static constexpr auto inner_type = ConnectionProfileInfo::ConnectionType::InnerZoneRemote;
142+
143+
auto & connection_profile_infos = io_profile_info->connection_profile_infos;
144+
RUNTIME_CHECK(connection_profile_infos.size() == 2, connection_profile_infos.size());
145+
RUNTIME_CHECK(current_seg_task->extra_remote_info.has_value());
146+
if (current_seg_task->extra_remote_info->connection_profile_info.type == inter_type)
147+
connection_profile_infos[INTER_ZONE_INDEX].merge(
148+
current_seg_task->extra_remote_info->connection_profile_info);
149+
else if (current_seg_task->extra_remote_info->connection_profile_info.type == inner_type)
150+
connection_profile_infos[INNER_ZONE_INDEX].merge(
151+
current_seg_task->extra_remote_info->connection_profile_info);
152+
else
153+
throw Exception("unexpected connection type");
154+
140155
// Current stream is drained, try to get next ready task.
141156
current_seg_task = nullptr;
142157
return startGettingNextReadyTask();

0 commit comments

Comments
 (0)