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

 

後記:

每次碰新的東西,就會踩到新的陷阱,我能做的,也就只有寫出來,讓大家可以快速的踏破這些陷阱,早點避開這些問題而已。

arrow
arrow

    JAVA Programmer 發表在 痞客邦 留言(0) 人氣()