Skip to content

Commit 92e8dac

Browse files
SeaRisegengliqi
andauthored
Pipeline: use notify instead of polling for ExchangeReceiver (#9073)
ref #8869 Signed-off-by: gengliqi <gengliqiii@gmail.com> Co-authored-by: gengliqi <gengliqiii@gmail.com> Co-authored-by: Liqi Geng <gengliqiii@gmail.com>
1 parent ea1105d commit 92e8dac

20 files changed

Lines changed: 154 additions & 113 deletions

dbms/src/Flash/Coprocessor/DAGContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,8 @@ class DAGContext
351351
UInt64 getConnectionID() const { return connection_id; }
352352
const String & getConnectionAlias() const { return connection_alias; }
353353

354+
MPPReceiverSetPtr getMPPReceiverSet() const { return mpp_receiver_set; }
355+
354356
public:
355357
DAGRequest dag_request;
356358
/// Some existing code inherited from Clickhouse assume that each query must have a valid query string and query ast,
@@ -443,6 +445,7 @@ class DAGContext
443445
/// warning_count is the actual warning count during the entire execution
444446
std::atomic<UInt64> warning_count;
445447

448+
// `mpp_receiver_set` is always set by `MPPTask` and is used later.
446449
MPPReceiverSetPtr mpp_receiver_set;
447450
std::vector<CoprocessorReaderPtr> coprocessor_readers;
448451
/// vector of SubqueriesForSets(such as join build subquery).

dbms/src/Flash/Executor/PipelineExecutorContext.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <Flash/Coprocessor/DAGContext.h>
1616
#include <Flash/Executor/PipelineExecutorContext.h>
1717
#include <Flash/Executor/ResultQueue.h>
18+
#include <Flash/Mpp/MPPReceiverSet.h>
1819
#include <Flash/Mpp/MPPTunnelSet.h>
1920
#include <Flash/Mpp/Utils.h>
2021
#include <Flash/Pipeline/Schedule/TaskScheduler.h>
@@ -180,9 +181,12 @@ void PipelineExecutorContext::cancel()
180181
cancelOneTimeFutures();
181182
if (likely(dag_context))
182183
{
183-
// Cancel the tunnel_set here to prevent pipeline tasks waiting in the WAIT_FOR_NOTIFY state from never being notified.
184+
// Cancel the tunnel_set and mpp_receiver_set here to prevent
185+
// pipeline tasks waiting in the WAIT_FOR_NOTIFY state from never being notified.
184186
if (dag_context->tunnel_set)
185187
dag_context->tunnel_set->close(getTrimmedErrMsg(), false);
188+
if (auto mpp_receiver_set = dag_context->getMPPReceiverSet(); mpp_receiver_set)
189+
mpp_receiver_set->cancel();
186190
}
187191
cancelResultQueueIfNeed();
188192
if likely (TaskScheduler::instance && !query_id.empty())

dbms/src/Flash/Mpp/LocalRequestHandler.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ struct LocalRequestHandler
4343
bool isWritable() const { return msg_queue->isWritable(); }
4444
void notifyNextPipelineWriter() const { return msg_queue->notifyNextPipelineWriter(); }
4545

46-
void registerPipeReadTask(TaskPtr && task) const { msg_queue->registerPipeReadTask(std::move(task)); }
4746
void registerPipeWriteTask(TaskPtr && task) const { msg_queue->registerPipeWriteTask(std::move(task)); }
4847

4948
void writeDone(bool meet_error, const String & local_err_msg) const

dbms/src/Flash/Mpp/MPPTunnel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ WaitResult MPPTunnel::waitForWritable() const
403403
RUNTIME_CHECK_MSG(tunnel_sender != nullptr, "write to tunnel {} which is already closed.", tunnel_id);
404404
if (!tunnel_sender->isWritable())
405405
{
406-
setNotifyFuture(tunnel_sender);
406+
setNotifyFuture(tunnel_sender.get());
407407
return WaitResult::WaitForNotify;
408408
}
409409
return WaitResult::Ready;

dbms/src/Flash/Mpp/ReceivedMessage.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace DB
1818
{
1919
const std::vector<const String *> & ReceivedMessage::getChunks(size_t stream_id) const
2020
{
21-
if (remaining_consumers != nullptr)
21+
if (fine_grained_consumer_size > 0)
2222
return fine_grained_chunks[stream_id];
2323
else
2424
return chunks;
@@ -31,17 +31,18 @@ ReceivedMessage::ReceivedMessage(
3131
const mpp::Error * error_ptr_,
3232
const String * resp_ptr_,
3333
std::vector<const String *> && chunks_,
34-
size_t fine_grained_consumer_size)
34+
size_t fine_grained_consumer_size_)
3535
: source_index(source_index_)
3636
, req_info(req_info_)
3737
, packet(packet_)
3838
, error_ptr(error_ptr_)
3939
, resp_ptr(resp_ptr_)
4040
, chunks(chunks_)
41+
, remaining_consumers(fine_grained_consumer_size_)
42+
, fine_grained_consumer_size(fine_grained_consumer_size_)
4143
{
4244
if (fine_grained_consumer_size > 0)
4345
{
44-
remaining_consumers = std::make_shared<std::atomic<size_t>>(fine_grained_consumer_size);
4546
fine_grained_chunks.resize(fine_grained_consumer_size);
4647
if (packet->packet.chunks_size() > 0)
4748
{

dbms/src/Flash/Mpp/ReceivedMessage.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ class ReceivedMessage
3333
std::vector<const String *> chunks;
3434
/// used for fine grained shuffle, remaining_consumers will be nullptr for non fine grained shuffle
3535
std::vector<std::vector<const String *>> fine_grained_chunks;
36-
std::shared_ptr<std::atomic<size_t>> remaining_consumers;
36+
std::atomic<size_t> remaining_consumers;
37+
size_t fine_grained_consumer_size;
3738

3839
public:
3940
// Constructor that move chunks.
@@ -50,7 +51,7 @@ class ReceivedMessage
5051
const String & getReqInfo() const { return req_info; }
5152
const mpp::Error * getErrorPtr() const { return error_ptr; }
5253
const String * getRespPtr(size_t stream_id) const { return stream_id == 0 ? resp_ptr : nullptr; }
53-
std::shared_ptr<std::atomic<size_t>> & getRemainingConsumers() { return remaining_consumers; }
54+
std::atomic<size_t> & getRemainingConsumers() { return remaining_consumers; }
5455
const std::vector<const String *> & getChunks(size_t stream_id) const;
5556
const mpp::MPPDataPacket & getPacket() const { return packet->packet; }
5657
bool containUsefulMessage() const;

dbms/src/Flash/Mpp/ReceivedMessageQueue.cpp

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,7 @@ ReceivedMessageQueue::ReceivedMessageQueue(
114114
assert(fine_grained_channel_size > 0);
115115
msg_channels_for_fine_grained_shuffle.reserve(fine_grained_channel_size);
116116
for (size_t i = 0; i < fine_grained_channel_size; ++i)
117-
/// these are unbounded queues
118-
msg_channels_for_fine_grained_shuffle.push_back(
119-
std::make_shared<LooseBoundedMPMCQueue<ReceivedMessagePtr>>(std::numeric_limits<size_t>::max()));
117+
msg_channels_for_fine_grained_shuffle.emplace_back(std::make_unique<MSGUnboundedQueue>());
120118
}
121119
}
122120

@@ -133,7 +131,7 @@ MPMCQueueResult ReceivedMessageQueue::pop(size_t stream_id, ReceivedMessagePtr &
133131

134132
if (res == MPMCQueueResult::OK)
135133
{
136-
if (recv_msg->getRemainingConsumers()->fetch_sub(1) == 1)
134+
if (recv_msg->getRemainingConsumers().fetch_sub(1) == 1)
137135
{
138136
#ifndef NDEBUG
139137
ReceivedMessagePtr original_msg;
@@ -145,12 +143,21 @@ MPMCQueueResult ReceivedMessageQueue::pop(size_t stream_id, ReceivedMessagePtr &
145143
"The result of 'grpc_recv_queue->tryPop' is definitely not EMPTY.");
146144
if likely (original_msg != nullptr)
147145
RUNTIME_CHECK_MSG(
148-
*original_msg->getRemainingConsumers() == 0,
146+
original_msg->getRemainingConsumers() == 0,
149147
"Fine grained receiver pop a message that is not full consumed, remaining consumer: {}",
150-
*original_msg->getRemainingConsumers());
148+
original_msg->getRemainingConsumers());
151149
#else
152150
grpc_recv_queue.tryDequeue();
153151
#endif
152+
ExchangeReceiverMetric::subDataSizeMetric(*data_size_in_queue, recv_msg->getPacket().ByteSizeLong());
153+
}
154+
}
155+
else
156+
{
157+
if constexpr (!need_wait)
158+
{
159+
if (res == MPMCQueueResult::EMPTY)
160+
setNotifyFuture(msg_channels_for_fine_grained_shuffle[stream_id].get());
154161
}
155162
}
156163
}
@@ -160,13 +167,20 @@ MPMCQueueResult ReceivedMessageQueue::pop(size_t stream_id, ReceivedMessagePtr &
160167
res = grpc_recv_queue.pop(recv_msg);
161168
else
162169
res = grpc_recv_queue.tryPop(recv_msg);
163-
}
164170

165-
if (res == MPMCQueueResult::OK)
166-
{
167-
ExchangeReceiverMetric::subDataSizeMetric(*data_size_in_queue, recv_msg->getPacket().ByteSizeLong());
171+
if (res == MPMCQueueResult::OK)
172+
{
173+
ExchangeReceiverMetric::subDataSizeMetric(*data_size_in_queue, recv_msg->getPacket().ByteSizeLong());
174+
}
175+
else
176+
{
177+
if constexpr (!need_wait)
178+
{
179+
if (res == MPMCQueueResult::EMPTY)
180+
setNotifyFuture(&grpc_recv_queue);
181+
}
182+
}
168183
}
169-
170184
return res;
171185
}
172186

dbms/src/Flash/Mpp/ReceivedMessageQueue.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
#include <Common/TiFlashMetrics.h>
2222
#include <Flash/Mpp/ReceivedMessage.h>
2323
#include <Flash/Mpp/TrackedMppDataPacket.h>
24+
#include <Flash/Pipeline/Schedule/Tasks/NotifyFuture.h>
2425

2526
#include <memory>
27+
#include <utility>
2628

2729
namespace DB
2830
{
@@ -55,6 +57,31 @@ enum class ReceiverMode
5557
Async
5658
};
5759

60+
class GRPCNotifyRecvQueue final
61+
: public NotifyFuture
62+
, public GRPCRecvQueue<ReceivedMessagePtr>
63+
{
64+
public:
65+
template <typename... Args>
66+
explicit GRPCNotifyRecvQueue(const LoggerPtr & log_, Args &&... args)
67+
: GRPCRecvQueue<ReceivedMessagePtr>(log_, std::forward<Args>(args)...)
68+
{}
69+
70+
void registerTask(TaskPtr && task) override { registerPipeReadTask(std::move(task)); }
71+
};
72+
73+
class MSGUnboundedQueue final
74+
: public NotifyFuture
75+
, public LooseBoundedMPMCQueue<ReceivedMessagePtr>
76+
{
77+
public:
78+
MSGUnboundedQueue()
79+
: LooseBoundedMPMCQueue<ReceivedMessagePtr>(std::numeric_limits<size_t>::max())
80+
{}
81+
82+
void registerTask(TaskPtr && task) override { registerPipeReadTask(std::move(task)); }
83+
};
84+
5885
class ReceivedMessageQueue
5986
{
6087
public:
@@ -100,7 +127,6 @@ class ReceivedMessageQueue
100127
bool isWritable() const { return grpc_recv_queue.isWritable(); }
101128
void notifyNextPipelineWriter() { grpc_recv_queue.notifyNextPipelineWriter(); }
102129

103-
void registerPipeReadTask(TaskPtr && task) { grpc_recv_queue.registerPipeReadTask(std::move(task)); }
104130
void registerPipeWriteTask(TaskPtr && task) { grpc_recv_queue.registerPipeWriteTask(std::move(task)); }
105131

106132
#ifndef DBMS_PUBLIC_GTEST
@@ -119,8 +145,8 @@ class ReceivedMessageQueue
119145
/// write: the writer first write the msg to msg_channel/grpc_recv_queue, if write success, then write msg to msg_channels_for_fine_grained_shuffle
120146
/// read: the reader read msg from msg_channels_for_fine_grained_shuffle, and reduce the `remaining_consumers` in msg, if `remaining_consumers` is 0, then
121147
/// remove the msg from msg_channel/grpc_recv_queue
122-
std::vector<std::shared_ptr<LooseBoundedMPMCQueue<ReceivedMessagePtr>>> msg_channels_for_fine_grained_shuffle;
123-
GRPCRecvQueue<ReceivedMessagePtr> grpc_recv_queue;
148+
std::vector<std::unique_ptr<MSGUnboundedQueue>> msg_channels_for_fine_grained_shuffle;
149+
GRPCNotifyRecvQueue grpc_recv_queue;
124150
};
125151

126152
} // namespace DB

dbms/src/Flash/Pipeline/Schedule/Tasks/Impls/StreamRestoreTask.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ ExecTaskStatus StreamRestoreTask::tryFlush()
4848
t_block.clear();
4949
return ExecTaskStatus::IO_IN;
5050
case MPMCQueueResult::FULL:
51-
setNotifyFuture(sink);
51+
setNotifyFuture(sink.get());
5252
return ExecTaskStatus::WAIT_FOR_NOTIFY;
5353
case MPMCQueueResult::CANCELLED:
5454
return ExecTaskStatus::CANCELLED;

dbms/src/Flash/Pipeline/Schedule/Tasks/NotifyFuture.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@
1616

1717
namespace DB
1818
{
19-
thread_local NotifyFuturePtr current_notify_future = nullptr;
19+
thread_local NotifyFuture * current_notify_future = nullptr;
2020

21-
void setNotifyFuture(NotifyFuturePtr new_future)
21+
void setNotifyFuture(NotifyFuture * new_future)
2222
{
2323
assert(current_notify_future == nullptr);
2424
current_notify_future = std::move(new_future);
2525
}
2626

2727
void clearNotifyFuture()
2828
{
29-
current_notify_future.reset();
29+
current_notify_future = nullptr;
3030
}
3131

3232
void registerTaskToFuture(TaskPtr && task)
3333
{
3434
assert(current_notify_future != nullptr);
3535
current_notify_future->registerTask(std::move(task));
36-
current_notify_future.reset();
36+
current_notify_future = nullptr;
3737
}
3838
} // namespace DB

0 commit comments

Comments
 (0)