合理的迁移配置
目前还是推荐客户按照 VPC 的环境方式进行迁移,在服务体验感上有很大提升。在迁移过程中 OSS SLA 没有承诺迁移速度有明确指标,而且迁移数据和多因素有关(机器配置、数据量、网络、线程、限流等),所以根据实际情况进行问题诊断。
首先在迁移之前,要求使用者要先大致的学习一下我们的配置属性说明,和相关文件的作用,日志存储,异常处理等。
https://help.aliyun.com/document_detail/56990.html?spm=a2c4g.11174283.6.1079.sbu1ch
配置迁移文件单机版
迁移前要明确客户端的迁移体量和文件数量。目的是合理的配置 task 和线程数量,以及 ossimport 的工作模型。
- 一般迁移体量小于 30TB 的完全可以采用单机模式进行迁移,单机版可以配置多线程的方式进行迁移,调节 workerTaskThreadNum 参数,需要注意的是如果是高配,物理机的话,数量可以调大,可以参考 平均文件 size * 线程数量,对比 memory 是否够用,同时也要参考 CPU 核心数量是否能否抗住这种并发量。
- 当高并发,且文件的 size 较大时,如果配置数量不合理,会出现设备 OOM 的情况,可以通过 /var/log/message 看到,这是要么选择降低并发线程数量,要么是增大机器配置。
- 如果是本地 ECS 或者第三方存储迁移到 OSS ,请注意源是否有限流,目前经常会出现源发现有大流量流出后直接给限制住,导致迁移速度无法增长。关键参数 workerMaxThroughput(KB/s),如果源没有限制,可以释放调大这数。
- 其他 sys.properties 文件中的属性不要随意改动。
配置分布式迁移文件
- 分布式迁移模式的数据体量都是大于 30TB ,甚至上 PB 的级别才会用到,迁移模型也比较特殊,是通过 master 带多个 worker 协同工作,类似 nginx 的模型,master 只是用来切割任务和分配任务,对数据量庞大的用户,worker 的数量也要配置好,才能高效迁移。
- 首先通过客户端文件数量,来计算任务数,该项目中客户端总文件数 424421917 个,源头限制 3Gbps ,客户的机器数量有 12 台。
计划分成 20000 个 task ,每个 task 迁移 21221 个文件。每个 worker 机器开 200 线程,并发处理 200 个 task ,并发也就是能处理 2400 个,升级 17600 个 task 在队列中。 - 源流限制是 3000Mbps ,其实并发 worker 全部也就能跑到 375MB ,所以即便是你的线程开的再多,机器配置在高其他的线程也只能阻塞住。
OSS 单机版迁移速度慢优化建议
所有优化都是基于 ECS 的基础上,如果是自己的 PC 优化空间不大
- 如果是 OSS 迁移到 OSS 可以买 ECS 做迁移,将配置做大点,比 32G 16 核,64G 32核, 16G 8 核 等。
将 ECS 的 srcdomain destdomain 都设置为内网 internal 的域名。 - 如果不是 OSS 迁移到 OSS ,将配置做大点,比 32G 16 核,64G 32核, 16G 8 核 等。将 ECS 的 destdomain 设置为内网 internal 的域名。
- 将本机的迁移 heap 调大到 ECS 内存的 1/2 ,如果本机内存使用较高的请调到 1/4
- 线程数可以开到 workerTaskThreadNum=120
- 设置 workerMaxThroughput=0
OSS 分布式版迁移速度慢优化建议
- master 和 worker 机器要使用 ECS 机器进行迁移,master 机器要配置大点,如果想迁移快建议 master 64G 32核,worker 机器 32G 16 核 或者以上,数量越多越好,客户根据自己的业务情况买,具体情况再分析。将 ECS 的 srcdomain destdomain 都设置为内网 internal 的域名。
- 如果不是 OSS 迁移到 OSS ,将配置做大点,比 32G 16 核,64G 32核, 16G 8 核 等。
将 ECS 的 destdomain 设置为内网 internal 的域名。 - 将本机的迁移 heap 调大到 ECS 内存的 1/2 ,如果本机内存使用较高的请调到 1/4
- 配置文件线程数可以开到 workerTaskThreadNum=150
- 设置 workerMaxThroughput=0
问题:
ossimport NullPointException
排查:
- 空指针的目前存在于低版本的 ossimport 工具中,官网的新版本已经修复,下载新版本后重启任务进程即可解决。
- get target meta faild 是正常报错,ossimport 会自动重试,重试如果还是失败,最后会变成 failed success 任务,可以用 sh console.sh stat 看到,错误原因一般因为上传到 OSS 文件失败,无法拉去 meta 信息进行校验导致,可以不用关心。
问题:
ossimport 上传 oss 超时
排查:
通过上传报错即可知道 socket timeout ,基本上和网络脱不了关系,延迟过高、丢包、网络不通都会出现这种问题;
最有效的办法是客户端抓包走一波,然后通过抓包分析症结。
问题:
原文件带有特殊符号
排查:
出现这种错误,要检查下原文件是否存在特殊字符
, " ' \ / & <> 、? :
如果是以上带有特殊字符的原文件,需要经过本地先特殊字符处理掉,有些特殊字符可能在 Linux 的文件系统中可能无法正常显示,可能导致 OSS 获取原文件失败,最好自己将这种特殊的字符处理掉。
问题:
设置增量迁移,任务一直存在
排查:
isIncremental=true
incrementalModeInterval=86400
设置了这增量迁移参数后,如果第一次全量迁移完后,进程会一直存在,根据设置的间隔时间发起增量扫描,属于正常现象。
问题:
LocalScanner.run Exception:java.lang.StringIndexOutOfBoundsException: String index out of range
排查:
迁移的源文件设置了软链接单机版的暂时不支持,分布式版本的可以支持。
问题:
如何降低 ossimport 的迁移带宽,占用内存?
排查:
- 1)如果降低迁移带宽或者内存,将导致整体的 ossimport 迁移速度下降,耽误迁移时间,请做好预期。
- javaHeapMaxSize , 默认是 1024 最低的堆栈配置,想要调整迁移占用内存可以调整堆栈大小,不能少于 1024;
- workerMaxThroughput(KB/s) ,可以控制它迁移速度,单位是 KB;
- workerTaskThreadNum,迁移线程数,默认 60 ,可以调整。
通过以上几个参数可以降低迁移的占用带宽和内存消耗。所有配置文件都在 sys.properties 里面;
问题:
迁移过程中,出现 NoSuckKey ,但是本地文件存在,或者第三方存储源文件存在,为什么报 404?
[2018-12-05 10:33:13] [ERROR] Oss get meta failed, bucket:single key:mpg/All Japan 3200 Database Complete/Japan Data
base/J100040.mpg Exception:com.aliyun.oss.OSSException: Not Found
[ErrorCode]: NoSuchKey
[RequestId]: 5C0738E8D06C7BFCBDFFBAC1
[HostId]: null
at com.aliyun.oss.common.utils.ExceptionFactory.createOSSException(ExceptionFactory.java:104)
at com.aliyun.oss.internal.OSSErrorResponseHandler.handle(OSSErrorResponseHandler.java:56)
at com.aliyun.oss.common.comm.ServiceClient.handleResponse(ServiceClient.java:253)
at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:135)
at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:69)
at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:94)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:156)
at com.aliyun.oss.internal.OSSObjectOperation.getObjectMetadata(OSSObjectOperation.java:398)
at com.aliyun.oss.OSSClient.getObjectMetadata(OSSClient.java:582)
at com.aliyun.oss.OSSClient.getObjectMetadata(OSSClient.java:576)
at com.aliyun.ossimport.worker.uploader.OssUploader.getMeta(OssUploader.java:374)
at com.aliyun.ossimport.worker.task.localimpl.LocalAuditTask.checkWithRetry(LocalAuditTask.java:92)
at com.aliyun.ossimport.worker.task.localimpl.LocalImportTask.audit(LocalImportTask.java:101)
at com.aliyun.ossimport.worker.task.localimpl.LocalImportTask.run(LocalImportTask.java:150)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
排查:
ossimport 的工作过程是要先将源文件 list 出来,然后分成不同的 task 去执行,当所以任务执行完成后,再进行统计的文件校验比对,其方式是通过本地发起一条 http 的 header 请求到 OSS ,如果校验通过表示上传成功,如果校验失败上传就失败。
通过报错可以看到是 ossimport 执行了一个 http 请求到 OSS 端,获取了 404 的结果,这种情况只有两种可能:
- 迁移的数据源是 OSS,并且 OSS 上没有这个文件;
- 源文件存在,但是迁移过程中出现了失败任务,没有迁移成功,在最后 ossimport 校验时没有请求到目标 bucket 这条 object 所以出现 404 ;