我打算使用DynamoDB流来实现日志跟踪,以跟踪对多个表的更改(并将其写入S3的日志文件中)。每当对表进行修改时,都会从流事件中调用lambda函数。
现在,我需要记录进行修改的用户。
对于put
和update
,我可以通过包含保存调用者ID的实际表属性来解决。现在,存储在表中的记录将包含此ID,这并不是真正希望的,因为它比记录本身的一部分包含更多有关操作的元数据,但我可以接受。
例如:
put({
TableName: 'fruits',
Item: {
id: 7,
name: 'Apple',
flavor: 'Delicious',
__modifiedBy: 'USER_42'
})
这将导致lambda函数调用,在这里我可以在S3日志文件中写入以下内容:
table: 'fruits',
operation: 'put',
time: '2018-12-10T13:35:00Z',
user: 'USER_42',
data: {
id: 7,
name: 'Apple',
flavor: 'Delicious',
}
但是,对于删除,会出现问题-如何记录删除操作的主叫用户?当然,我可以发出两个请求,一个请求更新__modifiedBy
,另一个请求删除该项目,并且流只会从流事件中包含的__modifiedBy
中获取OLD_IMAGE
值。 。但是,这确实是不可取的,必须花费2次写入操作才能删除一个项目。
那么,有没有更好的方法,例如将元数据附加到DynamoDB操作中,这些操作会被继承到流事件中,而不会成为写入表本身的数据的一部分?
答案 0 :(得分:2)
这里有3个不同的选项。正确的选择取决于您的应用程序要求。这些可能都不适合您的特定用例,但总的来说,这些方法都可以使用。
选项1
如果您在足够细粒度的级别上使用AWS IAM,则可以从Stream Record获取用户身份。
选项2
如果在写入dynamodb时可以处理少量开销,则可以设置一个lambda函数(或基于ec2的服务),该函数充当dynamodb表的写代理。配置权限,以便只有Lambda可以写入表,然后您可以接受所需的任何元数据并按需要记录它。如果您只需要记录事件,则无需写入S3,因为AWS可以为您处理Lambda日志。
以下是使用日志记录而不是写入S3的lambda函数的示例伪代码。
handle_event(operation, item, user)
log(operation, item, user)
switch operation
case put:
dynamodb.put(item)
case update:
dynamodb.update(item)
case delete:
dynamodb.delete(item)
log(operation, item, user)
logEntry.time = now
logEntry.user = user
...
print(logEntry)
当然,您仍然可以直接直接登录S3,但是如果这样做,您可能会发现增加的延迟足以影响您的应用程序。
选项3
如果您可以容忍表中的某些陈旧数据,请在表上设置DynamoDB TTL。创建或更新项目时请勿设置TTL值。然后,不要删除项目,而是通过将当前时间添加到TTL字段来更新该项目。据我所知,DynamoDB在删除TTL过期的项目时不使用写容量,并且过期的项目将在其24小时到期后被删除。
这将使您可以将“添加TTL”记录为删除,并拥有一个last modified by
用户进行删除。您可以放心地忽略dynamodb清理过期项目时发生的实际删除。
在您的应用程序中,您还可以检查是否存在TTL值,这样就不会意外地向用户显示已删除的数据。您还可以向任何查询中添加过滤器表达式,这些查询将省略设置了TTL的项目。