AWS Lambda 使用的反馈(二)
最近公司的AWS越用越凶,之前用AWS是为了做网站,慢慢地,用AWS是为了大数据,
这次也是AWS的Lambda与大数据的Kinesis结合,因此也踩了不少陷阱,下方来谈谈这次遇到的事。
情境:
有一堆资料会送从公司送到AWS的Kinesis,然后会触发Lambda去处理这些资料,将资料解析后,储存到Database;
这部份全程没有使用Kinesis的Firehouse,而是由Kinesis直接到Lambda;另外,为了出问题能通知,所以配合CloudWatch的监控与寄信的功能。
问题:
因为要搭配CloudWatch的监控,所以我们使用的是由CloudWatch监控Lambda的错误,如下图:
只要Lambda出错,CloudWatch就能得知,后续由CloudWatch触发SNS的发信通知。
想像是如此的美好...实作时就遇到问题了。
首先为了让Lambda出错时,能把一些相关的资讯写到Log去进行Debug,所以必须要try-catch起来,最后再丢出RuntimeException,
这样就可以看到Lambda上的图表出现错误讯息,实测时,信也的确收到了,但是Log却是一直跑不停,Lambda一直被触发。
当时也确认并没有其他同事在丢资料,所以...陷阱1出现了,原因:(参考网页)
换句话说,我们为了触发CloudWatch的寄信功能,必须要丢错误出来,但是Lambda在处理Kinesis的资料时,若出现错误则会重新来一次,
直到这笔资料过期为止,根本就是无穷回圈嘛...
解法方法:
在Kinesis与原本的Lambda间,再插入一支Lambda。
原架构:
Kinesis → Lambda
修改后的架构
Kinesis → Lambda(一) → Lambda(二)
Lambda(一)承接Kinesis的资料,并用try-catch包住,让其永远不会出错, Lambda(二)等同原架构的Lambda,不过承接的不是Kinesis而是Lambda,
而CloudWatch监控 Lambda(二),因为 Lambda(二)承接的不是Kinesis而是Lambda,所以即使丢出错误,也不会重试该笔资料,不过原本是一支Lambda的金额,变成二支了,
为了省一些经费,最好改为非同步呼叫(InvocationType),这样可以减少第一支Lambda的执行时间。
改成新架构后,总算越过陷阱1,但是AWS可不会那么简单放过你;当然,陷阱2是紧跟在后的,陷阱2的问题是因为我们更动了架构才会出现的。
原架构:
Kinesis(同步呼叫) → Lambda
修改后的架构
Kinesis(同步呼叫) → Lambda(一)(非同步呼叫) → Lambda(二)
也就是说原架构的Lambda,在新架构的时候,由原本的同步呼叫,变为非同步呼叫了,这二者的差别在于Payload(送到Lambda处理的内容)的限制不同(参考网址):
由官网可看出,Payload由原本的6MB变成了128KB...,这是故意的吗?一定是故意的吧...
根据这个限制,我们可以在新架构的Lambda(一),找到出问题的Log(因为在try-catch里,所以要印出来)。
解法方法:
因为Lambda(一)是由我们控制的,但是可以控制丢到Lambda(二)的Payload大小,请在Lambda(一)写出计算Payload大小的程式,并控制其不要超出限制。
后记:
每次碰新的东西,就会踩到新的陷阱,我能做的,也就只有写出来,让大家可以快速的踏破这些陷阱,早点避开这些问题而已。