背景
在从七牛云迁移数据到阿里云OSS的时候,有遇到客户的文件名前缀是以/
开始的,例如/abc/123.jpg
。这样的文件名在OSS上面是非法的,所以如果直接使用在线迁移服务是无法迁移成功。一般建议的方案是添加一个前缀,例如变成new/abc/123.jpg
,这样可以解决迁移不了的问题。但是这样会引发另外一个问题,就是导致用户的文件路径变更。对于用户来说,可能涉及到改代码,是一个额外的迁移成本。本文提供一个间接的方案,利用函数计算的能力,当文件被复制到OSS后,自动修改文件的名称,达到无缝迁移。
原理
利用在线迁移服务将七牛的数据迁移到OSS,注意OSS这边要加上前缀tmp。
利用函数计算,当发现指定Bucket有新建文件并且文件名以tmp
开始的话,触发函数计算功能。
函数负责将文件名的tmp
去掉。这里利用了OSS的copy和delete操作。
整个过程在同一个Bucket中发生。
执行步骤
关于在线迁移服务的部分,参考官网手册,这里不再作详细论述。下面直接从函数计算的配置入手。
一. 进入函数计算业务,选择新建函数。
二. 配置函数,填入服务/函数等名字,运行环境选择python3,其他按照默认。
三. 建立好之后会跳转到在线编辑页面。
把下面的代码复制到编辑框里面,完整覆盖原来的代码并保存。
import logging
import oss2
import json
def handler(event, context):
logger = logging.getLogger()
logger.info('start of the function')
creds = context.credentials
#获取当前的ak和as
auth=oss2.StsAuth(
creds.access_key_id,
creds.access_key_secret,
creds.security_token)
#获取旧的路径名
evt = json.loads(event)
evt = evt['events'][0]
object_name = evt['oss']['object']['key']
logging.info('path is ' + object_name)
if object_name.startswith('tmp') == False :
#不是tmp开头的不处理
return
#去除掉tmp/
if object_name.startswith('tmp/') :
new_object_name = object_name[4:]
else :
new_object_name = object_name[3:]
#获取到事件触发的bucket
bucket_name = evt['oss']['bucket']['name']
endpoint = 'oss-' + evt['region'] + '.aliyuncs.com'
bucket = oss2.Bucket(auth, endpoint, bucket_name)
logging.info('bucket name is ' + bucket_name)
#复制文件之后再删除原文件
bucket.copy_object(bucket_name, object_name, new_object_name)
bucket.delete_object(object_name)
return
四. 创建一个触发器。选择对象存储触发器
,触发器名称自行创建。Bucket列表注意选择准备要上传文件的那个Bucket。触发事件选择 oss:ObjectCreated:PostObject
和 oss:ObjectCreated:PutObject
。触发规则前缀那里,一定要输入tmp
。如果没有加入这个前缀,可能会引起额外的调用。
五. 配置好触发器之后,还需要做一个权限设置,否则即使任务触发成功,也会因为没有权限,函数无法将文件复制成功。回到主界面,选择服务配置
,然后修改
。
往下到权限配置,这里需要创建一个新的角色。这里需要选择把 AliyunOSSFullAccess
和 AliyunLogFullAccess
添加进去。
六. 权限配置好之后,整个配置就完成了。如果需要做多个Bucket的迁移,只需要重复第4步,在同一个函数上面多建立几个触发器,监测不同的Bucket即可。
验证方式
通过网页的方式上传文件到到tmp/
目录下面的文件,该文件会被移动到根目录。
通过网页的方式上传文件到根目录,如果名字是以tmp
开始的,会被去掉tmp
几个字符。
由于引入了函数计算,所以迁移任务最后会报失败。这只是因为迁移服务要比对的文件都被我们重命名了,所以产生这样的报告,只要确保迁移的文件数量一致即可
故障排查
如果网页方式上传无效,没有触发任何效果,可能是权限配置没有设置正确,返回第五步检查一下。
如果网页方式上传生效,但是在线迁移没有触发效果,可能是触发器中,触发事件配置不正确,返回第四步检查一下。