开源的Serverless核心特点

柏舟   新冠4年 08-15

Serverless是一种云原生开发模型,允许开发人员构建和运行应用程序而无需管理(物理)服务器。目前开源的Serverless方案有Knative, Openfaas, fission, kubeless等。我发现,目前开源的Serverless有以下几个特点:

函数的拓扑结构

  1. Http的同步响应模型,请求一定是双向的,发送和回复都可以有数据。
  2. 异步的消息队列模型,一个队列对应多个消费者。常用于缓存削锋。
  3. 流处理模型,根据key进行分区,每个分区对应不同的消费者。常用于数据并行处理。
  4. 定时队列。

单独强调这个是为了说明Serverless支持丰富的模型,并且(knative)能够一定程度上兼容现有的系统。

Serverless组件和功能简单介绍

以knative为例,Serverless一般存在以下组件:

不管是那种Serverless方案,运行的服务都是以Server/Deployment的方式提供服务,而不是以Job的形式提供服务——处理完请求就销毁了。此外,事件的来源不仅包括外部来的流量,也包括git、kubernetes事件等等。

区别1:接口和事件传递

这些开源的框架都提供函数和Http Server的方式:

module.exports = function(context, callback) {
    callback(200, "Hello, world callback!\n");
}
[HttpPost]
public async Task<IActionResult> Post([FromBody] CloudEvent receivedEvent) {
    try {
        if (string.IsNullOrEmpty(SinkUri.Value)) {
            return this.ReceiveAndReply(receivedEvent);
        } else {
            return await this.ReceiveAndSend(receivedEvent);
        }
    } catch (JsonException) {
        return this.BadRequest("Failed to read the JSON data.");
    }
}

区别2:构建

构建有两种方式,第一种是部署前构建镜像,编写对应的yaml;第二种是直接上传源代码和配置文件,运行时动态生成执行文件运行。

第一种一般支持镜像和函数两种方式:

Fission

Fission的集群中包含很多各种语言的通用env镜像。当需要开启服务时, 它会拉取volume的代码到配置的位置,运行函数,修改pod标签为一种特化的镜像。由于通用镜像数量变少了,k8s会自动重启一个通用镜像,恢复到指定的状态。

感受

开源的Serverless主要干了两件事,基于事件的调度和制定了构建方案。其实就我个人而言,我开始以为Serverless是类似于lambda的东西,但并不完全是这样。说回Serverless的初衷,微服务和云计算从最初的IaaS到SaaS、BaaS到FaaS,整体的思路就是聚焦到最核心的业务,将底层基础设施、不同数据存储和接入全部托管出去,然后整个开发流程标准化。

这和几年前中台的思路并没有大的区别,只是Serverless更侧重基础设施,提供更具有弹性的部署方式。我觉得Serverless还非常不成熟:从零启动非常复杂,还需要各种镜像配合使用,我个人认为不可靠。而且这个概念也不是很新的概念,像Flink这些大数据引擎,很早就支持动态上传代码(JAR)执行,这不比冷启动强多了?唯一的问题可能是不支持Serverless这么多拓扑模型,只能用于大数据。

Serverless的概念本身没有什么问题,问题就是docker、k8s这一套并没有简化linux的复杂性,并且在此基础上有引入了额外的复杂度,特别是网络和可调试性。这一套东西最初兴起的原因是在linux的namespace和cgroup的隔离性基础上引入了Docker分层镜像构建方式,并且有Dockerhub大大简化了集群的运维和部署。

可是为什么要使用集群呢?现在常见的并行并发模型有:

现实有各种物理的原因限制了模型的扩展性。而编程语言的模型有什么问题呢?现在广泛使用的通用语言都是顺序执行的,而申明式语言如SQL虽然很容易优化但是使用范围受限。我认为一个理想的框架是编写一套代码,编译器可以自动并行优化和集群部署,并且还支持本地调试。但我又仔细想想,我发现这东西跟MapReduce差不多。

唉,有的时候不得不接受现实的不完美,可能开发一个复杂系统就是一件复杂的事情。