-
Notifications
You must be signed in to change notification settings - Fork 28.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SPARK-25250][CORE] : Late zombie task completions handled correctly even before new taskset launched #22806
Changes from 28 commits
5ad6efd
8667c28
a73f619
5509165
ee5bc68
7677aec
67e1644
f395b65
f7102ca
6709fe1
5234e87
9efbc58
6abd52c
89373af
231c51b
fcfe9f5
7ce6f10
0610939
929fbf9
393f901
52e832a
afbac96
024ec53
d2b7044
d6ac4a9
e9b363b
b55dbb0
551f412
28017ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -808,7 +808,6 @@ private[spark] class TaskSetManager( | |
if (tasksSuccessful == numTasks) { | ||
isZombie = true | ||
} | ||
maybeFinishTaskSet() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why you remove this ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before we were going to merge this PR, the redundant call to |
||
} | ||
} | ||
} | ||
|
@@ -924,6 +923,9 @@ private[spark] class TaskSetManager( | |
s" be re-executed (either because the task failed with a shuffle data fetch failure," + | ||
s" so the previous stage needs to be re-run, or because a different copy of the task" + | ||
s" has already succeeded).") | ||
} else if (sched.stageIdToFinishedPartitions.getOrElse( | ||
stageId, new HashSet[Int]).contains(tasks(index).partitionId)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this may create empty hash set unnecessarily. how about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense, have changed it. |
||
sched.markPartitionCompletedInAllTaskSets(stageId, tasks(index).partitionId, info) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(I'm also not really convinced this would solve the problem, but I'm afraid I have to spend a bit more time paging it all back in ...) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that is correct, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hashmaps are totally unsafe to be used for multiple threads -- its not just getting inconsistent values, its that the hashmap may be in some undefined state b/c of rehashing. see eg. http://javabypatel.blogspot.com/2016/01/infinite-loop-in-hashmap.html (I just skimmed this but I think it has the right idea). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, in that case, what if I turn There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that will take care of the access-during-rehash, but I'm still not sure the values of this are safe. Here you're querying it from a task-result-getter thread, but you're also updating it from the dag scheduler event loop, with no lock protecting access. The other proposal is easier to reason about, because it keeps this structure protected by a lock on TaskSchedulerImpl. |
||
} else { | ||
addPendingTask(index) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This call from thread
dag-scheduler-event-loop
do not acquire a lock onTaskScheduler
, so I think race condition still exists, sincehandleFailedTask
is called from threadtask-result-getter
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method
handleFailedTask
is called from TaskResultGetter to TaskSchedulerImpl which executes the call to TaskSetManager in synchronized block. So, my code in TaskSetManager runs within the TaskSchedulerImpl lock.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pgandhi999 I don't follow your explanation -- I think I agree w/ @Ngone51 . yes, TSM calls
DAGs.taskEnded
while it has a lock on the TaskSchedulerImpl, but theDAGs.taskEnded
call just puts an event into the queue and then returns. So this part is happening w/ out the lock. but maybe you meant something else?