Skip to content

Commit

Permalink
Merge pull request #390 from microsoft/ryonsteele/function-autoscale
Browse files Browse the repository at this point in the history
Ryonsteele/function autoscale
  • Loading branch information
ryonsteele authored Dec 19, 2023
2 parents 42cb0df + c826cdc commit 393e351
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 25 deletions.
19 changes: 17 additions & 2 deletions app/enrichment/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import json
import logging
import os
import threading
import time
import re
from datetime import datetime
from typing import List
Expand Down Expand Up @@ -276,9 +278,17 @@ def get_tags_and_upload_to_cosmos(blob_service_client, blob_path):
tagsHelper.upsert_document(blob_path, tags_list)
return tags_list


@app.on_event("startup")
@repeat_every(seconds=5, logger=log, raise_exceptions=True)
def startup_event():
poll_thread = threading.Thread(target=poll_queue_thread)
poll_thread.daemon = True
poll_thread.start()

def poll_queue_thread():
while True:
poll_queue()
time.sleep(5)

def poll_queue() -> None:
"""Polls the queue for messages and embeds them"""

Expand All @@ -294,6 +304,11 @@ def poll_queue() -> None:
response = queue_client.receive_messages(max_messages=int(ENV["DEQUEUE_MESSAGE_BATCH_SIZE"]))
messages = [x for x in response]

if not messages:
log.debug("No messages to process. Waiting for a couple of minutes...")
time.sleep(120) # Sleep for 2 minutes
return

target_embeddings_model = re.sub(r'[^a-zA-Z0-9_\-.]', '_', ENV["TARGET_EMBEDDINGS_MODEL"])

# Remove from queue to prevent duplicate processing from any additional instances
Expand Down
6 changes: 3 additions & 3 deletions app/frontend/src/components/filepicker/file-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ const FilePicker = ({folderPath, tags}: Props) => {

// handler called when files are selected via the Dropzone component
const handleOnChange = useCallback((files: any) => {

let filesArray = Array.from(files);

filesArray = filesArray.map((file) => ({
id: nanoid(),
file
}));

}));
setFiles(filesArray as any);
setProgress(0);
setUploadStarted(false);
}, []);
}, []);

// handle for removing files form the files list view
const handleClearFile = useCallback((id: any) => {
Expand Down
149 changes: 149 additions & 0 deletions docs/deployment/autoscale_sku.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Autoscale Settings Documentation

These are the current out of the box Autoscale settings.
You may find better settings to fit your needs. This document explains how this can be accomplished.

## Azure Functions Service Plan Autoscale

### Overview

The Azure Functions Service Plan Autoscale settings are defined in the file located at `/infra/core/host/funcserviceplan.bicep`. These settings enable automatic scaling of the Azure Functions Service Plan based on CPU usage metrics.



**File Location:** `/infra/core/host/funcserviceplan.bicep`

#### Scaling Rules

1. **Increase Capacity Rule:**
- **Metric:** `CpuPercentage`
- **Operator:** `GreaterThan`
- **Threshold:** `60%`
- **Time Window:** `5 minutes`
- **Scaling Action:** Increase capacity by `2` with a cooldown of `5 minutes`.

2. **Decrease Capacity Rule:**
- **Metric:** `CpuPercentage`
- **Operator:** `LessThan`
- **Threshold:** `40%`
- **Time Window:** `5 minutes`
- **Scaling Action:** Decrease capacity by `2` with a cooldown of `2 minutes`.


## App Service Plan Autoscale for Enrichment App

### Overview

The App Service Plan Autoscale settings for the enrichment app are defined in the file located at `/infra/core/host.enrichmentappserviceplan.bicep`. These settings enable automatic scaling of the App Service Plan based on CPU usage metrics.

### Key Parameters

**File Location:** `/infra/core/host.enrichmentappserviceplan.bicep`

#### Scaling Rules

1. **Increase Capacity Rule:**
- **Metric:** `CpuPercentage`
- **Operator:** `GreaterThan`
- **Threshold:** `60%`
- **Time Window:** `5 minutes`
- **Scaling Action:** Increase capacity by `1` with a cooldown of `5 minutes`.

2. **Decrease Capacity Rule:**
- **Metric:** `CpuPercentage`
- **Operator:** `LessThan`
- **Threshold:** `20%`
- **Time Window:** `10 minutes`
- **Scaling Action:** Decrease capacity by `1` with a cooldown of `15 minutes`.

### Customization

To customize the App Service Plan Autoscale settings, modify the parameters mentioned above in the specified Bicep file. And Run the `make infrastructure` command.



# SKU Settings Documentation

### Overview

The SKU settings for all Service Plans are defined in the file located at `/infra/main.bicep`. The SKU (Stock Keeping Unit) represents the pricing tier or plan for your App Service. It defines the performance, features, and capacity of the App Service.
More information can be found [here.](https://azure.microsoft.com/en-us/pricing/details/app-service/windows/#purchase-options)

## Web App Service Plan SKU


**File Location:** `/infra/main.bicep`

#### SKU Settings

- **Name:** `S1`
- **Capacity:** `3`


## Functions Service Plan SKU


**File Location:** `/infra/main.bicep`

#### SKU Settings

- **Name:** `S2`
- **Capacity:** `2`

## Enrichment App Service Plan SKU


**File Location:** `/infra/main.bicep`

#### SKU Settings

- **Name:** `P1v3`
- **Tier:** `PremiumV3`
- **Size:** `P1v3`
- **Family:** `Pv3`
- **Capacity:** `1`

### Enrichment Message Dequeue Parameter
There exist a property that can be set in the local.env file called `DEQUEUE_MESSAGE_BATCH_SIZE` and is defaulted in the `infra/main.bicep` and `app/enrichment/app.py` to the value of **3**. This means the app will process 3 messages from the queue at a time. This is found to be the most opitmal with the existing configuration but can be increased if you also increase the enrichment app service SKU. It is important to note that there will be issues if it is increased more than the app service SKU can handle.

### Customization

To customize the App Service Plans SKU settings, modify the `sku` parameters in the specified Bicep file and run the `make deploy` or `make infrastructure`command.

This can also be adjusted in the Azure Portal.

**Note:** Adjusting the scale or Tier can cause outages until the redeployment occurrs.


### Steps to Scale Up:

>1. **Sign in to the Azure Portal:**
> - Open a web browser and navigate to the [Azure Portal](https://portal.azure.com/).
> - Log in with your Azure account credentials.
>2. **Navigate to the App Service:**
> - In the left navigation pane, select "App Services."
> - Click on the specific App Service you want to scale.
>3. **Access the Scale Up Blade:**
> - In the App Service menu, find and click on "Scale up (App Service plan)" in the left sidebar.
>4. **Choose a New Pricing Tier:**
> - On the "Scale Up" blade, you'll see different pricing tiers representing various levels of resources.
> - Select the desired pricing tier that corresponds to the scale you need.
>5. **Review and Apply Changes:**
> - Review the information about the selected pricing tier, including its features and costs.
> - Click the "Apply" or "Save" button to apply the changes.

### Considerations:
- **Cost Implications:**
- Be aware of the cost implications associated with higher pricing tiers. Review the Azure Pricing documentation for details on costs.

- **Resource Limits:**
- Ensure that the new pricing tier aligns with the resource requirements of your application. Some tiers may have limitations on resources.

- **Performance Impact:**
- Scaling up provides additional resources, potentially improving performance. However, it's essential to assess whether your application benefits from the increased resources.

6 changes: 6 additions & 0 deletions docs/features/optional_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Please see below sections for coverage of IA Accelerator optional features.
* [Customer Usage Attribution](/docs/features/features.md#customer-usage-attribution)
* [Sovereign Region Deployment](/docs/features/features.md#sovereign-region-deployment)
* [Configure REST API access](#configure-rest-api-access)
* [Customize Autoscale and App Service SKU's](#customize-autoscale)

## Configuring your own language ENV file

Expand Down Expand Up @@ -45,3 +46,8 @@ Check out how to [setup Sovereign Region Deployment](/docs/deployment/enable_sov

If you are wanting to use the API stand-alone or use a custom UI.
Check out how to [enable OAuth Client Credentials Flow](/docs/deployment/client_credentials_flow.md)

## Customize Autoscale

If you want to learn more about Autoscale Settings and App Service SKU's
Check out how to [customize Autoscale settings](/docs/deployment/autoscale_sku.md)
11 changes: 8 additions & 3 deletions functions/host.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.*, 4.0.0)"
},
"extensions": {
"queues": {
"batchSize": 3
}
},
"concurrency": {
"dynamicConcurrencyEnabled": true,
"snapshotPersistenceEnabled": true
"dynamicConcurrencyEnabled": false,
"snapshotPersistenceEnabled": false
},
"functionTimeout": "01:00:00"
"functionTimeout": "02:00:00"
}
36 changes: 25 additions & 11 deletions infra/core/host/enrichmentappserviceplan.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ param kind string = ''
param reserved bool = true
param sku object

param storageAccountId string


// Create an App Service Plan to group applications under the same payment plan and SKU, specifically for containers
resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
Expand Down Expand Up @@ -40,29 +38,45 @@ resource scaleOutRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = {
{
name: 'Scale out condition'
capacity: {
maximum: '3'
maximum: '5'
default: '1'
minimum: '1'
}
rules: [
{
metricTrigger: {
metricName: 'CpuPercentage'
metricResourceUri: appServicePlan.id
timeGrain: 'PT1M'
statistic: 'Average'
timeWindow: 'PT5M'
timeAggregation: 'Average'
operator: 'GreaterThan'
threshold: 60
}
scaleAction: {
direction: 'Increase'
type: 'ChangeCount'
value: '1'
cooldown: 'PT5M'
}
}
{
metricTrigger: {
metricName: 'ApproximateMessageCount'
metricNamespace: ''
metricResourceUri: storageAccountId
operator: 'GreaterThan'
statistic: 'Average'
threshold: 10
timeAggregation: 'Average'
metricName: 'CpuPercentage'
metricResourceUri: appServicePlan.id
timeGrain: 'PT1M'
statistic: 'Average'
timeWindow: 'PT10M'
dividePerInstance: true
timeAggregation: 'Average'
operator: 'LessThan'
threshold: 20
}
scaleAction: {
direction: 'Decrease'
type: 'ChangeCount'
value: '1'
cooldown: 'PT15M'
}
}
]
Expand Down
57 changes: 57 additions & 0 deletions infra/core/host/funcserviceplan.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,62 @@ resource funcServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
}
}

resource autoscaleSettings 'Microsoft.Insights/autoscalesettings@2022-10-01' = {
name: '${funcServicePlan.name}-Autoscale'
location: location
properties: {
enabled: true
profiles: [
{
name: '${funcServicePlan.name}-Autoscale'
capacity: {
default: '2'
minimum: '2'
maximum: '10'
}
rules: [
{
metricTrigger: {
metricName: 'CpuPercentage'
metricResourceUri: funcServicePlan.id
timeGrain: 'PT1M'
statistic: 'Average'
timeWindow: 'PT5M'
timeAggregation: 'Average'
operator: 'GreaterThan'
threshold: 60
}
scaleAction: {
direction: 'Increase'
type: 'ChangeCount'
value: '2'
cooldown: 'PT5M'
}
}
{
metricTrigger: {
metricName: 'CpuPercentage'
metricResourceUri: funcServicePlan.id
timeGrain: 'PT1M'
statistic: 'Average'
timeWindow: 'PT5M'
timeAggregation: 'Average'
operator: 'LessThan'
threshold: 40
}
scaleAction: {
direction: 'Decrease'
type: 'ChangeCount'
value: '2'
cooldown: 'PT2M'
}
}
]
}
]
targetResourceUri: funcServicePlan.id
}
}

output id string = funcServicePlan.id
output name string = funcServicePlan.name
Loading

0 comments on commit 393e351

Please sign in to comment.