Reputation: 687
I got a large dataset of all the addresses in my country (3.8GB). I am creating an API which will query the database for one specific address and respond with basic JSON data (300bytes). The API is running in Python on Azure Functions.
So far everything works great. When I do a single request I get a response time of +/- 100-150ms. Great! but... If I try to load test the API with, let's say, 200 requests in 1 minute. The average response time is around 4-6 seconds.
This is what I tried so far
Is there some limit on the number of connections per database? The SQL Database or Cosmos DB doesn't seem to be the issue (% of CPU/Mem are good).
I created a simple /status
endpoint without the DB connection on the API which can handle 200 requests in 1 minute easily. Hopefully someone can push me in the right direction.
import azure.functions as func
import os
from azure.functions import AsgiMiddleware
from fastapi import Query
from typing import Optional
from api_app import app
import azure.cosmos.documents as documents
import azure.cosmos.cosmos_client as cosmos_client
import azure.cosmos.exceptions as exceptions
from azure.cosmos.partition_key import PartitionKey
@app.get("/status")
def get_status():
return ({"status": 200})
@app.get("/postcode_cosmosdb/{postcode}/{huisnummer}")
async def postcode_cosmosdb(postcode: str, huisnummer: int):
settings = {
'host': os.environ.get('ACCOUNT_HOST', 'XXXXXX'),
'master_key': os.environ.get('ACCOUNT_KEY', 'XXXXXX'),
'database_id': os.environ.get('COSMOS_DATABASE', 'WoningAdressen'),
'container_id': os.environ.get('COSMOS_CONTAINER', 'AdressenLight'),
}
HOST = settings['host']
MASTER_KEY = settings['master_key']
DATABASE_ID = settings['database_id']
CONTAINER_ID = settings['container_id']
client = cosmos_client.CosmosClient(HOST, {'masterKey': MASTER_KEY}, user_agent="CosmosDBPythonQuickstart", user_agent_overwrite=True)
db = client.get_database_client(DATABASE_ID)
container = db.get_container_client(CONTAINER_ID)
items = list(container.query_items(
query="SELECT l.postcode, l.huisnummer, l.huisletter, l.nummeraanduiding_id as bagid, l.gemeente FROM AdressenLight as l WHERE l.postcode=@postcode AND l.huisnummer=@huisnummer",
parameters=[
{ "name":"@postcode", "value": postcode },
{ "name":"@huisnummer", "value": huisnummer }
]
))
return items
def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
return AsgiMiddleware(app).handle(req, context)
Upvotes: 1
Views: 284
Reputation: 15271
It is official recommendation to reuse clients across function invocations. That keeps number of connections small and calls more efficient.
Please refer to docs: https://learn.microsoft.com/en-us/azure/azure-functions/manage-connections
Upvotes: 1