Search code examples
azureazure-container-appskedakeda-scaledjobazure-container-app-jobs

How to Configure Container App Job to use Accurate KEDA


We are having some difficulty figuring out how to configure the auto scale rules on our Azure Container App Job to use the "accurate" calculation method vs the default when determining the number of replicas needed to process a given queue length. The problem lies in that our replicas perform long running jobs and pull an item off the queue as soon as the container spins up. (We do not leave the items in the queue in a locked state)

Each running container may run for 20 to 60 minutes given the amount tasks that need to be performed. When the scaler evaluates the queue length again (say in 1 minute) the queue may have received 2 new items but since there are already two replicas running (processing 2 previous items from 20 minutes ago) it actually thinks the two active replicas are for the 2 items currently sitting in the queue which is not the case. The "accurate" calculation method is supposed to be a simple 1 to 1. One item in the queue would spin up 1 replica without any assumption that a running replica is for an existing item in the queue.

The MS documentation here states that we should be able to take full advantage of any of the ScaledObject base KEDA scalers.

enter image description here

The following is an example of our current Scale Rule which looks at the queue length and works only as described above.

enter image description here

Could use some ideas in configuring this to be a 1 to 1 queue item to replica.

Thanks,


Solution

  • To use an "accurate" calculation method for auto-scaling with KEDA, you can set up a custom scaling rule like this

    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      name: azure-servicebus-queue-scaler
      namespace: default
    spec:
      scaleTargetRef:
        kind: Deployment
        name: myapp
      pollingInterval: 30  
      cooldownPeriod: 300  
      minReplicaCount: 1   
      maxReplicaCount: 100  
      triggers:
      - type: azure-servicebus
        metadata:
          namespace: "amarServiceBusNamespace"
          queueName: "workflow_activity_output_queue"
          messageCount: "1"  # Trigger scale-out when there is at least 1 message
        authenticationRef:
          name: azure-servicebus-auth  # Reference to the authentication secret
    

    Just ensure that the messageCount should be set to 1 to ensure each message triggers a new replica and you provide the queueName where your messages are stored.

    Create a trigger authentication

    apiVersion: keda.sh/v1alpha1
    kind: TriggerAuthentication
    metadata:
      name: azure-servicebus-auth
      namespace: default
    spec:
      secretTargetRef:
        - parameter: connection
          name: servicebus-secret
          key: connectionString
    

    enter image description here

    But before this you need to create a az servicebus namespace create --resource-group arkorg --name amarServiceBusNamespace --location eastus --sku Standard

    enter image description here

    and a queue

    az servicebus queue create --resource-group arkorg --namespace-name amarServiceBusNamespace --name workflow_activity_output_queue
    

    enter image description here

    and deploy your keda

    helm install keda kedacore/keda --namespace keda --create-namespace
    

    enter image description here

    As you have already shared in your question, the container app scaling example section remains the same i.e. to use this ScaledObject for scaling, and the connection string is correctly stored in the specified secret.

    az servicebus namespace authorization-rule keys list --resource-group arkorg --namespace-name amarServiceBusNamespace --name RootManageSharedAccessKey --query primaryConnectionString --output tsv
    

    enter image description here

    kubectl create secret generic servicebus-secret --from-literal=connectionString="sb://amarservicebusnamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=abcdefghijklmnop=" -n default
    

    enter image description here

    References: