Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serverless in the Wild: Characterizing and Optimizing the Serverless Workload at a Large Cloud Provider #12

Open
linxuyalun opened this issue May 8, 2021 · 4 comments
Labels
done Finish reading serverless Papers about serverless

Comments

@linxuyalun
Copy link
Owner

USENIX'20

https://www.usenix.org/conference/atc20/presentation/shahrad

@linxuyalun linxuyalun added serverless Papers about serverless wip Read in progress labels May 8, 2021
@linxuyalun
Copy link
Owner Author

linxuyalun commented May 9, 2021

这篇文章主要两个个点:

  1. 对 serverless workload 进行表征分析;
  2. 提出了一个动态策略来管理 serverless keep-alive 从而更好的避免 function 的冷启动。

@linxuyalun
Copy link
Owner Author

FaaS Workloads Data

看一下其中一个的重点,serverless 的数据分析。

首先,所有的数据都可以在 https://github.com/Azure/AzurePublicDataset 下载到,这方便后续相关实验的复现和自己的研究。数据来源自整个 azure FaaS 大约两周的数据。

Functions

image

大约 50% 的 app 只有一个 function,大约 95% 的 app 不超过 10 个 function,只有 0.04% 的 app 有超过 100 个 function

Invocation Patterns

函数的调用情况同样非常值得研究。下图展现了平台上每小时调用量。

image

有明显的昼夜模式和每周模式(7月20日、21日、27日和28日是周末),还有一个不变的基线,即大约50%的调用量没有显示出变化。

image

图上 a 展示了平均每天调用次数的 CDF,不同 app 和函数在调用次数上有 8 个数量级的差异,绝大多数 app 和函数调用次数都很低,45% 每小时被调用一次一下,81% 的函数每分钟被调用一次一下。这表明相比于总执行计费时间,keep alive 的代价其实很高。图 b 则表达了最受欢迎的函数/应用在全部调用的占比,橙色阴影区域中的应用是 18.6% 最受欢迎的,那些平均每分钟至少被调用一次的应用,它们占所有函数调用的99.6%。

Inter-arrival Time Variability

抵达时间的差异性,简称 IAT。用 CV 衡量该指标,CV 为标准偏差除以平均值。因此如果是一个定时任务,那么 CV 为 0,下图为数据结果。

image

它表明,真正的 IAT 分布比简单的周期性分布复杂得多。例如,只有 50% 的只有定时器触发函数的应用程序的 CV 为0。具有不同周期的多个定时器将增加 CV 值。对于至少有一个定时器的应用,这个比例低于 30%,而在所有的应用中,这个比例是 20%。有趣的是,10% 没有定时器的应用程序的 CV 接近0,这意味着它们是相当周期性的,应该是可预测的。一方面,只有一小部分应用的 CV 值接近于 1,这意味着简单的泊松到达不是常态。这些结果表明,有相当一部分应用程序应该具有相当可预测的 IAT,即使它们没有定时器触发器。同时,对于许多应用来说,预测 IAT 并不是一件小事。

Function Execution Time

image

50% 的函数平均执行时间小于1s,50% 的函数最大执行时间短于 ∼3s;90% 的函数最多花 60s,96% 的函数平均花不到 60s。

这里面核心说明的一点是,函数的执行时间与冷启动时间处于同一数量级。

Takeaways

  • 绝大多数函数的执行时间为几秒钟,75% 的函数的最大执行时间为10秒,因此执行时间与函数冷启动的时间处于同一等级。因此,减少冷启动的次数或使冷启动大大加快是至关重要的;
  • 第二,绝大多数应用程序的调用频率很低,81% 的应用程序平均每分钟最多调用一次。同时,只有不到 20% 的应用程序对 99.6%的调用负责。因此,就内存占用而言,让那些不经常被调用的应用程序一直保持驻留是很昂贵的;
  • 第三,许多应用程序的 IATs 显示出广泛的变化性,其中 40% 的 IATs 的 CV 值高于 1,因此预测下一次调用的任务可能具有挑战性,特别是对于不经常调用的应用程序。

@linxuyalun
Copy link
Owner Author

Histogram Policy

Histogram Policy 不是我这里的重点,这里简单介绍给一个大致的思路。混合直方图的目的是为了减少冷启动的次数从而减少资源浪费。

对于 keep alive 为 10 分钟的情况,下面这种调用可以让它保持 warm

image

但是如果调用周期刚好是 11 分钟的周期,那么这种方法每次都调用都会有冷启动。

对此,混合直方图策略提出了两个窗口:

  • Pre-warming window:自上次调用后,策略期待下一次调用的等待时间;
  • Keep-alive window:函数被执行后,keep-alive 的时间。

显然 keep-alive window 增加可以增大函数 warm start 的概率,但是这种方式过于浪费资源;如果 pre-warming window 为 0,keep-alive window 为 ∞,则表示函数永远保持 warm。

混合直方图策略的宏观思想是,每个应用/函数,都有一个自己的 pre-warming window 和 keep-alive window。当一个函数被调用后,立即卸载这个函数。然后,根据 pre-warming window 的时间等待一段时间后启动这个函数,然后这个函数处于一直等待调用的状态,直到等待时间超过 keep-alive window 或者函数被调用。

举个例子,如下图:

image

  • 顶部的情况为 pre-warm 为 0,函数调用后,函数不被卸载,继续保持,因此后续调用都是 warm start;
  • 中间为一个理想的情况,在经过 pre-warm 这段时间后,函数被启动,然后这中间发生了调用,是一次 warm-start,函数执行完后被卸载,同时开始新的 pre-warm 计数;
  • 底部为一个反面例子,函数在 pre-warm 期间发生了调用,是一次冷启动。函数执行完后重新开始计时 pre-warm,然后 keep-alive。keep-alive 期间没有发生调用,函数被卸载,重新进入 pre-warm 计时,但是此处又发生了调用,再次触发冷启动。

那么这两个 window 是怎么得到的呢?实际上论文是一种混合策略,包含了各种 corner case,但是本文只针对核心 general 的部分。

image

如图,根据每次调用的间隔,生成一个直方图,然后其中 5% 的部分,计算所得时间为 pre-warm,而 99% 的时间则计算为 keep-alive。

@linxuyalun linxuyalun added done Finish reading and removed wip Read in progress labels May 13, 2021
@chatiti
Copy link

chatiti commented Jan 10, 2024

Hello, I'm very sorry to disturb you. I don't quite understand a certain point in the Histogram Policy section when reproducing the article, which is whether it counts idle time in units of a function or specific instances of a function. That is to say, it counts the time from when the function has no instances at all until the next instance, or from when each instance ends running until the next request is received. If it is the latter, should the function be kept from being destroyed during data collection?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
done Finish reading serverless Papers about serverless
Projects
None yet
Development

No branches or pull requests

2 participants