DynamoDB 流事件中用于删除操作的元数据?
Metadata in DynamoDB stream event for delete operation?
我打算使用 DynamoDB 流来实现日志跟踪,跟踪对 table 数量的更改(并将其写入 S3 上的日志文件)。每当对 table 进行修改时,都会从流事件中调用 lambda 函数。
现在,我需要记录进行修改的用户。
对于 put
和 update
,我可以通过包含一个保存调用者 ID 的实际 table 属性来解决这个问题。现在存储在 table 中的记录将包含此 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
,另一个删除项目,流只会从流事件中包含的 OLD_IMAGE
中获取 __modifiedBy
值.然而,这确实是不可取的,必须在一次删除项目上花费 2 次写入。
那么有没有更好的方法,例如将元数据附加到 DynamoDB 操作,这些操作将被转移到流事件中,而不是写入 table 本身的数据的一部分?
这里有 3 个不同的选项。正确的将取决于您的应用程序的要求。这些方法中的 none 可能适用于您的特定用例,但总的来说,这些方法都适用。
选项 1
如果您在足够精细的级别上使用 AWS IAM,那么您可以从 Stream Record.
中获取用户身份
选项 2
如果您在写入 dynamodb 时可以处理少量开销,则可以设置一个 lambda 函数(或基于 ec2 的服务)充当您的 dynamodb tables 的写入代理。配置您的权限,以便只有 Lambda 可以写入 table,然后您可以接受您想要的任何元数据并根据需要记录它。如果您只需要记录事件,则无需写入 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
如果您可以容忍 table 中的一些陈旧数据,请在 table(s) 上设置 DynamoDB TTL。创建或更新项目时不要设置 TTL 值。然后不是删除项目,而是通过将当前时间添加到 TTL 字段来更新项目。据我所知,DynamoDB 在删除 TTL 已过期的项目时不使用写入容量,并且过期的项目会在其到期 24 小时后被删除。
这将允许您将“添加 TTL”记录为删除操作,并拥有一个 last modified by
用户来进行该删除操作。您可以安全地忽略 dynamodb 清理过期项目时发生的实际删除。
在您的应用程序中,您还可以检查 TTL 值是否存在,以免意外向用户显示已删除的数据。您还可以向任何将忽略具有 TTL 集的项目的查询添加过滤器表达式。
我打算使用 DynamoDB 流来实现日志跟踪,跟踪对 table 数量的更改(并将其写入 S3 上的日志文件)。每当对 table 进行修改时,都会从流事件中调用 lambda 函数。
现在,我需要记录进行修改的用户。
对于 put
和 update
,我可以通过包含一个保存调用者 ID 的实际 table 属性来解决这个问题。现在存储在 table 中的记录将包含此 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
,另一个删除项目,流只会从流事件中包含的 OLD_IMAGE
中获取 __modifiedBy
值.然而,这确实是不可取的,必须在一次删除项目上花费 2 次写入。
那么有没有更好的方法,例如将元数据附加到 DynamoDB 操作,这些操作将被转移到流事件中,而不是写入 table 本身的数据的一部分?
这里有 3 个不同的选项。正确的将取决于您的应用程序的要求。这些方法中的 none 可能适用于您的特定用例,但总的来说,这些方法都适用。
选项 1
如果您在足够精细的级别上使用 AWS IAM,那么您可以从 Stream Record.
中获取用户身份选项 2
如果您在写入 dynamodb 时可以处理少量开销,则可以设置一个 lambda 函数(或基于 ec2 的服务)充当您的 dynamodb tables 的写入代理。配置您的权限,以便只有 Lambda 可以写入 table,然后您可以接受您想要的任何元数据并根据需要记录它。如果您只需要记录事件,则无需写入 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
如果您可以容忍 table 中的一些陈旧数据,请在 table(s) 上设置 DynamoDB TTL。创建或更新项目时不要设置 TTL 值。然后不是删除项目,而是通过将当前时间添加到 TTL 字段来更新项目。据我所知,DynamoDB 在删除 TTL 已过期的项目时不使用写入容量,并且过期的项目会在其到期 24 小时后被删除。
这将允许您将“添加 TTL”记录为删除操作,并拥有一个 last modified by
用户来进行该删除操作。您可以安全地忽略 dynamodb 清理过期项目时发生的实际删除。
在您的应用程序中,您还可以检查 TTL 值是否存在,以免意外向用户显示已删除的数据。您还可以向任何将忽略具有 TTL 集的项目的查询添加过滤器表达式。