Amazon web services 在Kinesis中使用分区键以确保具有相同键的记录由相同的记录处理器(lambda)处理
我正在使用AWS kinesis和lambda开发一个实时数据管道,我正在尝试找出如何保证来自相同数据生产者的记录由相同的碎片处理,最终由相同的lambda函数实例处理 我的方法是使用分区键来确保来自相同生产者的记录由相同的碎片处理。但是,我无法让来自同一个碎片的记录由同一个lambda函数实例处理 基本设置如下所示:Amazon web services 在Kinesis中使用分区键以确保具有相同键的记录由相同的记录处理器(lambda)处理,amazon-web-services,aws-lambda,amazon-kinesis,Amazon Web Services,Aws Lambda,Amazon Kinesis,我正在使用AWS kinesis和lambda开发一个实时数据管道,我正在尝试找出如何保证来自相同数据生产者的记录由相同的碎片处理,最终由相同的lambda函数实例处理 我的方法是使用分区键来确保来自相同生产者的记录由相同的碎片处理。但是,我无法让来自同一个碎片的记录由同一个lambda函数实例处理 基本设置如下所示: 有多个数据源将数据发送到动觉流 流有多个碎片来处理负载 有一个lambda函数通过事件源映射(批大小为500)连接到CREAR lambda函数正在处理记录,进行一些数据转换和
- 有多个数据源将数据发送到动觉流
- 流有多个碎片来处理负载
- 有一个lambda函数通过事件源映射(批大小为500)连接到CREAR
- lambda函数正在处理记录,进行一些数据转换和其他一些操作,然后将所有内容放入firehose
- 以后还会发生更多的事情,但这与问题无关
{'type': 'c', 'source': 100, 'id': 200, 'data': 'ce', 'partitionKey': '100'}
{'type': 'c', 'source': 100, 'id': 200, 'data': 'ce', 'partitionKey': '100'}
{'type': 'c', 'source': 103, 'id': 207, 'data': 'ce2', 'partitionKey': '103'}
{'type': 'c', 'source': 100, 'id': 200, 'data': 'ce', 'partitionKey': '100'}
{'type': 'c', 'source': 103, 'id': 207, 'data': 'ce2', 'partitionKey': '103'}
{'type': 'c', 'source': 101, 'id': 204, 'data': 'ce4', 'partitionKey': '101'}
{'type': 'c', 'source': 101, 'id': 205, 'data': 'ce5', 'partitionKey': '101'}
{'type': 'c', 'source': 101, 'id': 205, 'data': 'ce5', 'partitionKey': '101'}
Lambda实例2:
{'type': 'c', 'source': 101, 'id': 201, 'data': 'ce1', 'partitionKey': '101'}
{'type': 'c', 'source': 102, 'id': 206, 'data': 'ce1', 'partitionKey': '102'}
{'type': 'c', 'source': 101, 'id': 202, 'data': 'ce2', 'partitionKey': '101'}
{'type': 'c', 'source': 102, 'id': 206, 'data': 'ce1', 'partitionKey': '102'}
{'type': 'c', 'source': 101, 'id': 203, 'data': 'ce3', 'partitionKey': '101'}
Lambda实例3:
{'type': 'c', 'source': 100, 'id': 200, 'data': 'ce', 'partitionKey': '100'}
{'type': 'c', 'source': 100, 'id': 200, 'data': 'ce', 'partitionKey': '100'}
{'type': 'c', 'source': 101, 'id': 201, 'data': 'ce1', 'partitionKey': '101'}
{'type': 'c', 'source': 101, 'id': 202, 'data': 'ce2', 'partitionKey': '101'}
{'type': 'c', 'source': 101, 'id': 203, 'data': 'ce3', 'partitionKey': '101'}
{'type': 'c', 'source': 101, 'id': 204, 'data': 'ce4', 'partitionKey': '101'}
{'type': 'c', 'source': 101, 'id': 204, 'data': 'ce4', 'partitionKey': '101'}
{'type': 'c', 'source': 101, 'id': 204, 'data': 'ce4', 'partitionKey': '101'}
{'type': 'c', 'source': 101, 'id': 204, 'data': 'ce4', 'partitionKey': '101'}
{'type': 'c', 'source': 101, 'id': 204, 'data': 'ce4', 'partitionKey': '101'}
这就是我将数据插入流的方式(如您所见,分区键设置为源id):
所以我的问题是:
- 为什么每个lambda函数不能只处理一个碎片的记录
- 如何做到这一点
谢谢 为什么您会关心哪个Lambda实例处理碎片?Lambda实例无论如何都没有状态,所以哪个实例读取哪个碎片并不重要。更重要的是,在任何时候,Lambda实例都只能从一个碎片读取数据。在完成调用后,它可以从另一个碎片读取 您是否使用KCL使用流中的记录?我通过事件源映射()直接使用流。因此,记录通过传递给函数的事件传递给lambda函数。@oneschilling您解决过这个问题吗?我也吃同样的issue@gfree显然这是不可能的。我还与AWS的支持人员进行了交谈,他们证实了这一点。我通过他们提出了一个功能请求。我认为他们最初计划将其作为与lambda结合使用的动觉特征,因为文件一开始就说明了这一点,但在某个时候有所改变。因此,对于我们来说,此时最好的选择是改变插入数据的方式,因为我们依赖于管道中的顺序。我们将这种逻辑转移到数据生产者,使piepline顺序不可知,这意味着我们可以毫无问题地增加碎片的数量。
processed_records = []
for r in records:
processed_records.append({
'PartitionKey': str(r['source']),
'Data': json.dumps(r),
})
kinesis.put_records(
StreamName=stream,
Records=processed_records,
)