是否可以在连接到API网关的Lambda上使用AWS KPL

时间:2017-07-03 09:11:13

标签: amazon-web-services aws-lambda aws-api-gateway amazon-kinesis

我正在尝试在AWS服务之上构建数据收集管道。下面给出了总体架构;

总之,系统应该从API网关(1)获取事件(每个事件一个请求),并且应该将数据写入Kinesis(2)。

我期待每秒约100k个事件。我的问题与Lambda函数的KPL使用有关。在第2步,我计划用KPL编写一个Lambda方法,以高吞吐量在Kinesis上编写事件。但我不确定它是否可能,因为API网关分别为每个事件调用lambda函数。

在这种架构中使用KPL是否可能/合理,或者我应该使用Kinesis Put API?

        1                              2                              3                             4
+----------------+             +----------------+             +----------------+            +----------------+
|                |             |                |             |                |            |                |
|                |             |                |             |                |            |                |
|  AWS API GW    +-----------> |  AWS Lambda    +-----------> |  AWS Kinesis   +----------> |  AWS Lambda    |
|                |             |  Function with |             |  Streams       |            |                |
|                |             |  KPL           |             |                |            |                |
|                |             |                |             |                |            |                |
+----------------+             +----------------+             +----------------+            +-----+-----+----+
                                                                                                  |     |
                                                                                                  |     |
                                                                                                  |     |
                                                                                                  |     |
                                                                                                  |     |
                                                                                5                 |     |              6
                                                                         +----------------+       |     |      +----------------+
                                                                         |                |       |     |      |                |
                                                                         |                |       |     |      |                |
                                                                         |  AWS S3        <-------+     +----> |  AWS Redshift  |
                                                                         |                |                    |                |
                                                                         |                |                    |                |
                                                                         |                |                    |                |
                                                                         +----------------+                    +----------------+

我也在考虑直接写S3而不是从api-gw调用lambda函数。如果第一个架构不合理,这可能是一个解决方案,但在这种情况下,我会有延迟,直到将数据写入kinesis

        1                                2                         3                              4                             5
+----------------+               +----------------+        +----------------+             +----------------+            +----------------+
|                |               |                |        |                |             |                |            |                |
|                |               |                |        |                |             |                |            |                |
|  AWS API GW    +----------->   |  AWS Lambda    +------> |  AWS Lambda    +-----------> |  AWS Kinesis   +----------> |  AWS Lambda    |
|                |               |  to write data |        |  Function with |             |  Streams       |            |                |
|                |               |  to S3         |        |  KPL           |             |                |            |                |
|                |               |                |        |                |             |                |            |                |
+----------------+               +----------------+        +----------------+             +----------------+            +-----+-----+----+
                                                                                                                              |     |
                                                                                                                              |     |
                                                                                                                              |     |
                                                                                                                              |     |
                                                                                                                              |     |
                                                                                                            6                 |     |              7
                                                                                                     +----------------+       |     |      +----------------+
                                                                                                     |                |       |     |      |                |
                                                                                                     |                |       |     |      |                |

2 个答案:

答案 0 :(得分:2)

我不认为使用KPL是正确的选择。 KPL的关键概念是,在客户端收集记录,然后作为批处理操作发送给Kinesis。由于Lambdas每次调用都是无状态的,因此存储聚合记录(在将其发送到Kinesis之前)相当困难。

我认为您应该查看以下AWS文章,该文章解释了如何将API-Gateway直接连接到Kinesis。这样,您就可以避免额外的Lambda,它只是转发您的请求。

Create an API Gateway API as an Kinesis Proxy

答案 1 :(得分:0)

很显然,如果您通过AWS API Gateway传递的数据与一个Kinesis Data Streams记录相对应,那么Jens指出使用KPL是没有意义的。在这种情况下,您可以直接调用Kinesis API,而无需使用Lambda。最终,您可能会在Lambda中使用一些其他处理,并通过PutRecord(而不是KPL使用的PutRecords)发送数据。您在JAVA中的代码将如下所示:

AmazonKinesisClientBuilder clientBuilder = AmazonKinesisClientBuilder.standard();
clientBuilder.setRegion(REGION);
clientBuilder.setCredentials(new DefaultAWSCredentialsProviderChain());
clientBuilder.setClientConfiguration(new ClientConfiguration());
AmazonKinesis kinesisClient = clientBuilder.build();
...
//then later on each record
PutRecordRequest putRecordRequest = new PutRecordRequest();
putRecordRequest.setStreamName(STREAM_NAME);
putRecordRequest.setData(data);
putRecordRequest.setPartitionKey(daasEvent.getAnonymizedId());
putRecordRequest.setExplicitHashKey(Utils.randomExplicitHashKey());
putRecordRequest.setSequenceNumberForOrdering(sequenceNumberOfPreviousRecord);
PutRecordResult putRecordResult = kinesisClient.putRecord(putRecordRequest);
sequenceNumberOfPreviousRecord = putRecordResult.getSequenceNumber();

但是,在某些情况下,使用lambda的KPL是有意义的。例如,发送到AWS API Gateway的数据包含多个单独的记录,这些记录将发送到一个或多个流。在那种情况下,KPL的好处(参见https://docs.aws.amazon.com/streams/latest/dev/kinesis-kpl-concepts.html)仍然有效,但是您必须了解使用Lambda所给出的具体细节,此处https://github.com/awslabs/amazon-kinesis-producer/issues/143指出并使用

kinesisProducer.flushSync() 

在插入结束时也对我有用。