6
6
#include < ydb/library/actors/core/hfunc.h>
7
7
#include < ydb/library/actors/core/interconnect.h>
8
8
#include < ydb/library/yql/dq/actors/common/retry_queue.h>
9
+ #include < ydb/library/yql/providers/dq/counters/counters.h>
9
10
10
11
#include < ydb/core/fq/libs/actors/logging/log.h>
11
12
#include < ydb/core/fq/libs/events/events.h>
@@ -48,16 +49,22 @@ struct TEvPrivate {
48
49
enum EEv : ui32 {
49
50
EvBegin = EventSpaceBegin (NActors::TEvents::ES_PRIVATE),
50
51
EvCoordinatorPing = EvBegin + 20 ,
51
- EvPrintState ,
52
+ EvUpdateMetrics ,
52
53
EvEnd
53
54
};
54
55
55
56
static_assert (EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE), " expect EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE)" );
56
57
struct TEvCoordinatorPing : NActors::TEventLocal<TEvCoordinatorPing, EvCoordinatorPing> {};
57
- struct TEvPrintState : public NActors ::TEventLocal<TEvPrintState, EvPrintState > {};
58
+ struct TEvUpdateMetrics : public NActors ::TEventLocal<TEvUpdateMetrics, EvUpdateMetrics > {};
58
59
};
59
60
60
- ui64 PrintStatePeriodSec = 60 ;
61
+ struct TQueryStat {
62
+ const TString QueryId;
63
+ NYql::TCounters::TEntry UnreadRows;
64
+ NYql::TCounters::TEntry UnreadBytes;
65
+ };
66
+
67
+ ui64 UpdateMetricsPeriodSec = 60 ;
61
68
62
69
class TRowDispatcher : public TActorBootstrapped <TRowDispatcher> {
63
70
@@ -84,19 +91,19 @@ class TRowDispatcher : public TActorBootstrapped<TRowDispatcher> {
84
91
struct TopicSessionKey {
85
92
TString Endpoint;
86
93
TString Database;
87
- TString TopicName ;
94
+ TString TopicPath ;
88
95
ui64 PartitionId;
89
96
90
97
size_t Hash () const noexcept {
91
98
ui64 hash = std::hash<TString>()(Endpoint);
92
99
hash = CombineHashes<ui64>(hash, std::hash<TString>()(Database));
93
- hash = CombineHashes<ui64>(hash, std::hash<TString>()(TopicName ));
100
+ hash = CombineHashes<ui64>(hash, std::hash<TString>()(TopicPath ));
94
101
hash = CombineHashes<ui64>(hash, std::hash<ui64>()(PartitionId));
95
102
return hash;
96
103
}
97
104
bool operator ==(const TopicSessionKey& other) const {
98
105
return Endpoint == other.Endpoint && Database == other.Database
99
- && TopicName == other.TopicName && PartitionId == other.PartitionId ;
106
+ && TopicPath == other.TopicPath && PartitionId == other.PartitionId ;
100
107
}
101
108
};
102
109
@@ -154,10 +161,12 @@ class TRowDispatcher : public TActorBootstrapped<TRowDispatcher> {
154
161
TActorId TopicSessionId;
155
162
const TString QueryId;
156
163
ConsumerCounters Counters;
164
+ TopicSessionClientStatistic Stat;
157
165
};
158
166
159
167
struct SessionInfo {
160
168
TMap<TActorId, TAtomicSharedPtr<ConsumerInfo>> Consumers; // key - ReadActor actor id
169
+ TopicSessionCommonStatistic Stat;
161
170
};
162
171
163
172
struct TopicSessionInfo {
@@ -198,15 +207,16 @@ class TRowDispatcher : public TActorBootstrapped<TRowDispatcher> {
198
207
void Handle (NFq::TEvRowDispatcher::TEvMessageBatch::TPtr& ev);
199
208
void Handle (NFq::TEvRowDispatcher::TEvSessionError::TPtr& ev);
200
209
void Handle (NFq::TEvRowDispatcher::TEvStatus::TPtr& ev);
210
+ void Handle (NFq::TEvRowDispatcher::TEvSessionStatistic::TPtr& ev);
201
211
202
212
void Handle (NActors::TEvents::TEvPing::TPtr& ev);
203
213
void Handle (const NYql::NDq::TEvRetryQueuePrivate::TEvRetry::TPtr&);
204
214
void Handle (const NYql::NDq::TEvRetryQueuePrivate::TEvPing::TPtr&);
205
215
void Handle (const NYql::NDq::TEvRetryQueuePrivate::TEvSessionClosed::TPtr&);
206
- void Handle (NFq::TEvPrivate::TEvPrintState ::TPtr&);
216
+ void Handle (NFq::TEvPrivate::TEvUpdateMetrics ::TPtr&);
207
217
208
218
void DeleteConsumer (const ConsumerSessionKey& key);
209
- void PrintInternalState ();
219
+ void UpdateMetrics ();
210
220
211
221
STRICT_STFUNC (
212
222
StateFunc, {
@@ -223,12 +233,13 @@ class TRowDispatcher : public TActorBootstrapped<TRowDispatcher> {
223
233
hFunc (NFq::TEvRowDispatcher::TEvStopSession, Handle);
224
234
hFunc (NFq::TEvRowDispatcher::TEvSessionError, Handle);
225
235
hFunc (NFq::TEvRowDispatcher::TEvStatus, Handle);
236
+ hFunc (NFq::TEvRowDispatcher::TEvSessionStatistic, Handle);
226
237
hFunc (NYql::NDq::TEvRetryQueuePrivate::TEvRetry, Handle);
227
238
hFunc (NYql::NDq::TEvRetryQueuePrivate::TEvPing, Handle);
228
239
hFunc (NYql::NDq::TEvRetryQueuePrivate::TEvSessionClosed, Handle);
229
240
hFunc (NActors::TEvents::TEvPing, Handle);
230
241
hFunc (NFq::TEvRowDispatcher::TEvNewDataArrived, Handle);
231
- hFunc (NFq::TEvPrivate::TEvPrintState , Handle);
242
+ hFunc (NFq::TEvPrivate::TEvUpdateMetrics , Handle);
232
243
})
233
244
};
234
245
@@ -261,7 +272,7 @@ void TRowDispatcher::Bootstrap() {
261
272
auto coordinatorId = Register (NewCoordinator (SelfId (), config, YqSharedResources, Tenant, Counters).release ());
262
273
Register (NewLeaderElection (SelfId (), coordinatorId, config, CredentialsProviderFactory, YqSharedResources, Tenant, Counters).release ());
263
274
Schedule (TDuration::Seconds (CoordinatorPingPeriodSec), new TEvPrivate::TEvCoordinatorPing ());
264
- Schedule (TDuration::Seconds (PrintStatePeriodSec ), new NFq::TEvPrivate::TEvPrintState ());
275
+ Schedule (TDuration::Seconds (UpdateMetricsPeriodSec ), new NFq::TEvPrivate::TEvUpdateMetrics ());
265
276
}
266
277
267
278
void TRowDispatcher::Handle (NFq::TEvRowDispatcher::TEvCoordinatorChanged::TPtr& ev) {
@@ -320,31 +331,42 @@ void TRowDispatcher::Handle(NFq::TEvRowDispatcher::TEvCoordinatorChangesSubscrib
320
331
Send (ev->Sender , new NFq::TEvRowDispatcher::TEvCoordinatorChanged (*CoordinatorActorId), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession);
321
332
}
322
333
323
- void TRowDispatcher::PrintInternalState () {
334
+ void TRowDispatcher::UpdateMetrics () {
324
335
if (Consumers.empty ()) {
325
336
return ;
326
337
}
338
+ TMap<TString, TQueryStat> queryStats;
327
339
TStringStream str;
328
- str << " Consumers:\n " ;
329
- for (auto & [key, consumerInfo] : Consumers) {
330
- str << " query id " << consumerInfo->QueryId << " , partId: " << key.PartitionId << " , read actor id: " << key.ReadActorId
331
- << " , queueId " << consumerInfo->EventQueueId << " , get next " << consumerInfo->Counters .GetNextBatch
332
- << " , data arrived " << consumerInfo->Counters .NewDataArrived << " , message batch " << consumerInfo->Counters .MessageBatch << " \n " ;
333
- str << " " ;
334
- consumerInfo->EventsQueue .PrintInternalState (str);
335
- }
336
340
337
- str << " \n Sessions:\n " ;
338
- for (auto & [key, sessionInfo1] : TopicSessions) {
339
- str << " " << key.Endpoint << " / " << key.Database << " / " << key.TopicName << " , id: " << key.PartitionId << " \n " ;
340
- for (auto & [actorId, sessionInfo2] : sessionInfo1.Sessions ) {
341
- str << " session id: " << actorId << " \n " ;
342
- for (auto & [actorId2, consumer] : sessionInfo2.Consumers ) {
343
- str << " read actor id: " << actorId2 << " \n " ;
341
+ str << " Statistics:\n " ;
342
+ for (auto & [key, sessionsInfo] : TopicSessions) {
343
+ str << " " << key.Endpoint << " / " << key.Database << " / " << key.TopicPath << " / " << key.PartitionId ;
344
+ for (auto & [actorId, sessionInfo] : sessionsInfo.Sessions ) {
345
+ str << " / " << actorId << " \n " ;
346
+ str << " unread bytes " << sessionInfo.Stat .UnreadBytes << " \n " ;
347
+ for (auto & [readActorId, consumer] : sessionInfo.Consumers ) {
348
+ auto & stat = queryStats[consumer->QueryId ];
349
+ stat.UnreadRows .Add (NYql::TCounters::TEntry (consumer->Stat .UnreadRows ));
350
+ stat.UnreadBytes .Add (NYql::TCounters::TEntry (consumer->Stat .UnreadBytes ));
351
+ str << " " << consumer->QueryId << " " << readActorId << " unread rows "
352
+ << consumer->Stat .UnreadRows << " unread bytes " << consumer->Stat .UnreadBytes << " offset " << consumer->Stat .Offset
353
+ << " get " << consumer->Counters .GetNextBatch
354
+ << " arrived " << consumer->Counters .NewDataArrived << " batch " << consumer->Counters .MessageBatch << " " ;
355
+ str << " retry queue: " ;
356
+ consumer->EventsQueue .PrintInternalState (str);
344
357
}
345
358
}
346
359
}
347
360
LOG_ROW_DISPATCHER_DEBUG (str.Str ());
361
+
362
+ for (const auto & [queryId, stat] : queryStats) {
363
+ LOG_ROW_DISPATCHER_DEBUG (" UnreadBytes " << queryId << " " << stat.UnreadBytes .Max );
364
+ auto queryGroup = Metrics.Counters ->GetSubgroup (" queryId" , queryId);
365
+ queryGroup->GetCounter (" MaxUnreadRows" )->Set (stat.UnreadRows .Max );
366
+ queryGroup->GetCounter (" AvgUnreadRows" )->Set (stat.UnreadRows .Avg );
367
+ queryGroup->GetCounter (" MaxUnreadBytes" )->Set (stat.UnreadBytes .Max );
368
+ queryGroup->GetCounter (" AvgUnreadBytes" )->Set (stat.UnreadBytes .Avg );
369
+ }
348
370
}
349
371
350
372
void TRowDispatcher::Handle (NFq::TEvRowDispatcher::TEvStartSession::TPtr& ev) {
@@ -383,6 +405,8 @@ void TRowDispatcher::Handle(NFq::TEvRowDispatcher::TEvStartSession::TPtr& ev) {
383
405
LOG_ROW_DISPATCHER_DEBUG (" Create new session " << readOffset);
384
406
sessionActorId = ActorFactory->RegisterTopicSession (
385
407
source.GetTopicPath (),
408
+ source.GetEndpoint (),
409
+ source.GetDatabase (),
386
410
Config,
387
411
SelfId (),
388
412
ev->Get ()->Record .GetPartitionId (),
@@ -407,7 +431,7 @@ void TRowDispatcher::Handle(NFq::TEvRowDispatcher::TEvStartSession::TPtr& ev) {
407
431
408
432
Forward (ev, sessionActorId);
409
433
Metrics.ClientsCount ->Set (Consumers.size ());
410
- PrintInternalState ();
434
+ UpdateMetrics ();
411
435
}
412
436
413
437
void TRowDispatcher::Handle (NFq::TEvRowDispatcher::TEvGetNextBatch::TPtr& ev) {
@@ -490,7 +514,7 @@ void TRowDispatcher::DeleteConsumer(const ConsumerSessionKey& key) {
490
514
ConsumersByEventQueueId.erase (consumerIt->second ->EventQueueId );
491
515
Consumers.erase (consumerIt);
492
516
Metrics.ClientsCount ->Set (Consumers.size ());
493
- PrintInternalState ();
517
+ UpdateMetrics ();
494
518
}
495
519
496
520
void TRowDispatcher::Handle (const NYql::NDq::TEvRetryQueuePrivate::TEvSessionClosed::TPtr& ev) {
@@ -577,9 +601,37 @@ void TRowDispatcher::Handle(NFq::TEvRowDispatcher::TEvStatus::TPtr& ev) {
577
601
it->second ->EventsQueue .Send (ev.Release ()->Release ().Release ());
578
602
}
579
603
580
- void TRowDispatcher::Handle (NFq::TEvPrivate::TEvPrintState::TPtr&) {
581
- Schedule (TDuration::Seconds (PrintStatePeriodSec), new NFq::TEvPrivate::TEvPrintState ());
582
- PrintInternalState ();
604
+ void TRowDispatcher::Handle (NFq::TEvPrivate::TEvUpdateMetrics::TPtr&) {
605
+ Schedule (TDuration::Seconds (UpdateMetricsPeriodSec), new NFq::TEvPrivate::TEvUpdateMetrics ());
606
+ UpdateMetrics ();
607
+ }
608
+
609
+ void TRowDispatcher::Handle (NFq::TEvRowDispatcher::TEvSessionStatistic::TPtr& ev) {
610
+ LOG_ROW_DISPATCHER_TRACE (" TEvSessionStatistic from " << ev->Sender );
611
+ const auto & key = ev->Get ()->Stat .SessionKey ;
612
+ TopicSessionKey sessionKey{key.Endpoint , key.Database , key.TopicPath , key.PartitionId };
613
+
614
+ auto sessionsIt = TopicSessions.find (sessionKey);
615
+ if (sessionsIt == TopicSessions.end ()) {
616
+ return ;
617
+ }
618
+ auto & sessionsInfo = sessionsIt->second ;
619
+ auto sessionIt = sessionsInfo.Sessions .find (ev->Sender );
620
+ if (sessionIt == sessionsInfo.Sessions .end ()) {
621
+ return ;
622
+ }
623
+
624
+ auto & sessionInfo = sessionIt->second ;
625
+ sessionInfo.Stat = ev->Get ()->Stat .Common ;
626
+
627
+ for (const auto & clientStat : ev->Get ()->Stat .Clients ) {
628
+ auto it = sessionInfo.Consumers .find (clientStat.ReadActorId );
629
+ if (it == sessionInfo.Consumers .end ()) {
630
+ continue ;
631
+ }
632
+ auto consumerInfoPtr = it->second ;
633
+ consumerInfoPtr->Stat = clientStat;
634
+ }
583
635
}
584
636
585
637
} // namespace
0 commit comments