最近公司的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大小的程式,并控制其不要超出限制。

 

后记:

每次碰新的东西,就会踩到新的陷阱,我能做的,也就只有写出来,让大家可以快速的踏破这些陷阱,早点避开这些问题而已。

相关文章