Azure功能在扩展之前需要冷却多长时间?

问题描述 投票:2回答:2

在我们的开发环境中,我们的功能应用程序通常只需要几台服务器。

在周末,我们意外地引发了连锁反应,导致逐步,持续扩展到大约140台服务器。现在我们已经修复了底层问题并清除了队列,活动似乎已恢复正常。 (唷!)

奇怪的是(30分钟后)我们仍然拥有所有这些服务器在线。我希望他们能够很快开始下线,但我看到“在线服务器”的数量在大约110到140之间波动(上升和下降)。其中绝大多数都坐在那里0个请求/秒,没有CPU,没有内存。

所以,有些问题:

  • 这是预期的吗?
  • 引导/保持在线服务器数量的启发式方法是什么?
  • 我什么时候应该看到这个数字下降到我以前的水平?
azure-functions scaling serverless
2个回答
2
投票

只是添加一些@Mikhail所写的内容 - 你的函数比例如何取决于所用触发器的类型。如果使用队列,运行时将查看队列长度并根据消息数量向上/向下扩展。使用Event Hub,这种行为取决于集线器中的分区数量 - 您拥有的越多,就越渴望扩展您的功能。

可以查看源代码并尝试理解至少部分功能。实际上,它基于计时器和工作者的概念,它们更新状态并让运行时决定是否需要向上或向下扩展。

整体算法描述如下:

protected virtual async Task MakeScaleDecision(string activityId, IWorkerInfo manager)
{
    if (DateTime.UtcNow < _scaleCheckUtc)
    {
        return;
    }

    try
    {
        var workers = await _table.ListNonStale();
        _tracer.TraceInformation(activityId, manager, workers.GetSummary("NonStale"));

        if (await TryRemoveIfMaxWorkers(activityId, workers, manager))
        {
            return;
        }

        if (await TryAddIfLoadFactorMaxWorker(activityId, workers, manager))
        {
            return;
        }

        if (await TrySwapIfLoadFactorMinWorker(activityId, workers, manager))
        {
            return;
        }

        if (await TryAddIfMaxBusyWorkerRatio(activityId, workers, manager))
        {
            return;
        }

        if (await TryRemoveIfMaxFreeWorkerRatio(activityId, workers, manager))
        {
            return;
        }

        if (await TryRemoveSlaveWorker(activityId, workers, manager))
        {
            return;
        }
    }
    catch (Exception ex)
    {
        _tracer.TraceError(activityId, manager, string.Format("MakeScaleDecision failed with {0}", ex));
    }
    finally
    {
        _scaleCheckUtc = DateTime.UtcNow.Add(_settings.ScaleCheckInterval);
    }
}

更重要的是,你可以在源代码中找到为什么你看到活着的工人的答案:

protected virtual async Task PingWorker(string activityId, IWorkerInfo worker)
{
    // if ping was unsuccessful, keep pinging.  this is to address
    // the issue where site continue to run on an unassigned worker.
    if (!_pingResult || _pingWorkerUtc < DateTime.UtcNow)
    {
        // if PingWorker throws, we will not update the worker status
        // this worker will be stale and eventually removed.
        _pingResult = await _eventHandler.PingWorker(activityId, worker);

        _pingWorkerUtc = DateTime.UtcNow.Add(_settings.WorkerPingInterval);
    }

    // check if worker is valid for the site
    if (_pingResult)
    {
        await _table.AddOrUpdate(worker);

        _tracer.TraceUpdateWorker(activityId, worker, string.Format("Worker loadfactor {0} updated", worker.LoadFactor));
    }
    else
    {
        _tracer.TraceWarning(activityId, worker, string.Format("Worker does not belong to the site."));

        await _table.Delete(worker);

        _tracer.TraceRemoveWorker(activityId, worker, "Worker removed");

        throw new InvalidOperationException("The worker does not belong to the site.");
    }
}

不幸的是,实现的某些部分是密封的(如IWorkerInfo),所以你无法得到全貌,我们只能猜测(或问;))


1
投票

Scale Controller是一种具有无证行为的封闭源专有技术。您的问题没有正式答案。回答它的唯一方法就是做你做的事:运行实验和测量。但是,这种行为可能会随着时间的推

函数确实具有一些启发式,可以根据平均数量和资源利用率进行扩展以及何时扩展。在过去,他们非常节俭,但没有提供足够好的扩展速度。现在,他们倾向于错误配置太多而不是太少。

好消息是除了出于好奇之外,你不应该真正关心扩展。您不需要为空闲服务器付费。

© www.soinside.com 2019 - 2024. All rights reserved.