Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
94f976ca
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
94f976ca
编写于
5月 23, 2022
作者:
D
dapan1121
提交者:
GitHub
5月 23, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #12860 from taosdata/feature/qnode
feat: support schedule based on level
上级
52385bac
8324a5a6
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
91 addition
and
25 deletion
+91
-25
source/libs/scheduler/inc/schedulerInt.h
source/libs/scheduler/inc/schedulerInt.h
+6
-4
source/libs/scheduler/src/schFlowCtrl.c
source/libs/scheduler/src/schFlowCtrl.c
+16
-17
source/libs/scheduler/src/scheduler.c
source/libs/scheduler/src/scheduler.c
+69
-4
未找到文件。
source/libs/scheduler/inc/schedulerInt.h
浏览文件 @
94f976ca
...
...
@@ -132,7 +132,7 @@ typedef struct SSchLevel {
int32_t
taskSucceed
;
int32_t
taskNum
;
int32_t
taskLaunchedNum
;
SHashObj
*
flowCtrl
;
// key is ep, element is SSchFlowControl
int32_t
taskDoneNum
;
SArray
*
subTasks
;
// Element is SQueryTask
}
SSchLevel
;
...
...
@@ -175,11 +175,13 @@ typedef struct SSchJob {
SArray
*
levels
;
// starting from 0. SArray<SSchLevel>
SNodeList
*
subPlans
;
// subplan pointer copied from DAG, no need to free it in scheduler
SArray
*
dataSrcTasks
;
// SArray<SQueryTask*>
int32_t
levelIdx
;
SEpSet
dataSrcEps
;
SHashObj
*
execTasks
;
// executing tasks, key:taskid, value:SQueryTask*
SHashObj
*
succTasks
;
// succeed tasks, key:taskid, value:SQueryTask*
SHashObj
*
failTasks
;
// failed tasks, key:taskid, value:SQueryTask*
SHashObj
*
flowCtrl
;
// key is ep, element is SSchFlowControl
SExplainCtx
*
explainCtx
;
int8_t
status
;
...
...
@@ -200,7 +202,7 @@ typedef struct SSchJob {
extern
SSchedulerMgmt
schMgmt
;
#define SCH_TASK_READY_
TO_L
UNCH(readyNum, task) ((readyNum) >= taosArrayGetSize((task)->children))
#define SCH_TASK_READY_
FOR_LA
UNCH(readyNum, task) ((readyNum) >= taosArrayGetSize((task)->children))
#define SCH_TASK_ID(_task) ((_task) ? (_task)->taskId : -1)
#define SCH_SET_TASK_LASTMSG_TYPE(_task, _type) do { if(_task) { atomic_store_32(&(_task)->lastMsgType, _type); } } while (0)
...
...
@@ -223,7 +225,7 @@ extern SSchedulerMgmt schMgmt;
#define SCH_SET_JOB_NEED_FLOW_CTRL(_job) (_job)->attr.needFlowCtrl = true
#define SCH_JOB_NEED_FLOW_CTRL(_job) ((_job)->attr.needFlowCtrl)
#define SCH_TASK_NEED_FLOW_CTRL(_job, _task) (SCH_IS_DATA_SRC_QRY_TASK(_task) && SCH_JOB_NEED_FLOW_CTRL(_job) && SCH_IS_LE
AF_TASK(_job, _task) && SCH_IS_LE
VEL_UNFINISHED((_task)->level))
#define SCH_TASK_NEED_FLOW_CTRL(_job, _task) (SCH_IS_DATA_SRC_QRY_TASK(_task) && SCH_JOB_NEED_FLOW_CTRL(_job) && SCH_IS_LEVEL_UNFINISHED((_task)->level))
#define SCH_SET_JOB_TYPE(_job, type) (_job)->attr.queryJob = ((type) != SUBPLAN_TYPE_MODIFY)
#define SCH_IS_QUERY_JOB(_job) ((_job)->attr.queryJob)
...
...
@@ -261,7 +263,7 @@ int32_t schLaunchTask(SSchJob *job, SSchTask *task);
int32_t
schBuildAndSendMsg
(
SSchJob
*
job
,
SSchTask
*
task
,
SQueryNodeAddr
*
addr
,
int32_t
msgType
);
SSchJob
*
schAcquireJob
(
int64_t
refId
);
int32_t
schReleaseJob
(
int64_t
refId
);
void
schFreeFlowCtrl
(
SSch
Level
*
pLevel
);
void
schFreeFlowCtrl
(
SSch
Job
*
pJob
);
int32_t
schCheckJobNeedFlowCtrl
(
SSchJob
*
pJob
,
SSchLevel
*
pLevel
);
int32_t
schDecTaskFlowQuota
(
SSchJob
*
pJob
,
SSchTask
*
pTask
);
int32_t
schCheckIncTaskFlowQuota
(
SSchJob
*
pJob
,
SSchTask
*
pTask
,
bool
*
enough
);
...
...
source/libs/scheduler/src/schFlowCtrl.c
浏览文件 @
94f976ca
...
...
@@ -19,13 +19,13 @@
#include "catalog.h"
#include "tref.h"
void
schFreeFlowCtrl
(
SSch
Level
*
pLevel
)
{
if
(
NULL
==
p
Level
->
flowCtrl
)
{
void
schFreeFlowCtrl
(
SSch
Job
*
pJob
)
{
if
(
NULL
==
p
Job
->
flowCtrl
)
{
return
;
}
SSchFlowControl
*
ctrl
=
NULL
;
void
*
pIter
=
taosHashIterate
(
p
Level
->
flowCtrl
,
NULL
);
void
*
pIter
=
taosHashIterate
(
p
Job
->
flowCtrl
,
NULL
);
while
(
pIter
)
{
ctrl
=
(
SSchFlowControl
*
)
pIter
;
...
...
@@ -33,11 +33,11 @@ void schFreeFlowCtrl(SSchLevel *pLevel) {
taosArrayDestroy
(
ctrl
->
taskList
);
}
pIter
=
taosHashIterate
(
p
Level
->
flowCtrl
,
pIter
);
pIter
=
taosHashIterate
(
p
Job
->
flowCtrl
,
pIter
);
}
taosHashCleanup
(
p
Level
->
flowCtrl
);
p
Level
->
flowCtrl
=
NULL
;
taosHashCleanup
(
p
Job
->
flowCtrl
);
p
Job
->
flowCtrl
=
NULL
;
}
int32_t
schCheckJobNeedFlowCtrl
(
SSchJob
*
pJob
,
SSchLevel
*
pLevel
)
{
...
...
@@ -47,9 +47,9 @@ int32_t schCheckJobNeedFlowCtrl(SSchJob *pJob, SSchLevel *pLevel) {
}
int32_t
sum
=
0
;
for
(
int32_t
i
=
0
;
i
<
pLevel
->
taskNum
;
++
i
)
{
SSchTask
*
pTask
=
taosArrayGet
(
pLevel
->
sub
Tasks
,
i
);
int32_t
taskNum
=
taosArrayGetSize
(
pJob
->
dataSrcTasks
);
for
(
int32_t
i
=
0
;
i
<
taskNum
;
++
i
)
{
SSchTask
*
pTask
=
*
(
SSchTask
**
)
taosArrayGet
(
pJob
->
dataSrc
Tasks
,
i
);
sum
+=
pTask
->
plan
->
execNodeStat
.
tableNum
;
}
...
...
@@ -59,9 +59,9 @@ int32_t schCheckJobNeedFlowCtrl(SSchJob *pJob, SSchLevel *pLevel) {
return
TSDB_CODE_SUCCESS
;
}
p
Level
->
flowCtrl
=
taosHashInit
(
pLevel
->
taskNum
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
false
,
HASH_ENTRY_LOCK
);
if
(
NULL
==
p
Level
->
flowCtrl
)
{
SCH_JOB_ELOG
(
"taosHashInit %d flowCtrl failed"
,
p
Level
->
taskNum
);
p
Job
->
flowCtrl
=
taosHashInit
(
pJob
->
taskNum
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
false
,
HASH_ENTRY_LOCK
);
if
(
NULL
==
p
Job
->
flowCtrl
)
{
SCH_JOB_ELOG
(
"taosHashInit %d flowCtrl failed"
,
p
Job
->
taskNum
);
SCH_ERR_RET
(
TSDB_CODE_QRY_OUT_OF_MEMORY
);
}
...
...
@@ -78,7 +78,7 @@ int32_t schDecTaskFlowQuota(SSchJob *pJob, SSchTask *pTask) {
int32_t
code
=
0
;
SEp
*
ep
=
SCH_GET_CUR_EP
(
&
pTask
->
plan
->
execNode
);
ctrl
=
(
SSchFlowControl
*
)
taosHashGet
(
p
Level
->
flowCtrl
,
ep
,
sizeof
(
SEp
));
ctrl
=
(
SSchFlowControl
*
)
taosHashGet
(
p
Job
->
flowCtrl
,
ep
,
sizeof
(
SEp
));
if
(
NULL
==
ctrl
)
{
SCH_TASK_ELOG
(
"taosHashGet node from flowCtrl failed, fqdn:%s, port:%d"
,
ep
->
fqdn
,
ep
->
port
);
SCH_ERR_RET
(
TSDB_CODE_SCH_INTERNAL_ERROR
);
...
...
@@ -110,11 +110,11 @@ int32_t schCheckIncTaskFlowQuota(SSchJob *pJob, SSchTask *pTask, bool *enough) {
SEp
*
ep
=
SCH_GET_CUR_EP
(
&
pTask
->
plan
->
execNode
);
do
{
ctrl
=
(
SSchFlowControl
*
)
taosHashGet
(
p
Level
->
flowCtrl
,
ep
,
sizeof
(
SEp
));
ctrl
=
(
SSchFlowControl
*
)
taosHashGet
(
p
Job
->
flowCtrl
,
ep
,
sizeof
(
SEp
));
if
(
NULL
==
ctrl
)
{
SSchFlowControl
nctrl
=
{.
tableNumSum
=
pTask
->
plan
->
execNodeStat
.
tableNum
,
.
execTaskNum
=
1
};
code
=
taosHashPut
(
p
Level
->
flowCtrl
,
ep
,
sizeof
(
SEp
),
&
nctrl
,
sizeof
(
nctrl
));
code
=
taosHashPut
(
p
Job
->
flowCtrl
,
ep
,
sizeof
(
SEp
),
&
nctrl
,
sizeof
(
nctrl
));
if
(
code
)
{
if
(
HASH_NODE_EXIST
(
code
))
{
continue
;
...
...
@@ -273,10 +273,9 @@ int32_t schLaunchTasksInFlowCtrlList(SSchJob *pJob, SSchTask *pTask) {
SCH_ERR_RET
(
schDecTaskFlowQuota
(
pJob
,
pTask
));
SSchLevel
*
pLevel
=
pTask
->
level
;
SEp
*
ep
=
SCH_GET_CUR_EP
(
&
pTask
->
plan
->
execNode
);
SSchFlowControl
*
ctrl
=
(
SSchFlowControl
*
)
taosHashGet
(
p
Level
->
flowCtrl
,
ep
,
sizeof
(
SEp
));
SSchFlowControl
*
ctrl
=
(
SSchFlowControl
*
)
taosHashGet
(
p
Job
->
flowCtrl
,
ep
,
sizeof
(
SEp
));
if
(
NULL
==
ctrl
)
{
SCH_TASK_ELOG
(
"taosHashGet node from flowCtrl failed, fqdn:%s, port:%d"
,
ep
->
fqdn
,
ep
->
port
);
SCH_ERR_RET
(
TSDB_CODE_SCH_INTERNAL_ERROR
);
...
...
source/libs/scheduler/src/scheduler.c
浏览文件 @
94f976ca
...
...
@@ -391,6 +391,8 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) {
SCH_TASK_ELOG
(
"taosArrayPush childTask failed, level:%d, taskIdx:%d, childIdx:%d"
,
i
,
m
,
n
);
SCH_ERR_RET
(
TSDB_CODE_QRY_OUT_OF_MEMORY
);
}
SCH_TASK_DLOG
(
"children info, the %d child TID %"
PRIx64
,
n
,
(
*
childTask
)
->
taskId
);
}
if
(
parentNum
>
0
)
{
...
...
@@ -423,6 +425,8 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) {
SCH_TASK_ELOG
(
"taosArrayPush parentTask failed, level:%d, taskIdx:%d, childIdx:%d"
,
i
,
m
,
n
);
SCH_ERR_RET
(
TSDB_CODE_QRY_OUT_OF_MEMORY
);
}
SCH_TASK_DLOG
(
"parents info, the %d parent TID %"
PRIx64
,
n
,
(
*
parentTask
)
->
taskId
);
}
SCH_TASK_DLOG
(
"level:%d, parentNum:%d, childNum:%d"
,
i
,
parentNum
,
childNum
);
...
...
@@ -464,6 +468,17 @@ int32_t schRecordTaskExecNode(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *ad
return
TSDB_CODE_SUCCESS
;
}
int32_t
schRecordQueryDataSrc
(
SSchJob
*
pJob
,
SSchTask
*
pTask
)
{
if
(
!
SCH_IS_DATA_SRC_QRY_TASK
(
pTask
))
{
return
TSDB_CODE_SUCCESS
;
}
taosArrayPush
(
pJob
->
dataSrcTasks
,
&
pTask
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
schValidateAndBuildJob
(
SQueryPlan
*
pDag
,
SSchJob
*
pJob
)
{
int32_t
code
=
0
;
pJob
->
queryId
=
pDag
->
queryId
;
...
...
@@ -473,6 +488,11 @@ int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) {
SCH_ERR_RET
(
TSDB_CODE_QRY_INVALID_INPUT
);
}
pJob
->
dataSrcTasks
=
taosArrayInit
(
pDag
->
numOfSubplans
,
POINTER_BYTES
);
if
(
NULL
==
pJob
->
dataSrcTasks
)
{
SCH_ERR_RET
(
TSDB_CODE_OUT_OF_MEMORY
);
}
int32_t
levelNum
=
(
int32_t
)
LIST_LENGTH
(
pDag
->
pSubplans
);
if
(
levelNum
<=
0
)
{
SCH_JOB_ELOG
(
"invalid level num:%d"
,
levelNum
);
...
...
@@ -551,6 +571,8 @@ int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) {
SCH_ERR_JRET
(
TSDB_CODE_QRY_OUT_OF_MEMORY
);
}
SCH_ERR_JRET
(
schRecordQueryDataSrc
(
pJob
,
p
));
if
(
0
!=
taosHashPut
(
planToTask
,
&
plan
,
POINTER_BYTES
,
&
p
,
POINTER_BYTES
))
{
SCH_TASK_ELOG
(
"taosHashPut to planToTaks failed, taskIdx:%d"
,
n
);
SCH_ERR_JRET
(
TSDB_CODE_QRY_OUT_OF_MEMORY
);
...
...
@@ -629,6 +651,17 @@ int32_t schSetTaskCandidateAddrs(SSchJob *pJob, SSchTask *pTask) {
return
TSDB_CODE_SUCCESS
;
}
int32_t
schRemoveTaskFromExecList
(
SSchJob
*
pJob
,
SSchTask
*
pTask
)
{
int32_t
code
=
taosHashRemove
(
pJob
->
execTasks
,
&
pTask
->
taskId
,
sizeof
(
pTask
->
taskId
));
if
(
code
)
{
SCH_TASK_ELOG
(
"task failed to rm from execTask list, code:%x"
,
code
);
SCH_ERR_RET
(
TSDB_CODE_SCH_INTERNAL_ERROR
);
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
schPushTaskToExecList
(
SSchJob
*
pJob
,
SSchTask
*
pTask
)
{
int32_t
code
=
taosHashPut
(
pJob
->
execTasks
,
&
pTask
->
taskId
,
sizeof
(
pTask
->
taskId
),
&
pTask
,
POINTER_BYTES
);
if
(
0
!=
code
)
{
...
...
@@ -774,6 +807,9 @@ int32_t schTaskCheckSetRetry(SSchJob *pJob, SSchTask *pTask, int32_t errCode, bo
int32_t
schHandleTaskRetry
(
SSchJob
*
pJob
,
SSchTask
*
pTask
)
{
atomic_sub_fetch_32
(
&
pTask
->
level
->
taskLaunchedNum
,
1
);
SCH_ERR_RET
(
schRemoveTaskFromExecList
(
pJob
,
pTask
));
SCH_SET_TASK_STATUS
(
pTask
,
JOB_TASK_STATUS_NOT_START
);
if
(
SCH_TASK_NEED_FLOW_CTRL
(
pJob
,
pTask
))
{
SCH_ERR_RET
(
schDecTaskFlowQuota
(
pJob
,
pTask
));
SCH_ERR_RET
(
schLaunchTasksInFlowCtrlList
(
pJob
,
pTask
));
...
...
@@ -947,6 +983,32 @@ _return:
SCH_RET
(
schProcessOnJobFailure
(
pJob
,
errCode
));
}
int32_t
schLaunchNextLevelTasks
(
SSchJob
*
pJob
,
SSchTask
*
pTask
)
{
if
(
!
SCH_IS_QUERY_JOB
(
pJob
))
{
return
TSDB_CODE_SUCCESS
;
}
SSchLevel
*
pLevel
=
pTask
->
level
;
int32_t
doneNum
=
atomic_add_fetch_32
(
&
pLevel
->
taskDoneNum
,
1
);
if
(
doneNum
==
pLevel
->
taskNum
)
{
pJob
->
levelIdx
--
;
pLevel
=
taosArrayGet
(
pJob
->
levels
,
pJob
->
levelIdx
);
for
(
int32_t
i
=
0
;
i
<
pLevel
->
taskNum
;
++
i
)
{
SSchTask
*
pTask
=
taosArrayGet
(
pLevel
->
subTasks
,
i
);
if
(
pTask
->
children
&&
taosArrayGetSize
(
pTask
->
children
)
>
0
)
{
continue
;
}
SCH_ERR_RET
(
schLaunchTask
(
pJob
,
pTask
));
}
}
return
TSDB_CODE_SUCCESS
;
}
// Note: no more task error processing, handled in function internal
int32_t
schProcessOnTaskSuccess
(
SSchJob
*
pJob
,
SSchTask
*
pTask
)
{
bool
moved
=
false
;
...
...
@@ -1015,11 +1077,13 @@ int32_t schProcessOnTaskSuccess(SSchJob *pJob, SSchTask *pTask) {
qSetSubplanExecutionNode
(
par
->
plan
,
pTask
->
plan
->
id
.
groupId
,
&
source
);
SCH_UNLOCK
(
SCH_WRITE
,
&
par
->
lock
);
if
(
SCH_TASK_READY_
TO_L
UNCH
(
readyNum
,
par
))
{
SCH_ERR_RET
(
schLaunchTask
Impl
(
pJob
,
par
));
if
(
SCH_TASK_READY_
FOR_LA
UNCH
(
readyNum
,
par
))
{
SCH_ERR_RET
(
schLaunchTask
(
pJob
,
par
));
}
}
SCH_ERR_RET
(
schLaunchNextLevelTasks
(
pJob
,
pTask
));
return
TSDB_CODE_SUCCESS
;
_return:
...
...
@@ -2400,8 +2464,6 @@ void schFreeJobImpl(void *job) {
for
(
int32_t
i
=
0
;
i
<
numOfLevels
;
++
i
)
{
SSchLevel
*
pLevel
=
taosArrayGet
(
pJob
->
levels
,
i
);
schFreeFlowCtrl
(
pLevel
);
int32_t
numOfTasks
=
taosArrayGetSize
(
pLevel
->
subTasks
);
for
(
int32_t
j
=
0
;
j
<
numOfTasks
;
++
j
)
{
SSchTask
*
pTask
=
taosArrayGet
(
pLevel
->
subTasks
,
j
);
...
...
@@ -2411,12 +2473,15 @@ void schFreeJobImpl(void *job) {
taosArrayDestroy
(
pLevel
->
subTasks
);
}
schFreeFlowCtrl
(
pJob
);
taosHashCleanup
(
pJob
->
execTasks
);
taosHashCleanup
(
pJob
->
failTasks
);
taosHashCleanup
(
pJob
->
succTasks
);
taosArrayDestroy
(
pJob
->
levels
);
taosArrayDestroy
(
pJob
->
nodeList
);
taosArrayDestroy
(
pJob
->
dataSrcTasks
);
qExplainFreeCtx
(
pJob
->
explainCtx
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录