【手摸手学ModelArts】偶遇OBS“惊天”大Bug!
偶遇OBS"惊天"大Bug
本文首次发表于华为云社区 ModelArts 版块,主要是作者在学习使用 AI 开发平台 ModelArts 过程中的一些经验产出。此次分享的是上次在ModelArts 上体验 MindSpore[1]时遇到OBS的一个Bug,经过华为云工程师长达40分钟的耐心解答,终于搞懂了这个“惊天大Bug”的来龙去脉,期间我尝试了moxing、obsutils、OBS SDK等方式来解决Bug,最后问题终于得到解决。如果您对 AI 感谢兴趣,欢迎【点击阅读原文】参与“2020 华为云 AI 实战营”[2],7 月 31 号前参与还可积分兑好礼!
↑开局一张图,故事全靠编。
缘起
做开发的尤其是前端,你永远不知道用户会怎么使用你的产品,比如页面上一个输入框,你永远不知道用户会输入什么。这次能遇到OBS的这个Bug,也是我无意间做了不当的“输入”,导致上传到OBS的文件无法正常显示,也无法正常操作(如:删除)。先来看看问题究竟是啥,请看下图:1. 无法显示正常的文件信息;2. 点击删除无法正常删除文件,是怎么删都不能删的!; 3. 其他操作也不正常,如分享复制出来的链接访问是NoSuchKeyThe specified key does not exist等等。导致问题出现的原因,大概就是工单解决方案中提到的:上传的对象带了特殊字符,OBS 服务后台不能正常的转义。
显示异常 | 无法删除 |
---|---|
复现
我究竟是做了什么操作才导致OBS无法正常转义呢?为了复现这个问题,我找到了上一次实践的错误代码,罪魁祸首就是它了:
cd ~cd workmkdir mytestcd mytestwget http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gztar -zxvf ./train-images-idx3-ubyte.gz
通过一波Terminal操作,我下载了一个train-images-idx3-ubyte.gz文件,并错误地执行了tar -zxvf ./train-images-idx3-ubyte.gz
,这里其实已经是“罪恶的源头”了,我们通过执行ls
,可以看到如下文件:
sh-$ls'<' ''$'\224' ''$'\374\374\356' ''$'\376\035' ''$'\313\367\372\375\375\375\257''9' train-images-idx3-ubyte.gz''$'\315' ''$'\341' ''$'\374\375\216' ''$'\f' 'm'$'\v\002'
其实这里已经是问题的所在了,因为解压不当导致了一些特殊字符的文件名的生成,当然,如果不上传这些文件到OBS,是不会偶遇文章开头的问题。为了复现,我们通过Moxing将文件上传到OBS上,代码如下:
import os import moxing as mox mox.file.copy_parallel('./mytest', 'obs://mindspore-labs/mytest')print('Upload done!')
上传之后,回到OBS,发现我们刚解压出来的文件已经存在, 而且如“幽灵”一般存在,它们没有名字,无法删除,就算分享出来也无法正常访问,这里姑且称它们为“影子文件”。
求解
遇到这样的Bug,我还是很兴奋的,作为Copy攻城狮,我平时很少独立思考,这次却破天荒地费了的脑力想想了--还是提工单吧!本来提了工单可能就万事无忧了,不过对于未知事物的好奇,我也开始一步步探索。
网页操作
首先,从结果来论证,直接面向用户的前端页面最能直接展现问题。我分别查看了正常情况和“影子文件”的network,发现了有意思额情况,正常的返回在XML中Contents下包含key、size等返回信息,也就是我们能看到的文件名、文件大小、修改时间之类的,而“影子文件”返回的数据Contents下没有任何信息,所以我们看不到文件相关的信息,也无法正常操作文件。
正常文件 | 影子文件 |
---|---|
通Moxing列举
其次,通过Moxing列举正常能读取的文件和“影子文件”,也发现了些猫腻,正常文件列表是可以被读取到的,而尝试读取“影子文件”目录就会报错。
执行代码:
import moxing as mox # 列举正常文件mox.file.list_directory('obs://mindspore-labs/experiment_1/MNIST/', recursive=True)# 列举影子文件mox.file.list_directory('obs://mindspore-labs/mytest/', recursive=True)
通过以上两步尝试,也预示我们无法通过OBS网页端和Moxing来删除“影子文件”,根据大佬给出的指导,应该使用obsutil[3]或者SDK[4]去删除文件对象。值得注意的是,这两种方法都需要获取访问密钥即AK/SK(Access Key ID/Secret Access Key),获取AK/SK的细节这里就不赘述了。
obsutil体验
不得不提下这款用于访问管理OBS的命令行工具,它具有四大优势:
简单、易用;
无需安装,轻便小巧,即下即用;
同时支持Windows/Linux/macOS三大平台;
配置多元化,性能卓越。
我是windows系统,下载之后运行obsutil.exe,执行config -i=ak -k=sk -e=endpoint
进行初始化配置,ak就是访问密钥的AK,sk是访问密钥的SK,endpoint对应桶所在的终端节点如:obs.cn-north-4.myhuaweicloud.com就是华北-北京4,endpoint可访问地区和终端节点[5]查看。
我尝试列出“影子文件”,结果还是抛了异常Error: Status [0], error code [], error message [XML syntax error on line 1: illegal character code U+000C], request id [000001735BD0E90D440F97BC745F201C],如果要知道究竟发生了什么,可以工单并向华为云工程师大佬提供这个request id,其实通过报错信息我们也能察觉到是有非法字符导致的。
然后我满怀信心的敲下了rm obs://mindspore-labs/mytest -r -f
,以为这样就能删除掉,结果:
[________________________________________________________] ?% tps:0.00 0/0 52ms Warn: No task to run List objects in the bucket [mindspore-labs] to delete failed, status [0], error code [], error message [XML syntax error on line 1: illegal character code U+000C], request id [000001735BD70EBE44149CE8B9E179C9]
是的,删除失败!!!去网页端查看,文件依旧如磐石般岿然不动!
OBS SDK体验
既然前面三种方法都没能删除顽固的“影子文件”,那试试仅有的一丝希望--OBS SDK。由于我是JavaScript技术栈,尽管工单那头的大佬极力推荐Java SDK,我还是毅然决然地选择了Node.js SDK。赶紧下载官方文档提供的Demo代码[6],开始我认为的最后一根破除稻草:
安装依赖:
npm install esdk-obs-nodejs
找到examples\delete-objects-sample.js开干,替换access_key_id的值为访问密钥的AK,secret_access_key的值为访问密钥的SK,server的值为桶所在的终端节点如:"https://obs.cn-north-4.myhuaweicloud.com";其实和**obsutil**的配置大同小异.
我们先通过listObjects列举一下“影子文件”:
var obs = new ObsClient({ access_key_id: '您的访问访问AK', secret_access_key: '您的访问密钥CK', server : '桶所在的终端节点'});var bucketName = 'mindspore-labs'; // 桶名obs.listObjects({ Bucket: bucketName, Prefix: 'mytest/' // 前缀,列举mytest下文件}).then((result) => { if(result.CommonMsg.Status < 300){ console.log('List all objects in folder mytest/ \n'); for(let j=0;j<result.InterfaceResult.Contents.length;j++){ console.log('\tKey-->' + result.InterfaceResult.Contents[j]['Key']); console.log('\tETag-->' + result.InterfaceResult.Contents[j]['ETag']); } console.log('\n'); }});
得到的结果出乎我的意料,不仅是影子文件,其他正常的文件也能正常列出,这足以说明Copy攻城狮功力到位了,也是能够解决问题的:
$ node examples/delete-objects-sample.js List all objects in folder src0/ Key-->mytest/ ETag-->"d41d8cd98f00b204e9800998ecf8427e" Key-->mytest/ ETag-->"d41d8 ETag-->"d41d8cd98f00b204e9800998ecf8427e" Key-->mytest/< ETag-->"d41d8cd98f00b204e9800998ecf8427e" Key-->mytest/md98f00b204e9800998ecf8427e" Key-->mytest/t ETag-->"d41d8cd98f00b204e9800998ecf8427e" Key-->mytest/train-images-idx3-ubyte.gz
影子文件神秘的面纱已经揭开,因为OBS后台无法解析特殊符号如小于号,导致解析进程中断了,亦或是文件路径名不能有特殊字符。既然问题到这,已经非常透彻了,接下来应该是破局的时候了。
破局
既然最终找到了问题的根本,尝试解决吧,依旧使用我们的SDK来处理,只需在上面列举中调用deleteObject:
obs.listObjects({ Bucket: bucketName, Prefix: 'mytest/'}).then((result) => { if(result.CommonMsg.Status < 300){ console.log('List all objects in folder mytest/ \n'); for(let j=0;j<result.InterfaceResult.Contents.length;j++){ console.log('\tKey-->' + result.InterfaceResult.Contents[j]['Key']); console.log('\tETag-->' + result.InterfaceResult.Contents[j]['ETag']); obs.deleteObject({ Bucket: bucketName, Key: result.InterfaceResult.Contents[j]['Key'] }, (err, result) => { if(err){ console.error('Error-->' + err); }else{ console.log('Status-->' + result.CommonMsg.Status); console.log('CommonMsg-->' + JSON.stringify(result.CommonMsg)); } }); } console.log('\n'); }});
尽管这是最愚笨的方式,但我已经达到了我的预期,无法删除的“影子文件”终于可以通通删除了,感觉世界终于清静了!
温馨提示:以上方法会清除目录下的所有文件,如有要保留特定的文件请通过编写代码实现
最后在OBS网页端再确认一下,终于完成了!
加入组织
MDG 是 ModelArts Developer Groups 的缩写。是由 ModelArts 开发者发起的开放、创新、多元的开发者社区组织。致力于帮助开发者学习提升、互动交流、挖掘机会,推动 AI、互联网等产业生态的建立和发展。MDG 是面向人工智能、AI 技术、开源项目及 ModelArts 平台技术感兴趣的公益性开发者社区,相关开发者、软件工程师、创业者、运营人、产品人、大学生、老师等都可以参加到 MDG 社区。
MDG 秉承开放、创新、多元的社区文化,完全由各地志愿者自发组织和建立。目前,我们已在北京、上海、杭州、重庆建立了社区组织。自 2019 年12月起陆续开展了多次线上、线下活动。许多小伙伴正是参与了华为云 ModelArts 的相关活动后,申请加入MDG志愿者组织,从而更深入地了解ModelArts平台。
关于作者
新晋华为云云享专家Copy攻城狮,我是胡琦,近期有幸参与【2020华为云AI实战营】,学习ModelArts并加入【MDG社区】,期待在这里与你相遇!
参考链接
[1] https://bbs.huaweicloud.cn/forum/thread-65345-1-1.html
[2] http://2020.huaweicloud.ai
[3] https://support.huaweicloud.cn/utiltg-obs/obs_11_0001.html
[4] https://support.huaweicloud.cn/sdkreference-obs/obs_02_0001.html
[5] https://developer.huaweicloud.cn/endpoint?OBS
[6] https://obssdk.obs.cn-north-1.myhuaweicloud.com/current/nodejs/nodejs.zip
- 点赞
- 收藏
- 关注作者
评论(0)