一、创建源和目标 Amazon S3 存储桶
*注意:**如果已经创建了源和目标 S3 存储桶,则可以跳过此步骤。
完成以下步骤:
- 打开 Amazon S3 控制台。
- 选择创建存储桶。
- 对于存储桶名称,输入源存储桶的名称。
- 从 AWS 区域下拉列表中,选择您的 AWS 区域。
- 选择创建存储桶。
- 对您的目标存储桶重复步骤 1-4。
二、创建 Lambda 函数
完成以下步骤:
-
在 Lambda 控制台中打开“函数”页面。
-
选择创建函数,然后选择从头开始创作。
-
对于函数名称,输入您的函数的名称。
-
从运行时下拉列表中,选择 Python 3.11。
5.展开更改默认执行角色,然后选择创建具有基本权限的新角色。
再加一个策略 可以 访问到s3
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:PutLogEvents",
"logs:CreateLogGroup",
"logs:CreateLogStream"
],
"Resource": "arn:aws-cn:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": [
"arn:aws-cn:s3:::源",
"arn:aws-cn:s3:::目标"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws-cn:s3:::源/*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl"
],
"Resource": "arn:aws-cn:s3:::目标/*"
}
]
}
6.选择创建函数。
-
选择代码选项卡,然后粘贴以下 Python 代码:
import boto3
import datetimes3 = boto3.client('s3')
def lambda_handler(event, context):
source_bucket = '源桶'
destination_bucket = '目标桶'
# 获取当前 UTC 时间并计算一天前的时间戳
now_utc = datetime.datetime.utcnow()
timestamp_utc = now_utc.timestamp()
one_day_ago = timestamp_utc - 86400 # 86400 秒 = 1 天
print("今天的开始时间:", one_day_ago)# 检查事件是否包含 LastModified 属性
if 'LastModified' in event:
last_modified = event['LastModified']
key = event["Key"]
# 只处理昨天之后上传的文件对象
if last_modified > one_day_ago:
print(key)
copy_source = {'Bucket': source_bucket, 'Key': key}
s3.copy_object(CopySource=copy_source, Bucket=destination_bucket, Key=key)
print(f"Copied object: {key}")
return {
'statusCode': 200,
'body': 'Data synchronization of objects from the last day completed successfully.'
}
else:
print(f"Jumped object: {key}")
return {
'statusCode': 200,
'body': 'Jump objects from not the last day completed.'
}
这个 Lambda 函数的作用是根据传入的事件,判断 S3 桶中的对象是否是昨天上传的,如果是则复制到另一个 S3 桶中。它利用datetime
模块来计算昨天的时间戳,并与对象的LastModified
时间进行比较来决定处理或跳过对象。
8.选择部署。
部署完之后要去配置页面改一下超时时间,和内存大小 根据你要同步是数据量大小来选择
三、为 Lambda 函数的执行角色提供 IAM 权限
可以创建内联策略,也可以去创建策略
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:PutLogEvents",
"logs:CreateLogGroup",
"logs:CreateLogStream"
],
"Resource": "arn:aws-cn:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": [
"arn:aws-cn:s3:::源",
"arn:aws-cn:s3:::目标"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws-cn:s3:::源/*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl"
],
"Resource": "arn:aws-cn:s3:::目标/*"
}
]
}
四、创建Step Functions 状态机
默认即可
输入源桶以及如果要同步特定文件夹的数据就带上目录
选择对应的ldmbda,setp funtion遍历s3,获取的值,lambda再去拉取筛选。
其他默认就可以,然后创建
五、配置定时Amazon EventBridge
创建规则
1.使用cron表达式
2.固定多久运行一次
3.绑定lambda
4.创建
六、运行测试
上传一个对象到源端
目标端无文件
改一下定时为5min执行一次对应的状态机
再去目标桶那里可以看到源端的桶1天内上传的数据过来了,这里的一天是你执行的时间开始减去一天,比如7.2的12点执行,传输的数据就是7.1的12点到7.2的12点中间的数据(左闭右开)
刚刚看到源端的S3桶时间为2024年7月1日 pm2:50:02 CST 我先删除目标端的文件删除在pm3.04执行一下 看是哪些传过去了,哪些没传过去
发现只有7.2的pm3.04到7.1的pm3.04文件过去了,说明是没问题的。
可能会遇到的错误是说你 区域问题。实际可以去状态机 的 编辑看代码 lambda 块有个 aws改为 aws-cn 就可以了 ,s3桶 权限 不用单独设置。
七、总结
其实本来是可以靠lambda 直接去遍历s3,通过添加触发器来实现复制,不过lambda有15分钟超时,对于大文件遍历时间过长会报错,所以这里整个流程是step funtion去遍历s3,然后获取Lambda Invoke的输入LastModified这个时间戳来控制复制的对象,这是除了配置脚本定时运行的另一个方式。