We tested the scaleout feature of Azure Functions with a more heavyweight console app, with HTTP trigger, and Consumption Service Plan. So we expected a parallel execution with scale out. We execute the console app in a new AppDomain, because funcion instances are running in the same process. In the console app we do sqlite database operations on an in memory db.
First we executed the function only 1 time, and measured the execution time. Let it be x :) We initiated continuously an increased number of parallel threads. We experienced that the execution time of 1 function app instance in these cases was x * num_of_threads. So as if the function instances would have been serialized and not executed parallel.
Thanks for you help.
EDIT: The basic source code of my app:
using System.Net;
using System;
public static HttpResponseMessage Run(HttpRequestMessage req, TraceWriter log, ExecutionContext context)
{
string testThreadId = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "id", true) == 0)
.Value;
var funcId = context.InvocationId.ToString();
var homePath = Environment.GetEnvironmentVariable("HOME");
var folderName = Path.Combine(homePath,@"site\wwwroot\JanoRunTime2");
var fileName = Path.Combine(folderName,"AzureFunctionTest.exe");
var configFile = Path.Combine(folderName,"AzureFunctionTest.exe.config");
var setup = new AppDomainSetup();
setup.ApplicationBase = folderName;
setup.ConfigurationFile = configFile;
var newDomain = AppDomain.CreateDomain("JanoTestExecutorDomain_" + funcId, null, setup );
try{
newDomain.ExecuteAssembly(fileName, new []{testThreadId, funcId});
return req.CreateResponse(HttpStatusCode.OK );
}
catch(Exception e){
return req.CreateResponse(HttpStatusCode.InternalServerError);
}
finally{
AppDomain.Unload(newDomain);
}
}
The requests are executed in parallel, but there are differences based on language (node is single-threaded, for example). If you want some workloads to verify parallel execution and scaling there is a github of solutions you can deploy here.
Your function will scale to more instances under a few conditions, but the most relevant is throughput: Azure Functions track how many requests are completed per unit time and scale up if that number drops. Here is some info on how the consumption plan works.
As for the hardware, the idea of Functions and serverless computing is to remove that consideration from the developer. A function 'instance' can be thought of as a unit of compute with 1.5GB of memory. If you want more control over hardware you can always run functions in an app service plan.
It's possible that you're seeing this 'serialized' behavior because of your workload. If you kick off a CPU dependent workload in an entirely new AppDomain and return, the function may not track that you are still doing work. In this case you could max out CPU without hitting that throughput scaling condition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With