什么是 Serverless
究竟什么是 Serverless?准确回答似乎有些难。但确定无疑的是,让开发者对服务器的感知尽可能少,这是题中之义。
FaaS
最狭义的观点认为,FaaS 才算 Serverless。开发者按云平台的要求用云平台所支持的语言编写函数,并将函数交付给云平台。而云平台依某种条件(事件)——如 MQ 消息、某指标的阈值——调用函数。
这样的函数,往往运行时间短,调用代价低,调用时机规律不明显。而云平台通常按照调用次数和运行时间计费,以达到“用多少付多少”的效果。
Job,App Engine,托管式服务
后来人们发现,上述理念可以推广到 Job 类负载上。
考察一段时间 \(T\),设 \(P_1\) 为某负载的启动时间,\(W\) 为负载真正工作的时间,\(P_2\) 为负载销毁时间,\(m\) 为这段时间内负载的运行次数。
令
并且令
那么可以称 \(\eta\) 为有效时间占比,\(\psi\) 为时间饱和度。\(\eta\) 愈高愈好,而 \(\psi\) 不宜太高,否则经典的常驻型服务会更好。
推广到 Job 的好处是,可以将重负载 Serverless 化。
一个典型的例子是向量数据库的索引训练。数据库在适当的时机调动一批 GPU 或 FPGA 资源训练索引(如 ScaNN,hnsw),训练完毕后执行训练的负载即可退出并释放相应的硬件计算资源。
经实践,由于索引训练不频繁发生,故节省资源效果较好。
此外,经典的 App Engine 也非常符合 Serverless 的理念。开发者只需要编写代码,而负载均衡,自动扩缩,监控告警,日志,以及所依赖的基础软件(infra)全部由云平台负责并精细化计费。
借用 Kubernetes 的语言,App Engine 可以粗略地理解为可以将副本数缩减至零的 Deployment,再辅以云平台托管的数据库、MQ、网关、LB 之类的组件,配合 DevOps,达到代码提交之后全自动的效果。
至此,Serverless 可以粗略认为是 Job + App Engine。:
更广但更虚
还有一种观点认为,不用理会服务器在哪的事物都算 Serverless 的范畴。例如
<script type="text/javascript" src="foo.js"></script>
但这样的理念过于宽泛,难以对工程开发形成指引。
基本共识
好在,共识已经在业界形成。Serverless 在 Job + App Engine 基础上形成了一个“公理化”或“接口化”的定义:
- 几乎不感知服务器
- 自动扩缩,且可以缩减至零
- 精细计费
在企业推广 Serverless
在企业推广 Serverless 有如下几件事要干:
(1)看应用
了解企业内的应用,根据其特点,判断是否应该上 Serverless。有些应用,例如时刻在运行的 Web 后端,不能硬上。
(2)看诉求
看企业是否有省钱的诉求。
有些企业,反而需要把预算花出去;有些企业,稳定性高于一切,不能接受改动。
(3)量化效果
通过 FinOps(至少有个精细化的计费系统),量化引入 Serverless 的效果。
开发指南,零散事项
大部分 Serverless 是基于 Kubernetes 实现的,如 Knative、OpenFaaS。要想比较好地落地 Serverless,有如下事项可以考虑。
(1)调度器配合
由于负载创建销毁频繁,而且负载有轻有重,有的还需要特定硬件,需要对此场景友好的调度策略或调度器。
(2)Wasm 技术方案
如果用 Wasm 实现 FaaS 负载,选择合适的 CRI-runtime 和 OCI-runtime,并引入对应的 Wasm 技术方案。
常见的有:
- SpinKube:简单,落地快。
- Knative + WasmEdge:如果已经有或决定引入 Knative,那么这种更合适。
(3)数据库
如果有条件,使用对 Serverless 友好的数据库。例如,类似于 DynamoDB 的东西。