-
Notifications
You must be signed in to change notification settings - Fork 13.8k
[FLINK-9455][RM] Add support for multi task slot TaskExecutors #6734
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
Conversation
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.
Thanks for the nice feature @tillrohrmann ! I left some comments to consider minor improvements before merge.
this.workersInLaunch = new HashMap<>(8); | ||
this.workersBeingReturned = new HashMap<>(8); | ||
|
||
final ContaineredTaskManagerParameters containeredTaskManagerParameters = taskManagerParameters.containeredParameters(); |
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.
I would create a method to create and return slotsPerWorker
to unload constructor code.
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.
Good idea.
// create the specific TM parameters from the resource profile and some defaults | ||
MesosTaskManagerParameters params = new MesosTaskManagerParameters( | ||
resourceProfile.getCpuCores() < 1.0 ? taskManagerParameters.cpus() : resourceProfile.getCpuCores(), | ||
taskManagerParameters.cpus(), |
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 looks like a copying of immutable MesosTaskManagerParameters
. Is it on purpose?
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.
No it is not on purpose. Will correct it.
this(0, 0); | ||
} | ||
|
||
PendingSlotBalance(int numPendingSlots, int numUnassignedSlots) { |
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.
minor: @nonnegative
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.
I will remove this class since it is a left-over from a previous implementation.
return pendingTaskManagerSlot; | ||
} | ||
|
||
public void assignPendingTaskManagerSlot(PendingTaskManagerSlot pendingTaskManagerSlotToAssign) { |
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.
@nonnull pendingTaskManagerSlotToAssign seems to make sense only then
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.
Yes will add it.
return resourceProfile; | ||
} | ||
|
||
public void assignPendingSlotRequest(PendingSlotRequest pendingSlotRequestToAssign) { |
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.
also here @nonnull pendingSlotRequestToAssign
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.
true.
} | ||
|
||
updateSlot(slotId, allocationId, jobId); | ||
private void completePendingTaskManagerSlot(ResourceProfile resourceProfile) { |
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.
is this completePendingTaskManagerSlot
some leftover? looks unused
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.
Yes, will remove it.
/** | ||
* Immutable slot balance. | ||
*/ | ||
final class ImmutablePendingSlotBalance extends PendingSlotBalance { |
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.
I cannot find where these balance classes are used. Are they for future?
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.
No a left-over from a previous implementation. Will remove it.
slotManager.registerTaskManager(taskExecutorConnection, slotReport); | ||
|
||
assertThat(slotManager.getNumberRegisteredSlots(), is(numberSlots - 1)); | ||
assertThat(slotManager.getNumberPendingTaskManagerSlots(), is(1)); |
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 slot request should be fulfilled now, right? Then we could also check:
assertThat(slotManager.getNumberAssignedPendingTaskManagerSlots(), is(0));
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.
I think getNumberPendingTaskManagerSlots == 1
is an even stricter condition, because it requires that actually some of the pending task manager slots have been completed.
final ResourceActions resourceManagerActions = mock(ResourceActions.class); | ||
final AtomicInteger allocateResourceCalls = new AtomicInteger(0); | ||
final ResourceActions resourceManagerActions = new TestingResourceActionsBuilder() | ||
.setAllocateResourceConsumer(resourceProfile -> allocateResourceCalls.incrementAndGet()) |
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 logic of some of this built TestingResourceActions repeat in some places, we could create some standard factory methods for them (maybe in future), e.g.:
resourceManagerActions = TestingResourceActionsBuilder.createAllocatingFixedSlotsResource(numOfSlotsPerWorker);
allocateResourceCalls = resourceManagerActions.getAllocationsCounter();
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.
True, one could add a helper function doing this.
a59e4d4
to
c5412f5
Compare
// ------------------------------------------------------------------------ | ||
|
||
protected static Collection<ResourceProfile> createSlotsPerWorker(int numSlots) { | ||
final Collection<ResourceProfile> slots = new ArrayList<>(numSlots); |
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.
It would be enough to write:
Collections.nCopies(numSlots, ResourceProfile.ANY);
The returned List
would also be immutable. At the moment there is no need to return a mutable list. I would even say it is not right that after calling Collection<ResourceProfile> startNewWorker(ResourceProfile resourceProfile)
, one may potentially modify the state of the ResourceManager (by accidentally modifying the returned collection).
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.
Good point. I'll update the PR.
final PendingTaskManagerSlot pendingTaskManagerSlot; | ||
|
||
if (allocationId == null) { | ||
pendingTaskManagerSlot = findExactlyMatchingPendingTaskManagerSlot(resourceProfile); |
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.
Why use exactly matching here but isMatching in other place? I think we should make the methods for finding pending task manager slots extendable so user can define their own matching algorithm according to need.
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.
Because we use the ResourceProfile
at the moment as a key for fulfilling pending task manager slots. Therefore, we need to find an exactly matching resource profile. In the future we could introduce an ID to identify newly started slots.
Think for example that you have two pending slots with resource profile (1,1)
and (2,2)
. Now a slot with (2,2)
is registered. You don't want to complete the pending task manager slot (1,1)
(even though it would fulfill the requirements), because the slot (1,1)
, won't be able to complete the remaining pending task manager slot.
Making the matching algorithm pluggable should be a separate issue.
c5412f5
to
3201620
Compare
3201620
to
2a7c6b9
Compare
Extend ResourceActions interface to return a set of ResourceProfiles describing the set of slots with which the new resource will be started. The SlotManager stores them as PendingTaskManagerSlots which can be assigned to PendingSlotRequests. Only if there are no more TaskManagerSlots and PendingTaskManagerSlots, the SlotManager will request new resources from the ResourceManager. This closes apache#6734.
2a7c6b9
to
1ac7336
Compare
Thanks for the review @azagrebin, @GJL and @shuai-xu. Merging this PR once Travis gives green light. |
Extend ResourceActions interface to return a set of ResourceProfiles describing the set of slots with which the new resource will be started. The SlotManager stores them as PendingTaskManagerSlots which can be assigned to PendingSlotRequests. Only if there are no more TaskManagerSlots and PendingTaskManagerSlots, the SlotManager will request new resources from the ResourceManager. This closes apache#6734. (cherry picked from commit 771277b)
@tillrohrmann Hello, I am confused with you code. Before your code, YarnResourceManager's requestYarnContainer will addContainerRequest only if pendingSlotRequests is bigger than pendingSlotAllocation, I think that Flink already won't allocate resources over-excessive when numberOfTaskSlots is bigger than 1. So I am confused what your code does compared with the previous code. Thank you very much. |
Hi @Myracle, the problem was that Flink did not take the number of pending slots into account (one TaskExecutor can be started with many slots) and instead only looked at the number of container requests (== number of TaskExecutors to be started). With this change, Flink does this properly. |
@tillrohrmann Thank you for your reply. Before your change, Flink calculate pendingTaskManagerSlots(==numPendingContainerRequests * numberOfTaskSlots) in the class YarnResourceManager. Flink will only request containers from yarn when pendingTaskManagerSlots is bigger than pendingTaskManagerSlots. It means that Flink will request resources only when total requested slots can not satisfy current's requirement. There is another issue ([FLINK-9567][yarn] Before requesting new containers always check if it is required). Does FLINK-9567 resolve the same problem? What's the difference between your issue and FLINK-9567? Thank you. |
What is the purpose of the change
This PR adds support for multi task slot TaskExecutors to Flink. Before it was recommended to start a Flink cluster with single slot
TaskExecutors
. Now also multi slotTaskExecutors
can be configured and Flink won't allocate resources over-excessively.Brief change log
ResourceActions#allocateResource
to returnCollection<ResourceProfile>
indicating the set of slots to expectPendingTaskManagerSlot
PendingTaskManagerSlot
to fulfillPendingSlotRequest
TaskManagerSlots
andPendingTaskManagerSlots
Verifying this change
SlotManagerTest#
:testRequestNewResources
,testFailingAllocationReturnsPendingTaskManagerSlot
,testPendingTaskManagerSlotCompletion
,testRegistrationOfDifferentSlot
,testOnlyFreeSlotsCanFulfillPendingTaskManagerSlot
,Does this pull request potentially affect one of the following parts:
@Public(Evolving)
: (no)Documentation