关于serverless:Serverless-应用优化四则秘诀

8次阅读

共计 3451 个字符,预计需要花费 9 分钟才能阅读完成。

简介:Serverless 架构下,尽管咱们更多精力是关注咱们的业务代码,然而实际上对于一些配置和老本也是须要进行关注的,并且在必要的时候,还须要依据配置与老本进行对咱们的 Serverless 利用进行配置优化和代码优化。

Serverless 架构下,尽管咱们更多精力是关注咱们的业务代码,然而实际上对于一些配置和老本也是须要进行关注的,并且在必要的时候,还须要依据配置与老本进行对咱们的 Serverless 利用进行配置优化和代码优化。

资源评估仍旧重要

Serverless 架构尽管是按量付费的,然而并不代表他就肯定比传统的服务器租用费用低,如果咱们对本人的我的项目评估不精确,对一些指标设置不合理,Serverless 架构所产生的费用可能是微小的。

个别状况下,FaaS 平台的免费是和三个指标具备间接关系的:

所配置的内存规格;

程序所耗费的工夫;

以及产生的流量费用。

通常状况下程序所耗费的工夫可能会与内存规格、程序自身所解决的业务逻辑无关。流量费用与程序自身和客户端交互的数据包大小无关,所以在这三个常见的指标,可能因为配置不标准导致计费呈现比拟大偏差的就是内存规格。以阿里云函数计算为例,咱们假如有一个 Hello World 的程序,每天都会被执行 10000 次,能够统计不同规格的实例所产生的费用(不包含网络费用):


阿里云

通过上表能够看到,当程序在 128MB 规格的内存中能够失常执行,如果咱们谬误地将内存规格设置成了 3072MB,可能每月产生的费用将会暴涨 25 倍!所以咱们在上线 Serverless 利用之前,要对资源进行评估,以便失去更正当的配置来进一步升高咱们的老本。

正当的代码包规格

各个云厂商的 FaaS 平台中都对代码包大小有着限度,抛掉云厂商对代码包的限度,单纯地说代码包的规格可能会产生的影响,通过函数的冷启动流程能够看到:

在函数启动的过程中,有一个过程是加载代码的过程,那么当咱们所上传的代码包过大,或者说文件过多导致解压速度过慢,就会间接导致加载代码这个过程变长,进一步间接导致冷启动工夫变久。

能够构想一下,当咱们有两个压缩包,一个是只有 100KB 的代码压缩包,另一个是 200MB 的代码压缩包,两者同时在千兆的内网带宽下理想化(即不思考磁盘的存储速度等)下载,即便最大速度能够达到 125MB/S,那么前者的下载速度只有不到 0.01s,后者须要 1.6s。除了下载工夫之外,还有文件的解压工夫,那么两者的冷启动工夫可能就相差 2s。

个别状况下,一个传统的 Web 接口,如果要 2s 以上的响应工夫,实际上对很多业务来说是不能承受的,所以在咱们打包代码时就要尽可能的升高压缩包大小。以 Node.js 我的项目为例,打包代码包时,能够采纳 Webpack 等办法,来压缩依赖包大小,进一步升高整体代码包的规格,晋升函数的冷启动效率。

正当利用实例的复用

在各个云厂商的 FaaS 平台中,为了更好的解决冷启动的问题,为了更正当的利用资源,是存在“实例”复用状况的。所谓的实例复用,就是当一个实例实现一个申请后并不会开释,而是进入“静默”的状态。在肯定工夫范畴内,如果有新的申请被调配过去,则会间接调用对应的办法,而不须要再初始化各类资源等,这在很大水平上缩小了函数冷启动的状况呈现。为了验证,咱们能够创立两个函数:

函数 1:

# -*- coding: utf-8 -*-

def handler(event, context):
  print("Test")
  return 'hello world'

函数 2:



# -*- coding: utf-8 -*-

print("Test")

def handler(event, context):
  return 'hello world'

咱们在控制台屡次点击“测试”按钮,对这两个函数进行测试,判断其是否在日志中输入了“Test”,咱们能够统计后果:

依据下面的状况,咱们能够看到,其实实例复用的状况是存在的。因为“函数 2”并不是每次都会执行入口函数之外的一些语句。依据“函数 1”和“函数 2”,咱们也能够进一步思考,如果 print(“Test”) 语句是一个初始化数据库连贯,或者是加载一个深度学习的模型,是不是“函数 1”的写法就是每次申请都会执行,而“函数 2”的写法是能够存在复用已有对象的状况?

所以在理论的我的项目中,有一些初始化操作,是能够依照“函数 2”来进行实现的,例如:

  • 机器学习场景下,在初始化的时候加载模型,防止每次函数被触发都会加载模型带来的效率问题,进步实例复用场景下的响应效率;
  • 数据库等链接操作,能够在初始化的时候进行链接对象的建设,防止每次申请都创立链接对象;
  • 其余一些须要首次加载时下载文件,加载文件的场景,在初始化的时候进行这部分需要的实现,能够在实例复用的时候效率更高;

长于利用函数个性

各个云厂商的 FaaS 平台都有一些“平台个性”,所谓的平台个性,是指这些性能可能并不是《CNCF WG-Serverless Whitepaper v 1.0》中规定的能力,或者形容的能力,仅仅是作为云平台依据本身业务倒退和诉求,从用户角度登程开掘进去,并且实现的性能,可能只在某个云平台或者某几个云平台所领有的性能。这类性能个别状况下如果利用切当会让咱们的业务性能等有质的晋升。

1、Pre-freeze & Pre-stop

以阿里云函数计算为例,在平台倒退过程中,用户痛点(尤其是传统利用平滑迁徙至 Serverless 架构)如下:

  • 异步背景指标数据提早或失落:如果在申请期间没有发送胜利,则可能被提早至下一次申请,或者数据点被抛弃。
  • 同步发送指标减少提早:如果在每个申请完结后都调用相似 Flush 接口,不仅减少了每个申请的提早,对于后端服务也产生了不必要的压力。
  • 函数优雅下线:实例敞开时利用有清理连贯,敞开过程,上报状态等需要。在函数计算中实例下线机会开发者无奈把握,也短少 Webhook 告诉函数实例下线事件。

依据这些痛点公布了运行时扩大(runtime extensions)性能。该性能在现有的 HTTP 服务编程模型上扩大,在已有的 HTTP 服务器的模型中减少了 PreFreeze 和 PreStop webhooks。扩大开发者实现 HTTP handler,监听函数实例生命周期事件,如下图所示:

PreFreeze:在每次函数计算服务决定冷冻以后函数实例前,函数计算服务会调用 HTTP GET /pre-freeze 门路,扩大开发者负责实现相应逻辑以确保实现实例冷冻前的必要操作,例如期待指标发送胜利等。函数调用 InvokeFunction 的工夫不包 PreFreeze Hook 的执行工夫。

PreStop:在每次函数计算决定进行以后函数实例前,函数计算服务会调用 HTTP GET /pre-stop 门路,扩大开发者负责实现相应逻辑以确保实现实例开释前的必要操作,如敞开数据库链接,以及上报、更新状态等。

2、单实例多并发

家喻户晓,各个厂商的函数计算通常是申请级别的隔离,即当客户端同时发动 3 个申请到函数计算,实践上会产生三个实例来进行应答,这个时候可能会波及到冷启动问题,可能会波及到申请之间状态关联问题等,然而局部云厂商提供了单实例多并发的能力(例如阿里云函数计算),该能力容许用户为函数设置一个实例并发度(InstanceConcurrency),即单个函数实例能够同时解决多少个申请。

如图下图,假如同时有 3 个申请须要解决,当实例并发度设置为 1 时,函数计算须要创立 3 个实例来解决这 3 个申请,每个实例别离解决 1 个申请;当实例并发度设置为 10 时(即 1 个实例能够同时解决 10 个申请),函数计算只须要创立 1 个实例就能解决这 3 个申请。


单实例多并发成果简图

单实例多并发的劣势如下:

  • 缩小执行时长,节俭费用。例如,偏 I / O 的函数能够在一个实例内并发解决,缩小实例数从而缩小总的执行时长。
  • 申请之间能够共享状态。多个申请能够在一个实例内共用数据库连接池,从而缩小和数据库之间的连接数。
  • 升高冷启动概率。因为多个申请能够在一个实例内解决,创立新实例的次数会变少,冷启动概率升高。
  • 缩小占用 VPC IP 在雷同负载下,单实例多并发能够升高总的实例数,从而缩小 VPC IP 的占用。

单实例多并发的利用场景是比拟宽泛的,例如函数中有较多工夫在期待上游服务的响应的场景就比拟适宜应用该种性能,然而单实例多并发也并不适宜全副利用场景,例如当函数中有共享状态且不能并发拜访的场景,单个申请的执行要耗费大量 CPU 及内存资源的场景,就不适宜应用单实例多并发这个性能。

原文链接
本文为阿里云原创内容,未经容许不得转载。

正文完
 0