l 如果某个AZ发生故障,则其他AZ需要被分配足够的IP地址,来处理并发的Lambda请求。(注意,每个Lambda的执行都需要有一个私有的IP地址,来处理请求。)因此,我们需要在子网中分配足够多的IP地址,是达到HA。 并发性
虽说AWS Lambda会以自己的方式来实现可伸缩性,但是对于有限的资源而言,Lambda会遵循如下的并发执行限制:
l 帐户级别 - 默认情况下,它会参照每个区域内的所有函数,将该值定为1000。
l 函数级别 - 默认情况下,它会使用“Unreserved Account Concurrency limit”,但是这并不是一种很好的实现方式。为了避免耗尽所有帐户级别的并发数,它会限制其他的功能函数。因此,我们应该为每一个函数保留单独的并发数,以便在事件数量因为某种原因出现激增时,仅影响并隔离在该函数之中。
注意 - AWS始终保留一个具有至少100个并发执行量的无保留并发池(unreserved concurrency pool),以处理那些未做特殊设置的函数请求。也就是说,您最多只能分配900个。 如果我们是在一个专有的VPC上运行Lambda呢?
在这种情况下,我们需要根据函数的ENI(Elastic Network Interfaces,弹性网络接口)扩展性,去请求足够多的IP地址。您可以使用如下公式来估算ENI的近似容量: Concurrent executions * (Memory in GB / 3 GB)
其中:
l 并发执行 - 是工作负载的预计并发数(用每秒调用次数*平均执行的时长,以秒为单位)。
l 内存大小 - 是为Lambda函数配置的内存数量(以GB为单位)。
在设计Lambda的并发性时,我们还应该始终考虑,诸如DynamoDB、RDS等其他集成服务的限制。我们需要根据这些服务能够处理的最大连接,来调整函数的并发限制。 节流
正如前文在“并发性”中提到的,一旦函数事件出现激增,并超过了并发数的限制,那么Lambda将无法再处理任何新的请求。如果我们不及时予以处理的话,业务系统就会受到影响。
l 如果Lambda的调用是同步模式的话,它会马上接收到429类型的错误代码。同时,如果节流被设定为函数级别或是帐户级别,那么它还能接收其他一些信息。因此,诸如API网关之类的调用服务,则需要处理此类重试问题。
l 如果Lambda的调用是异步模式的话,Lambda只会在丢弃事件之前尝试两次。因此,如果函数无法处理该事件,我们就应该使用SQS或SNS所定义的DLQ(Dead Letter Queue),来做稍后调试与处理。而如果我们忘记了定义DLQ,那些消息则会被直接丢弃掉。
l 如果Lambda调用是基于轮询模式的话,我们进一步细分两种情况:
n 如果是流式(Kinesis),它将继续重试,直到超时(最多为7天)。
n 如果是非流式(SQS),它将把消息放回到队列之中,并仅在Visibility时限到期后才开始重试,并持续执行下去,直到它能够成功地完成处理、或是超过保留期。