-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Adding Scaling Strategy for ScaledJob #1227
Conversation
Signed-off-by: Tsuyoshi Ushio <[email protected]>
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.
Looking good, minor comments
Signed-off-by: Tsuyoshi Ushio <[email protected]>
Hi @zroubalik |
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.
LGTM, thanks @TsuyoshiUshio !
Signed-off-by: Tsuyoshi Ushio <[email protected]>
Hey, I tried using "accurate" strategy, but because it takes pods lots of time to actually get started and consume the message, every polling_time, the trigger is creating new pods for messages that pods were already created for. Is that the expected behaviour? Am I missing something here? If that's the way it works, distinguishing between runningJobs and waitingJobs somehow could help calculating the right amount of new pods to schedule. |
@TsuyoshiUshio PTAL |
Hi @orsher For example, some customer using this strategy with ServiceBus. The service bus scaler queue length includes running jobs. Which scaler do you use? If your scaler's queue length include the number of running jobs, and your job consume a message then do something, after finishing the job, the message is deleted from queue, then you can use default strategy. However, we need to learn more use case, If your use case is not I described, could you share which scaler, and how is your job's message consuming strategy? I'd happy to hear that and reflect it to keda. |
Hey @TsuyoshiUshio , We get much more jobs sent than what we need and it will keep sending some more jobs until there will be available resources for the jobs to actually start running, consume and ack the messages. I hope that this flow is clear. Am I missing something here? |
I think there is a typo in this documentation that has been confusing me: in
maxScale and queueLength should be the same thing. @orsher my plan to deal with that is to increase the poll interval, and write my consumers to shut themselves down if there is no message to consume. But i agree, it should take into account pending jobs when calculating the new scale, probably something like
which could be simplified to
|
I see the exact same problem as @orsher using Azure Storage Queues. It is kind of independent of the queue type and strategy used right now, as it is a problem with an inner fast control loop scaling up the number of jobs a lot faster than our outer control loops making resources available (scaling out virtual machines/nodes in our case). We have already made our jobs do some queue message polling 10 times, then shut down if there are no messages, so the extra jobs are not a big problem from that standpoint. But since some of our jobs are very resource intensive and long running (which is kinda the point of using Jobs instead of Deployments for us), we have to put some high There are of course a lot of variables we can tweak, like the polling interval, but we would like to start our long running jobs as fast as possible (i.e. having a short poll interval), and have a design that allows some slower startup only when we have bursty requests. Taking Edit: I think this issue is covering the problem already: #1323 |
Sorry for the inconvenience. I'll have a look However, we should talk in #1323 rather than merged PR. |
Signed-off-by: Thomas Lamure <[email protected]>
Hey @TsuyoshiUshio, I am using Azure Queue Storage and from what I understand it gives the count of all messages (invisible/running and visible/non-running). You have mentioned that in such cases we should use 'default' strategy, but the official doc recommends the use of 'accurate' strategy for Azure Queue Storage. |
I talked with Several Customers of the ScaledJob. The use case is totally different, and the request for the Scaling Logic is also different. Also I found some limitation for many scalers. For considering, all of these, I'd like to introduce new scale logic.
Probably, we can discuss the
custom
scale logic that I talk you later.What do we need to know?
1.
ScaledJob
scaling expectationHPA scaler is about Scale-In, and Scale-Out, however, ScaledJob has no Scale-In/Out If new messages arrives in the queue, it should create new jobs until it reaches
maxReplicaCount
.2. Limitation of the
queueLength
implementationScalers use various SDKs. The behavior is different. If we fetch the
queueLength
, it usually includeslocked message
and there is no way to fetchthe number of message that not locked
.The ideal metric is
the number of message that is not locked
. Why? The ideal number of the scale will be newly arrived messages. There are several jobs running, however, we can ignore it until it reachesMaxReplicaCount
. That is the ideal behavior. For gettingnewly arrived message
, it should not includesthe number of locked message
that means, messages that is already consumed by jobs. However, a lot of implementation of SDKs includes the locked messages as a number ofqueueLength
. That causes an issue for ScaledJob.The kind of scalers
a. Some of them can fetch the
queueLength
as the number ofall messages - locked messages
. ideal metrics e.g. Azure Storage Queue.b. Some of them is not. e.g. Azure Service Bus. It will return
queueLength
as the number ofall messages
We need to adjust two use cases. In case of a, Things is easy, it is ideal metric. We can have one firm scale logic for Scaled Job.
However, in case of b. We need to compromise the scale logic. And it might be very different for each use cases.
I introduce three scaling strategy
default
,custom
,accurate
. For the a. I provideaccurate
. For the b. I providedefault
andcustom
. If you don't specify anything, it will bedefault
The logic of three strategies
queueLength
: the length of messages on a queuerunningJobCount
: the number of running jobsdefault
The original logic of ScaledJob. It is default to protect from a breaking change.
custom
You can configure
customScalingQueueLengthDeduction
andcustomScalingRunningJobPercentage
on the ScaledJob definition. Users can change the parameter based on the default logic.queueLength - customScalingQueueLengthDeduction - (runningJobCount * customScalingRunningJobPercentage)
However, it doesn't exceed
MaxReplicaCount
.accurate
If the scaler returns ideal metrics or, customer delete a message once consumed it, it will be the ideal number of the queue then you can use this strategy.
Example Configuration
Checklist
Fixes #
#1186
#1207
Documentation
kedacore/keda-docs#279