浅谈
本章节结合一些实际遇到的案例讲一下各种工具使用。
- 在遇到问题时先确保自己的工具一定是官方的最新迭代版本。
- 使用工具遇到问题时如果遇到 4xx 3xx 2xx 500 等问题,oss 都会返回一个 x-oss-requestID 的 http 头,value 是一串字符,类似
5BEE7AD4C84D1C447120083C
这个对于排查分析问题非常重要。 - 每个工具基本都带有 log 功能,请使用者务必开启,遇到问题时可以追根溯源。
一、使用场景
- ossbrower,图形版的操作工具,有控制台的基本功能,可以理解是 ossutil 工具的图形版,适用于一些非技术人员来操作 oss 。
- ossfs,将 oss mount 到本地放使用,利用的是 fuse 用户态的文件系统,然后通过开源的 s3 协议和 oss 做了一个网络映射,不推荐先敏感业务或者高并发使用,个人当作私人仓库标适合。
- ossftp ,和开源的 ftp 一样,将 oss 挂在本地后,当作远程的仓库上传下载用。
- ossutil,目前 oss 对外工具性能最好,支持功能较多的高并发读写工具。操作易用,而且可以嵌入到脚本使用。
二、使用遇到问题
ossbrower
案例:驻云工具无法加载 bucket 中 object
排查:
- 如图是一个第一个非 oss 官方的第三方工具,用户可以尝试在客户端做下基本的 ping 测试先看下网络是否通。
- 检查登陆的 AccesskeyID 的权限是否可以将 bucket 下的内容 list 出来。
- 用 ossbrower 测试下,看同样的 AccesskeyID 登陆后是否也会报错,如果 ossbrower 可以正常显示,证明策略没有问题,是第三方放工具的问题。可以联系驻云公司看下是否配置上有特殊的地方。
案例:ossbrower 使用注意
- 如果登陆的 AK 没有 AliYunOSSFullAccess 权限,截图的位置必须要预设 endpoint;
- 遇到并发文件较多时,建议将任务数调大;
ossfs
ossfs 的报错都会有明显的 message,需要收集到这些 message,根据 message 判断是否直接看出问题,比如 socket 建联失败,或者响应的状态码 4XX 5XX 等,一般 403 是权限问题被 deny ,400 是用户的操作方法有误,5xx 一般和网络抖动以及客户端业务有关系,使用前先将 debug-log 功能开启。
如果使用 ossfs 发现性能很差,建议使用 ossutil,因为 ossfs 是将远端的 OSS 挂载到本地磁盘,如果对业务性能敏感性很高的业务,不建议使用 ossfs ,而且该工具也不是原子性,存在本地操作成功,但 oss 远端操作失败的风险。
如果发现 ossfs 在 ls 目录文件时很慢,可以增加调优参数 通过 -omax_stat_cache_size=xxx
参数增大 stat cache 的 size,这样第一次ls会较慢,但是后续的ls就快了。
案例:ossfs 偶尔出现断开的情况
排查:
- 出现问题后也不知原因,于是开启了 ossfs 的 debug 日志进行分析
加上-d -o f2
参数,ossfs 会把日志写入到系统/var/log/message
- 日志发现是 ossfs 在 listbucket listobject 申请内存过多,导致触发了系统的 oom 将进行 killer ,找到了元凶。
- listobject 是要发起 http 请求到 oss 获取一个 meta 信息,如果客户的文件很多,ls 会消耗系统的大量内存来获取文件的 meta,这是正常情况。
解决方案:
- 通过
-omax_stat_cache_size=xxx
参数增大 stat cache 的 size,这样第一次 ls 会较慢,但是后续的 ls 就快了,因为文件的元数据都在本地 cache 中。默认这个值是1000,大约消耗 4MB 内存,请根据您机器内存大小调整为合适的值。 - 使用
ls -f
命令,这个命令会消除与 OSS 的 n 次 http 请求。 - ossfs 在读写时会占用磁盘写大量的 temp cache ,和 nginx 差不多,可能会导致磁盘空间不满,最好能常清理一下。
- 使用 osstuil 替代 ossfs ,非线上敏感业务可以用 ossfs ,要求可靠性、稳定性的还是用 ossutil。
案例:访问 403 deny
排查:
类这种有明显报错的很好判断,明显是 endpoint 指定错误。
- bucket 和 endpoint 不匹配
- bucket UID 和实际的 Accesskey 对应的 UID 不一致
案例:
cp 出现 input/output error
排查:
- 看下当时的磁盘读写是否出现高负载的情况。 io error 都是捕获到这系统磁盘的错误。
- 可以尝试增加分片参数,控制文件读写 , ossfs -h 看下 multipart 选项。
使用 rsync 同步出现 input/output error
- ossfs 与 rsync 同步使用会出现问题,而且用户对一个 141G 的文件进行 cp 操作,对 ossfs 本身的磁盘读写比就是一个挑战。
- 建议,如果想要将 oss 文件下载到本地 ECS ,或者本地上传到 ECS ,可以通过 ossutil 的分片上传、下载进行操作。
案例:
安装依赖库 fuse 报错
排查:
出现这种问题都是 fuse 的版本不满足 ossfs 的要求,2.8.3 的都不行,直接去 fuse 链接上下载最新版本的编译安装,不要用 yum, yum 安装的都不是新版
参考链接:https://github.com/libfuse/libfuse
案例:
客户使用 ossfs 上传超过超过 100G 的文件出现
“there is no enough disk space for used as cache(or temporary)"
排查:
- 1) 先了解 ossfs 的大文件上传原理,ossfs 上传大文件,是通过分片来做的,默认分片时 10M,分片数量最大时 1000 个,也就是默认限制大小为 100G。
- 2) 出现这种本地磁盘空间不够的情况,是因为 OSS 再上传会写一些临时缓存文件到 /tmp 目录下,再写之前先要判断下磁盘的管理空间是否小于用户上传的文件总量
// check free disk space
if(!FdManager::IsSafeDiskSpace(NULL, S3fsCurl::GetMultipartSize() * S3fsCurl::GetMaxParallelCount())){
S3FS_PRN_EXIT("There is no enough disk space for used as cache(or temporary) directory by s3fs.");
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
exit(EXIT_FAILURE);
}
- 3) 而用户上传的文件是一个 300G 的文件,本地磁盘冗余 600G,不可能不够的,但是代码统计不会说谎,当时磁盘空间预判确实不够,ossfs 唯一能够控制分片的就是 ,multipart_size 和 控制线程的数量。但是默认是 5 个,不可能是线程数量导致的,唯一可能就是 multipart_size 导致。通过分析发现用户 multipart_size 是 300G * 5 = 1.5T,这个 multipart_size 分片大小是 M ,结果自然超过了本地的磁盘安全空间,所以导致的无法上传,将分片大小降低后就解决了。
案例:
ossfs 挂载到本地,touch 文件出现 input/output error ,返回结果 403;
排查:
遇到类似问题,可以先使用 ossfs 的前台挂载参数,将错误信息输出到 console 上; -f -d -o curldbg -o dbglevel=info
有了 curl 的报错日志问题就比较好定位;
> PUT /.fuse_hidden0000000300000002 HTTP/1.1
Host: pgone.oss-cn-hangzhou-internal.aliyuncs.com
Accept: */*
Authorization: OSS LYnddfOj:l9hXsWS4KubHT+b0=
Content-Type: application/octet-stream
Date: Sat, 22 Dec 2018 11:52:22 GMT
User-Agent: aliyun-sdk-http/1.0()/ossfs1.80.5
x-oss-acl: private
x-oss-copy-source: /pgback/tmpn18XKo
x-oss-meta-gid: 0
x-oss-meta-mode: 33152
x-oss-meta-mtime: 1545479542
x-oss-meta-uid: 0
x-oss-metadata-directive: REPLACE
Content-Length: 0
Expect: 100-continue
< HTTP/1.1 100 Continue
< HTTP/1.1 403 Forbidden
< Server: AliyunOSS
< Date: Sat, 22 Dec 2018 11:52:22 GMT
< Content-Type: application/xml
< Content-Length: 331
< Connection: keep-alive
< x-oss-request-id: 5C1E2576D9D458BE30B9D539
< x-oss-server-time: 2
* HTTP error before end of send, stop sending
- 通过拿到的 http request、response 信息看到用户有一个 rename 的操作,并且返回的 requestID 信息;
- 结合 ossfs 的源码得知,ossfs 在挂载 oss 到本地成功后,会发起一个类似探针的操作进行 rename 和 chown 的操作,此过程是为了类似验证 OSS 权限和连通性的操作;
- 如果出现类似的 copy 操作被 403 后,就需要您检查下您的 bucket 是否为归档 bucket,如果不是归档继续下面排查;
- 确认您的 Accesskey 对应的权限是否有对应的操作权限;
- 把 ossfs 卸载然后进入挂载的目录看下直接 touch 会不会报错;
如果以上仍不能解决您的问题,请将 requestID 提供到阿里云进行排查。
ossutil
ossutil 目前没有做限速功能,计划支持中,目前真多多文件并发上传是通过 --jobs(控制多个文件并发)
--parallel(控制单一文件并发)
参数控制的。
案例:
ossutil 出现 skip 情况
[root@iZ2Sv4olcc4Z opt]# echo “testlil” > dskydb/test.txt
[root@iZ25v4olcc4Z opt]# ./ossutil64 cp -rt -c ~/.ossuti.Lcofig dskyclb/test.txt oss://gres/test.txt
Succeed: Total nun: 1, $ze: 30. OK nun: 1(upload 1 files).
0.372650(s) elapsed I
[root@iZ2Sv4olcc4Z opt] echo " ttest222r" >> dskydb/test.txt
[root@iZ2Sv4olcc4Z opt]. /ossutil64 cp —u —c ~/.ossutilconfig cbkydb/test.txt oss://gres/test.txt
Succeed: Total num: 1, ize: 38. OK nun: l(skip 1 files), Skip sin 38.
0.252878(s) elapsed
排查:
使用 -u 强制更新时,重新对所有的上传文件和原的进行一次比对,发现美有更改的情况就会跳过,有发生更改的就会触发上传进行覆,正常情况。
遇到这种情况可以看下本地的 log 哪些文件被跳过了,将 oss 存储的文件和本地文件做个 MD5 比对确保文件是一致。
命令:./ossutil64 cp -u -r -f aa.test oss://alihua -i -k -e
案例:ossutil 文件递归解冻时遇到 403
排查:
如图用户在操作解冻文件的过程中出现 403,可能与两个原因有关系
- 用户使用的子账号操作文件,权限不够。
- 用户的文件是违禁内容被封禁掉了。
PS:遇到 403 时,递归解冻会中断不会继续。这种现象是正常的,工具在设计之初就是考虑到如果文件遇到 403 的话,代表没有权限操作该文件,那么通过该账号下的其他文件也操作不了,所以就会中断退出。
案例:ossutil 文件递归解冻时遇到 400
排查:
- 检查用户的命令和官方提供的命令是否完全一致,避免误操作。
- 使用 stat 选项看一下文件的状态是否是已经解冻了,如果以及解冻再次操作,就会出现 400。
案例:
ossutil 操作 object 出现 “The operation is not valid for the object's state”
排查:
出现这个问题是因为用户操作的文件是一个归档的文件,不能直接操作,需要先进行解冻 restore 的操作后才能使用。
ossuti64 restore oss://bucket/prefix/object -I <accesskey> -k <secretkey> -e <endpoint>
递归解冻ossuti64 restore oss://bucket/prefix/ -r -I <accesskey> -k <secretkey> -e <endpoint>
案例:
ossutil 挂载 crontab 中执行报错
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x6b4981]
goroutine 1 [running]:
github.com/aliyun/ossutil/lib.DecideConfigFile(0x0, 0x0, 0x7a8017, 0x7)
/Users/fengyu/go/src/github.com/aliyun/ossutil/lib/config_helper.go:57 +0x51
排查:
请直接下载 ossutil 的工具最近版本进行处理。这个问题已经解决掉。
http://gosspublic.alicdn.com/ossutil/1.4.2/ossutil64?spm=a2c4g.11186623.2.10.2ca74af8lGi3C8
案例:
Windows ossutil 上传 OSS 速率慢不稳定
客户端是在河北公网,目标服务端是北京,存在跨省情况;
首先了解下用户在公网情况下,能否切换到同 region 的 OSS 上进行访问,同 region 的 OSS 内网是有阿里环网组成,如果客户只能在公网使用,进行下面的排查。
排查:
公网:
1) 首先看下用户端 ping OSS 的完整域名的网络 ping 值是否正常,tracert 是否有延迟抖动,此步骤可以通过脚本来做,下载脚本后运行,直接输入完整的 OSS 域名即可; 脚本
- 脚本中是 ping 的是大包 1460,发现用户端直接网络超时,此时怀疑是客户的网络有限制或者网络拥塞,但是 tracert 通的,再进行下一步排查;
- 尝试降低 ping 包的 len 发现到 1412 ping 可以通过,说明客户端在网络上做限制,不允许 1460 大包的传输,影响了客户端的上行网络吞吐量;
2)尝试检查本机的网络负载;
- 通过本机资源监控看用户端当时的 CPU 负载和本机内存占用较高,实际登陆到客户端机器上发现系统卡顿,实际资源监控器看到 ossutil 工具线程并没有跑到和设置的 --job=10 --parallel=10 (10*10=100)一样,只是运行了 24 个,说明工具的线程受到了系统 CPU 调度影响,无法将网络吞吐打上去,于是让用户关系了一些占用 CPU 内存较高的应用后,ossutil 线程数终于打到 69;
调整前
调整后
3)灵活调整 ossutil 的线程数和分片的并发数;
- --bigfile-threshold=52428800 --jobs=10 --parallel=50 --part-size=52428800
- 遇到大文件数量多,以及单一的大文件时我们要灵活调整 ossutil 的相关参数能够提高我们的 ossutil 的效率;
- 比如这个案例中客户的文件大小平均是 100M 以上,而且客户的出口带宽是共享 200M ,也就是客户自己的上线速度理论上也要 20M;
- 针对这种情况,我们可以把分片大小调整为 50M-10M,同时增加 parallel 分片的并发数量,尽可能的打满上行的吞吐。当客户端 CPU 核心比较少的时候不建议分的太小,比如分到 1M 时就会造成 CPU 切片过快,消耗 CPU 计算,影响系统性能。
- 如果遇到文件数量单一大文件,或者小文件时,可以不用加任何参数,直接上传即可;调整完成后用户的上行出口速率能打到 10M 大 B。
4)对比其他家的工具
- 比如七牛的 qfetch 以及 qshell 做了性能对比,上行的传输效率相差并不多,并没有用户反馈了七牛 20M (大B)阿里云 4M(大B),基本上qshell 和 qfetch 的效果都是稳定在 10M 左右;
总结下问题以及需要客户下一步解决:
当使用 ossbrower 上传速度低时可以切换到 ossutil 这个高兴的工具进行测试;
需要用户解决下为什么网络出口限制的大包(1460) 的传输,这个问题不解决很难将网络带宽吞吐提上去。
尽量本机不要在负载高的情况下上传一些大文件,如果传输的话可以关闭一些应用卡顿的程序,或者降低下 ossutil 工具的并发线程数量,不然即使设置了 100 ,但实际受到系统的 CPU 调用影响,不一定能跑到 100 。降低线程数,上传的效率也会受到影响;
osscmd
案例:
OSS 存储文件数量和本地的文件数量不符,用 ossutil 就是正确的。
排查:
osscmd 下载,是直接将 oss 云存储的 object 下载下来,不会包含 prefix ,有多少 object 就累计总和,不会出现误差。
为什么 oss 存储的比 osscmd 统计的多?
- 因为 oss 上的 prefix 也算是一个 object ,oss 上一切都是文件,没有目录的概念,prefix 被认为是 object 计算后,总的数量就会比 osscmd 看到的多。
- 要想判断是否有失败文件,只要关心 fail num 的数量即可,为 0 代标没有失败的,skip 如果不为 0 说明用户之前有下载过文件,又重复下载一遍,但是文件内容没更新所以被计到 skip 中。
为什么 ossutil 正常?
- 因为 ossutil 下载是将整个目录结构下载下来,统计的方式是和 OSS 一致的,将 prefix 也计算在 object 中,所以和 OSS 云端看到的一致。