Auto-Scaling in AWS

Liferay’s auto-scaling feature automatically creates and destroys replicas (nodes) in the Liferay cluster to optimize performance. You can choose the minimum and maximum number of nodes that can be up at any time. Monitor your resource usage (CPU and memory) regularly for applications that require auto-scaling.

Note

Clustering and auto-scaling require a valid Liferay cluster license.

Static Clustering

Static clustering consists of manually setting the number of replicas desired by using the replicaCount property:

replicaCount: 2

After configuring Helm to scale the cluster, run the following command using the Kubernetes CLI with the desired replica number:

kubectl scale statefulset/liferay --replicas=2
Note

You can use scale Liferay automatically with static clustering by using an external agent to look at metrics and decide when and how to scale. However, dynamic clustering is recommended for those who are more experienced with auto-scaling.

Dynamic Clustering

Default auto-scaling using dynamic clustering lets you define how the cluster scales based on metrics emitted by the Kubernetes Metrics Server (CPU and memory). To scale based on other metrics, see Advanced Auto-Scaling Using Custom Metrics. Follow these steps to configure dynamic clustering:

  1. Configure container resources to prepare your cluster for auto-scaling.

  2. Set the autoscaling.enabled portal propertyto true.

  3. Next, define the autoscaling Helm property in your .yaml file. To do this, you must pass a few other properties as its value.

  4. Set the enabled property to true:

    enabled: true
    
  5. Choose a number of minReplicas and maxReplicas to limit how Kubernetes can scale your cluster.

    maxReplicas: 5
    minReplicas: 1
    
  6. Choose the metrics to base the scaling. For example, to keep the CPU and memory usage of each replica at 80%, use the following values. This way, if either the CPU or memory is near its limit for a replica, a new one is created to lighten the load. Additionally, if the average CPU and memory usage is lower than this, the cluster destroys a replica to save resources.

    metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          averageUtilization: 80
          type: Utilization
    - type: Resource
      resource:
        name: memory
        target:
          averageUtilization: 80
          type: Utilization
    
  7. Lastly, you can define additional behavior like the frequency to verify metrics, the timeout before scaling, the tolerance range for resource usage, and more:

    behavior:
      scaleDown:
        policies:
        - periodSeconds: 60
          type: Percent
          value: 10
          type: Pods
          value: 1
        stabilizationWindowSeconds: 60
      scaleUp:
        stabilizationWindowSeconds: 300
    

In the end, your autoscaling property should look something like this:

autoscaling:
  behavior:
    scaleDown:
      policies:
      - periodSeconds: 60
        type: Percent
        value: 10
        type: Pods
        value: 1
      stabilizationWindowSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 300
  enabled: true
  maxReplicas: 5
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        averageUtilization: 80
        type: Utilization
  - type: Resource
    resource:
      name: memory
      target:
        averageUtilization: 80
        type: Utilization
  minReplicas: 1

Advanced Auto-Scaling Using Custom Metrics

Auto-scaling using custom metrics requires an external adapter that implements custom.metrics.k8s.io or external.metrics.k8s.io APIs. The recommended solution for this is KEDA. You also need a way to collect metrics from the Kubernetes cluster. See Viewing Metrics from Kubernetes for more information.

Once completed, the necessary metric data is stored in a system that a KEDA scaler can be configured to use as a data source. Install KEDA using the following Helm commands:

  1. Navigate to liferay-aws-terraform/cloud. This is the directory where you previously installed Liferay.

  2. Install the KEDA helm chart:

    helm repo add kedacore https://kedacore.github.io/charts
    helm repo update
    helm upgrade -i keda kedacore/keda \
        --create-namespace \
        --namespace keda-system
    
  3. Define a resource to control the custom metrics that are being collected:

    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      annotations:
        scaledobject.keda.sh/transfer-hpa-ownership: "true"
      name: liferay-scaledobject
      namespace: liferay-system
    spec:
      advanced:
        horizontalPodAutoscalerConfig:
          name: liferay-default
        restoreToOriginalReplicaCount: true
      cooldownPeriod: 300
      maxReplicaCount: 5
      minReplicaCount: 1
      pollingInterval: 30
      scaleTargetRef:
        apiVersion: apps/v1
        kind: StatefulSet
        name: liferay-default
      triggers:
        [...]
    
  4. For the triggers key in the .yaml file, choose the metric that auto-scaling should be based on. For example, if you’re using Prometheus as the collector and you wish to scale when the number of live users reaches 200 per node:

    triggers:
    - type: prometheus
      metadata:
        serverAddress: http://prometheus-server.prometheus-system:9090
        query: abs(server_live_users{instance="liferay-default-0", job="liferay-system/liferay-default"}) / on(job) group_left() count by (job) (server_live_users{job="liferay-system/liferay-default"})
        threshold: '200'
    
  5. Install the resource using the following command:

    kubectl apply -n liferay-system -f liferay-scaledobject.yaml
    

Now, as users login, when the number exceeds 200 per node, the cluster will scale up.