Skip to content

Commit 3338d2f

Browse files
authored
Merge to Q 24 3 (#9807)
1 parent 719f33d commit 3338d2f

35 files changed

+1265
-126
lines changed

ydb/core/kqp/executer_actor/kqp_data_executer.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,7 @@ class TKqpDataExecuter : public TKqpExecuterBase<TKqpDataExecuter, EExecType::Da
18611861
size_t sourceScanPartitionsCount = 0;
18621862
for (ui32 txIdx = 0; txIdx < Request.Transactions.size(); ++txIdx) {
18631863
auto& tx = Request.Transactions[txIdx];
1864+
auto scheduledTaskCount = ScheduleByCost(tx, ResourceSnapshot);
18641865
for (ui32 stageIdx = 0; stageIdx < tx.Body->StagesSize(); ++stageIdx) {
18651866
auto& stage = tx.Body->GetStages(stageIdx);
18661867
auto& stageInfo = TasksGraph.GetStageInfo(TStageId(txIdx, stageIdx));
@@ -1908,8 +1909,10 @@ class TKqpDataExecuter : public TKqpExecuterBase<TKqpDataExecuter, EExecType::Da
19081909
UnknownAffectedShardCount = true;
19091910
}
19101911
break;
1911-
case NKqpProto::TKqpSource::kExternalSource:
1912-
BuildReadTasksFromSource(stageInfo, ResourceSnapshot);
1912+
case NKqpProto::TKqpSource::kExternalSource: {
1913+
auto it = scheduledTaskCount.find(stageIdx);
1914+
BuildReadTasksFromSource(stageInfo, ResourceSnapshot, it != scheduledTaskCount.end() ? it->second.TaskCount : 0);
1915+
}
19131916
break;
19141917
default:
19151918
YQL_ENSURE(false, "unknown source type");

ydb/core/kqp/executer_actor/kqp_executer_impl.h

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ struct TShardRangesWithShardId {
8181
const TShardKeyRanges* Ranges;
8282
};
8383

84+
struct TStageScheduleInfo {
85+
double StageCost = 0.0;
86+
ui32 TaskCount = 0;
87+
};
8488

8589
TActorId ReportToRl(ui64 ru, const TString& database, const TString& userToken,
8690
const NKikimrKqp::TRlPath& path);
@@ -807,6 +811,40 @@ class TKqpExecuterBase : public TActorBootstrapped<TDerived> {
807811
}
808812
}
809813

814+
std::map<ui32, TStageScheduleInfo> ScheduleByCost(const IKqpGateway::TPhysicalTxData& tx, const TVector<NKikimrKqp::TKqpNodeResources>& resourceSnapshot) {
815+
std::map<ui32, TStageScheduleInfo> result;
816+
if (!resourceSnapshot.empty()) // can't schedule w/o node count
817+
{
818+
// collect costs and schedule stages with external sources only
819+
double totalCost = 0.0;
820+
for (ui32 stageIdx = 0; stageIdx < tx.Body->StagesSize(); ++stageIdx) {
821+
auto& stage = tx.Body->GetStages(stageIdx);
822+
if (stage.SourcesSize() > 0 && stage.GetSources(0).GetTypeCase() == NKqpProto::TKqpSource::kExternalSource) {
823+
if (stage.GetStageCost() > 0.0 && stage.GetTaskCount() == 0) {
824+
totalCost += stage.GetStageCost();
825+
result.emplace(stageIdx, TStageScheduleInfo{.StageCost = stage.GetStageCost()});
826+
}
827+
}
828+
}
829+
// assign task counts
830+
if (!result.empty()) {
831+
// allow use 2/3 of threads in single stage
832+
ui32 maxStageTaskCount = (TStagePredictor::GetUsableThreads() * 2 + 2) / 3;
833+
// total limit per mode is x2
834+
ui32 maxTotalTaskCount = maxStageTaskCount * 2;
835+
for (auto& [_, stageInfo] : result) {
836+
// schedule tasks evenly between nodes
837+
stageInfo.TaskCount =
838+
std::max<ui32>(
839+
std::min(static_cast<ui32>(maxTotalTaskCount * stageInfo.StageCost / totalCost), maxStageTaskCount)
840+
, 1
841+
) * resourceSnapshot.size();
842+
}
843+
}
844+
}
845+
return result;
846+
}
847+
810848
void BuildSysViewScanTasks(TStageInfo& stageInfo) {
811849
Y_DEBUG_ABORT_UNLESS(stageInfo.Meta.IsSysView());
812850

@@ -912,7 +950,7 @@ class TKqpExecuterBase : public TActorBootstrapped<TDerived> {
912950
}
913951
}
914952

915-
void BuildReadTasksFromSource(TStageInfo& stageInfo, const TVector<NKikimrKqp::TKqpNodeResources>& resourceSnapshot) {
953+
void BuildReadTasksFromSource(TStageInfo& stageInfo, const TVector<NKikimrKqp::TKqpNodeResources>& resourceSnapshot, ui32 scheduledTaskCount) {
916954
const auto& stage = stageInfo.Meta.GetStage(stageInfo.Id);
917955

918956
YQL_ENSURE(stage.GetSources(0).HasExternalSource());
@@ -923,7 +961,16 @@ class TKqpExecuterBase : public TActorBootstrapped<TDerived> {
923961

924962
ui32 taskCount = externalSource.GetPartitionedTaskParams().size();
925963

926-
if (!resourceSnapshot.empty()) {
964+
auto taskCountHint = stage.GetTaskCount();
965+
if (taskCountHint == 0) {
966+
taskCountHint = scheduledTaskCount;
967+
}
968+
969+
if (taskCountHint) {
970+
if (taskCount > taskCountHint) {
971+
taskCount = taskCountHint;
972+
}
973+
} else if (!resourceSnapshot.empty()) {
927974
ui32 maxTaskcount = resourceSnapshot.size() * 2;
928975
if (taskCount > maxTaskcount) {
929976
taskCount = maxTaskcount;
@@ -1302,7 +1349,11 @@ class TKqpExecuterBase : public TActorBootstrapped<TDerived> {
13021349
}
13031350

13041351
if (isShuffle) {
1305-
partitionsCount = std::max(partitionsCount, GetMaxTasksAggregation(stageInfo, inputTasks, nodesCount));
1352+
if (stage.GetTaskCount()) {
1353+
partitionsCount = stage.GetTaskCount();
1354+
} else {
1355+
partitionsCount = std::max(partitionsCount, GetMaxTasksAggregation(stageInfo, inputTasks, nodesCount));
1356+
}
13061357
}
13071358

13081359
for (ui32 i = 0; i < partitionsCount; ++i) {

0 commit comments

Comments
 (0)