Serverless性能优化
Serverless函数配置最佳实践
- 运行时语言
当选择编译型语言(如Java,C#等),冷启动时延一般由于首次初始化消耗比较大会导致冷启动时延偏高,但是初始化完成后每次执行的时延相较其他解释型语言(NodeJs,Python等)会有一定优势。如果流量不均衡,且对冷启动时延或者最大时延有一定要求的业务使用NodeJs, Python等运行时语言,如果流量比较均衡或者对最大时延不敏感,但是对平均时延敏感的业务选择Java,Go等编译型语言。
- 内存规格
函数Pod中分配的CPU资源与内存规格成正比,所以更大的内存规格可以获得更高的CPU资源从而提升执行性能。如果业务场景为CPU密集型或者需要大量使用内存的,建议配置更大的内存规格来获取更低的执行时延,可以通过配置不同大小内存进行性能测试,观察时延监控结合业务实际预算选择合适的内存规格。
同时如果同一个函数在不同场景下对内存和CPU资源的要求不一样,可以使用动态内存能力,参考配置动态内存。
- 最大实例数
如果函数执行并发量较大,那么默认的最大实例数可能不足以支撑业务调用,如果超出最大实例数对应的处理能力,可能造成执行排队时延升高,甚至出现报错。建议最大实例数和业务实际最大并发数保持一致。
- 预留实例数
预留实例是将函数实例的创建和释放交由用户管理,当您为某一函数创建了预留实例,函数工作流收到此函数的调用请求时,会优先将请求转发给您的预留实例,当请求的峰值超过预留实例处理能力时,剩余部分的请求将会转发给按量实例,由函数工作流自动为您分配执行环境。如果业务流量不均衡,存在波峰波谷情况,且对冷启动时延有要求的可以结合实际预算配置一定数量预留实例,同时,如果业务波峰波谷存在周期规律的,也可以配置预留实例的定时伸缩和智能预测弹性策略,提升资源利用率,减少资源浪费。参考预留实例管理。
网络配置
公网访问:函数提供了公网访问能力,但是函数提供的公网出口带宽有限,且所有租户共享,只适合对带宽、可靠性要求较低的测试业务使用。
VPC访问:函数提供了指定VPC访问的能力,但在冷启动时会初始化到该VPC网络的网络链路造成额外的冷启动时延。
如果需要访问公网,且对带宽有要求的生产业务可以通过配置绑定了NAT网关的VPC来访问公网;如果函数没有网络访问场景的,不建议配置VPC。
参考配置网络。
- 超时时间
如果函数配置的超时时间比较长的话,且函数代码中发生异常导致阻塞,函数同步调用会等待直到超出超时时间才返回超时异常,造成业务卡顿,长时间不退出等问题,无法实现failfast,影响业务体验。建议结合业务实际场景配置超时时间,避免超时时间配置过大。
Serverless函数代码最佳实践
如果业务可以异步实现,那么不需要关心函数的性能(除了优化成本之外)。FunctionGraph函数的性能很大程度上取决于需要FunctionGraph函数执行何种逻辑。
策略:
- 正确的使用连接池,保持连接存活并重用在上一次调用中建立的连接(HTTP,数据库、redis等)。
- 通过接口调用FunctionGraph函数时,建议客户端维护http连接池,减少http连接初始化时间。
- 避免在每次调用时重新初始化变量对象(使用全局静态变量、单例等)。
- 选择解释性语言(nodejs、python)而不是编译型语言(java、go)。
- 精简函数代码包,满足其运行时需要即可。 这将大辐减少在调用前从华为云 OBS下载代码包所花费的时间。
- FunctionGraph函数调用华为云其他云服务资源时(例:dis、obs),如果选择对应云服务sdk,需要对sdk参数进行调优(例:超时时间、连接数、重试次数等)。
- FunctionGraph函数中访问第三方服务或华为云服务时,性能上限受第三方服务或华为云服务的性能上限制,需要确保访问的服务无性能瓶颈。
冷启动优化实践
Serverless按用付费、自动弹性伸缩、屏蔽复杂性等特征使其逐渐成为下一代云计算新范式。但是在Serverless架构带来极大便利的同时,在实时性要求较高的应用场景下,冷启动将是面临的一个挑战。当使用serverless构建 Web 服务时,冷启动和Web服务初始化时间一共超过了5秒钟,那么无疑将会使用户体验大打折扣,因此设法减少冷启动时间,提高终端用户的使用体验,是构建无服务器架构时亟待解决的问题。
Serverless实例的生命周期可以分为三个阶段:初始化阶段、执行阶段、关闭阶段。
当触发FunctionGraph时,若当前没有处于激活阶段的函数实例可供调用,则会下载函数的代码并创建一个函数的执行环境。从事件触发到新的FunctionGraph环境创建完成这个周期通常称为 冷启动时间。在serverless架构中,冷启动问题是无法避免的。
目前FunctionGraph已经对系统侧的冷启动做了大量优化,针对用户侧参考以下方案。:
- 选择合适的编程语言
目前FunctionGraph支持的编程语言(Runtime)有 .NET Core、Go、Java、Node.js、Python。在默认 512MB 内存的情况下,我们创建不同语言的函数,做一个冷启动时间横向的测试和比较。各个语言的冷启动时间为JAVA>GO>.NET>Node.js>Python。
- 选择合适的内存
在请求并发量一定的情况下,函数内存越大,分配的CPU资源相应越多,一般冷启动表现越优。
- 快照冷启动
Java应用冷启动速度慢的问题尤为突出。华为云FunctionGraph创新提出的基于进程级快照的冷启动加速解决方案,致力于在用户无感知(无需/少量进行代码适配)的前提下,帮助用户突破冷启动的性能瓶颈。本优化方案直接从应用初始化后的快照进行运行环境恢复,跳过复杂的框架、业务初始化阶段,从而显著降低 Java 应用的启动时延,实测性能提升达90%+。
观测性能指标
为了更好地支持用户使用函数,FunctionGraph提供了一系列指标供用户参考。一旦函数被调用,您可以在函数的监控页面和日志页面查看相应指标的变化,通过FunctionGraph函数的观测能力来进一步优化函数配置和函数代码。
目前,FunctionGraph提供的指标主要分为总览指标和函数指标。详细指标可参考官方指标文档。