Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

azure function scale out

Tags:

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.

  1. What can be the reason for this? Why are they not executed parallel?
  2. What hardware is there by default? It is quite slow. Can it be somehow upgraded in Consumption Plan. Why it was not scaled out? Can sg block scale out feature?

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);        

    }

}
like image 754
Zsolt Amschl Avatar asked Dec 02 '16 11:12

Zsolt Amschl


1 Answers

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.

like image 114
Matt Mason Avatar answered Sep 26 '22 16:09

Matt Mason