做了这么多年数据对接的活儿,我发现自己几乎每年都会被“下载慢”这件事折磨几次。尤其是处理生物信息数据或者跨机房同步大文件的时候,一个几十 GB 的文件,用普通的 FTP 或 HTTP 下载,有时候能拉到天荒地老,中间断一次更是让人崩溃。后来换了 Aspera,才真正体会到什么叫“把带宽跑满”。
Aspera 是 IBM 旗下的一款高速文件传输软件,核心卖点就是快,而且是那种不讲道理的快。同一份数据,在同一台服务器、同一条网络链路下,FTP 可能只有几 MB/s,Aspera 能直接干到几百 MB/s。我现在手里所有跟欧美公共数据库打交道的下载任务,只要对方开放了 Aspera 通道,我就绝不会走普通 HTTP。这篇文章就围绕“用 Aspera 批量下载数据”这个主题,把从下载工具、密钥配置、命令参数到批量脚本的完整链路都理一遍,适合每天跟数据打交道、经常需要从 EBI、NCBI、TCGA 这类公共平台拉数据的科研人员,也适合需要在机房之间做大数据传输的运维朋友。
1. 为什么 Aspera 能跑这么快
1.1 TCP 的老毛病与新思路
传统文件传输协议,比如 FTP 和 HTTP,底层都是 TCP。TCP 本身是个“老实人”,它有一套完整的确认机制:发送方每发出去一批数据,都要等接收方回一个 ACK 确认包,确认收到了才继续发下一批。这种机制保证了数据不丢、不乱序,但也带来一个致命问题——当网络延迟很高的时候,整条链路就被“等待”卡住了。我把 TCP 比作一个每走两步就要停下来打电话报备的快递员,你把距离拉到一万公里之外,他大半时间都花在打电话上了。
Aspera 用的是一套叫 FASP 的协议,底层走的是 UDP。UDP 本来是个“莽夫”,不管对方收没收到,先发了再说。FASP 就是在这个基础上加入了拥塞控制、丢包重传和流量调度机制,让数据包像高速公路上的车队一样持续不断地冲过去,只在出现丢包时才精准地补偿,而不是像 TCP 那样动不动就“减速慢行”。我这几年用它下载数据最大的感受就是:只要网络链路本身能承受住,FASP 几乎能把本地的网卡带宽压到极限。
1.2 影响传输速度的真正变量
很多刚接触 Aspera 的朋友以为装了客户端就能快,其实不对。Aspera 快不快,起决定作用的是链路的带宽延迟积,简单说就是带宽越大、延迟越高,TCP 的劣势越是明显。国内访问欧洲的服务器,物理距离远、延迟动不动一百多毫秒,TCP 在这种场景下会非常难受,而 FASP 几乎不受影响。
所以 Aspera 特别适合两类场景:
- 跨大洲、跨国下载大型公共数据文件;
- 内部跨机房传输超大文件,比如数据库备份、影像资料、测序数据。
它的另一个重要特点是安全性。FASP 支持端到端加密,传输过程走 SSH 认证,公共数据库通常还会给你一个专门的数据访问账号和密钥文件。也就是说,Aspera 并不是简单把 FTP 换了层皮,而是从连接、认证到数据流整个重写了一套体系。
补充一句,Aspera 不是所有服务器都能用的,它要求服务端和客户端同时部署对应的软件。如果对方只开了普通的 FTP 端口,那该慢还是慢。
2. 先把 Aspera 客户端装好
2.1 Linux 下推荐用命令行版 ascp
Aspera 官方提供了好几种安装包,Windows 上有图形界面的 Aspera Connect,macOS 也有对应的桌面客户端,但真正适合批量下载、能写进脚本的,是命令行工具ascp。我用的一直是 Linux 服务器环境,最简单的安装方式就是下载 IBM Aspera Connect 的 RPM 包,解压之后就能拿到ascp可执行文件,剩下的事情就是把路径配好。
这里有一个细节:很多教程会让你下载 Aspera Connect 桌面版,但如果是给服务器用,我更建议直接用aspera-cli或者从 Connect 包里把ascp单独拷出来。Connect 装的是一整套浏览器插件和图形组件,服务器上根本用不到,反而容易把环境搞乱。我用的是从官方 RPM 包里解出来的ascp,用起来没有遇到过任何问题。
装好之后把软件路径加到环境变量里,验证一下版本号:
export PATH=$PATH:/path/to/aspera/connect/bin/ ascp --version只要能看到类似Aspera version 4.x.x的输出,说明客户端安装这步已经完成了。
2.2 密钥文件、账号与端口说明
接下来要搞明白三个东西:密钥文件、账号名、端口。
Aspera 的认证方式很特殊,它不走密码,而是用 SSH 密钥对。下载公共数据库的数据时,不同的数据库会给你不同的密钥文件,而且这些密钥文件通常就在安装包里已经自带了。我用过的几个典型例子:
- EBI 默认的密钥文件是
asperaweb_id_dsa.openssh; - NCBI 用的是同一个文件,但登录账号是
anonftp; - 有些内部渠道会单独提供专用密钥,比如
aspera01_id_rsa.openssh。
端口默认是33001,绝大多数公共服务器都默认开这个端口。如果发现连不上,第一步就要检查端口通不通,可以用telnet或者nc探测:
nc -zv ftp.ebi.ac.uk 33001密钥文件、登录名、主机地址这三样东西是 Aspera 下载命令里必不可少的。我建议把它们统一放到一个配置文件里,后面写批量脚本的时候引用起来非常方便。
3. 三个常见数据源的 Aspera 下载实例
3.1 EBI 数据库下载实操
EBI(欧洲生物信息学研究所)是我用得最多的数据源,它的 FTP 上存放了大量测序数据。EBI 开放了 Aspera 服务,登录用户名是固定的era-fasp,下载命令一般是这样的:
ascp -i ~/.aspera/connect/etc/asperaweb_id_dsa.openssh \ -Q -T -l 300m \ --host=ftp.ebi.ac.uk \ --user=era-fasp \ /vol1/fastq/SRR000/SRR000001/SRR000001_1.fastq.gz \ /local/data/这里解释一下参数:
-i指定密钥文件路径;-Q启用 FASP 的流量控制;-T表示不加密传输数据,只加密控制通道,公共数据一般不需要应用层加密,能节省不少 CPU 开销;-l 300m把最大传输带宽限制到 300 Mbps,如果链路很好可以开到更大;- 最后两个参数,一个是远程文件路径,一个是本地保存目录。
EBI 的 Aspera 服务有个特点:远程路径写的就是 FTP 目录结构下的路径,但进去之后要用era-fasp账号。我一开始踩过坑,直接用--host=ftp.ebi.ac.uk --user=era-fasp去连,结果怎么都登录不上,后来才发现路径前要加/vol1/...这层前缀。
3.2 NCBI 的 SRA 数据批量拉取
NCBI 的 SRA 数据库存放了海量高通量测序原始数据,我下载 SRA 文件时最早用wget和ftp,那个速度真的是让我一度怀疑机房带宽是假的。后来发现 NCBI 其实提供了 Aspera 通道,命令大概是:
ascp -i ~/.aspera/connect/etc/asperaweb_id_dsa.openssh \ -T -Q -l 300m -P 33001 \ anonftp@ftp.ncbi.nlm.nih.gov:/sra/sra-instant/reads/ByRun/sra/SRR/SRR100/SRR100001/SRR100001.sra \ .跟 EBI 不太一样的地方是,NCBI 的登录方式直接在命令行里写成anonftp@ftp.ncbi.nlm.nih.gov,主机地址不用单独给--host,但端口还是要用-P 33001。
对于测序数据这种动不动就几十 GB 的文件,SRA 官方还提供了一个叫prefetch的工具,底层也可以调用 Aspera。不过我实测下来,直接用ascp命令更灵活,尤其是在我要做批量脚本的时候。
3.3 其他支持 Aspera 的公共云存储
除了 EBI 和 NCBI,现在很多公共数据库都支持 Aspera 了。我接触比较多的还有 TCGA/ICGC 的 GDC 数据中心,以及一些云厂商提供的对象存储服务。GDC 那边用 Aspera 下载需要去申请一个 token,带 token 之后用ascp的参数跟 EBI 这类的写法差别不大。
更值得说的是 S3 兼容存储。Aspera 在较新版本中支持了 S3 的--file-manifest和--transfer-request这类高级参数,可以直接把数据传到 AWS S3 存储桶。这套机制对于需要把医疗影像、大型测序文件直接上云的项目非常有用,我以前帮朋友处理过一次,几千个文件批量传 S3,速度比 aws s3 cli 快了一个数量级。
4. 批量下载脚本的正确写法
4.1 准备文件清单
Aspera 是单条命令处理单个或单目录传输的,如果面对几千条下载任务,最直接的办法就是写一个循环脚本。我自己写脚本的习惯是先把所有下载任务整理成一个文本清单,每一行包含一个远程文件路径和一个本地保存文件名,中间用制表符分隔。比如:
/vol1/fastq/SRR000/SRR000001/SRR000001_1.fastq.gz srr000001_1.fastq.gz /vol1/fastq/SRR000/SRR000001/SRR000001_2.fastq.gz srr000001_2.fastq.gz /vol1/fastq/SRR000/SRR000002/SRR000002_1.fastq.gz srr000002_1.fastq.gz这样做的好处是脚本本身不用关心远程路径规则,只需要逐行解析。
4.2 串行下载与断点续传
批量下载最基础、最不容易出错的写法是串行循环:
#!/bin/bash KEY=~/.aspera/connect/etc/asperaweb_id_dsa.openssh USER=era-fasp HOST=ftp.ebi.ac.uk LIST=filelist.txt LOGFILE=download.log while IFS=$'\t' read -r remote local; do echo "$(date '+%Y-%m-%d %H:%M:%S') Downloading $remote" ascp -i "$KEY" -Q -T -l 300m \ --host="$HOST" --user="$USER" \ --overwrite=diff \ "$remote" "/data/$local" >> "$LOGFILE" 2>&1 if [ $? -eq 0 ]; then echo "$local OK" >> "$LOGFILE" else echo "$local FAILED" >> "$LOGFILE" fi done < "$LIST"这里有一个容易被忽略但极其关键的参数:--overwrite=diff。它表示如果本地已经有同名文件且大小一致,就跳过下载;如果文件不完整(比如上次中断了、大小不一致),就重新下载。配合--partial参数,ascp 还能把断点续传的文件合并,只补全缺失的数据块。我把这套逻辑称为“断电不慌下载法”,实测下来,一次大批量下载就算中途断网,重新跑一遍脚本,已经下载好的文件不会重复拉取,进度会跳过它们,直接继续。
4.3 并发下载与日志管理
串行下载虽然稳,但面对几百个文件时效率不够好。Aspera 单条 transfer 就能打满一条链路,但同时下载多个文件时,能不能并行取决于源服务器的带宽分配策略。从 EBI 这种大平台下载时,串行单通道往往跑不满网络带宽,所以我会用xargs做并发控制。
一个比较稳的并发设计是同时开 4 个下载进程:
cat filelist.txt | xargs -P 4 -I{} bash -c ' arr=(${1//$'"'"'\t'"'"'/ }); remote=${arr[0]}; local=${arr[1]}; ascp -i ~/.aspera/connect/etc/asperaweb_id_dsa.openssh -Q -T -l 100m \ --host=ftp.ebi.ac.uk --user=era-fasp \ --overwrite=diff \ "$remote" "/data/$local" ' _ {}并发数不是越大越好,4 到 8 个进程是最合适的,再高反而会因为争抢带宽出现丢包率上升,FASP 的拥塞控制会自动降速,最后总吞吐量并不见涨。
日志也要做到位。我的习惯是把每个文件的下载结果单独记录,包括下载耗时、文件大小、是否失败,这样后面排查问题时有据可查。如果某次下载因为网络抖动失败,整个脚本跑完后,我只需要从日志里提取FAILED的行,重新生成清单再跑一遍。
5. 下载性能调优与参数细节
5.1 常用参数组合分析
Aspera 的参数很多,但日常批量下载真正需要关注的也就下面这几个:
| 参数 | 作用 | 我的建议 |
|---|---|---|
-T | 关闭传输数据加密,只保留控制通道加密 | 公共数据下载强烈建议开启,能省下大量 CPU 开销 |
-Q | 启用 FASP 拥塞控制 | 日常下载保持开启 |
-l | 设置最大带宽,单位 Mbps | 网络环境好可以开到 500m 以上 |
-k | 设置断点续传数据块大小,比如-k 3 | 网络不稳时加上,中断恢复更快 |
--overwrite=diff | 仅覆盖不同文件,相同则跳过 | 批量下载强烈推荐 |
--partial | 支持断点续传及部分文件传输 | 与 overwrite 配合使用 |
--file-list | 指定文件清单 | 新版本支持的批量模式 |
关于-k参数我多说一句。它代表的是 checkpoint 的策略级别,不同的数值代表不同的检查间隔。在网络不稳定的环境下,-k 3能够减少重传工作量。但如果网络质量很好,-k反而会增加开销,这时可以不设置。
5.2 为什么不是线程越多越快
很多第一次使用 Aspera 的人会有一个误解:既然是“高速传输”,那我是不是开几十个线程就能更快?我从实际测试来看,完全不是这么回事。
Aspera 的底层是一套智能的拥塞控制算法,它会动态感知当前链路的丢包率和可用带宽。单条 FASP 流已经是一个被高度优化的流,它的目标就是把整条链路的带宽打满。如果你同时开 20 条流,每条流开始时都会各自去做带宽探测,最终的结果是 20 条流互相挤占,丢包率上去,整体的有效吞吐反而可能不如 4 条流。
我的经验是:
- 单文件大文件(几个 GB 以上):单链路下载即可,
-l开到带宽上限; - 大量小文件(几十 MB 每个):适度并发,4~8 路,效果最好;
- 网络抖动频繁:降低并发,调大
-l的余量,增加-k级别。
有一次我从 EBI 下载一个 300 GB 的项目集,用 8 路并发不到两个小时完成了,而同机房用 FTP 下载同样的数据我之前测过,大概需要两天多。这个差距真的不是一星半点。
6. 常见问题与排查技巧实录
6.1 下载失败的典型原因速查表
我整理了一个常见问题表,基本覆盖了日常会遇到的大部分情况:
| 问题现象 | 可能原因 | 处理方法 |
|---|---|---|
Session. The connection was rejected | 密钥文件不对 / 账号不对 / 端口不对 | 确认密钥路径、登录用户名,检查 33001 端口连通性 |
No such file or directory | 远程路径不存在 | 去 FTP 页面核对路径,注意 DC 目录结构变化 |
| 下载速度极慢 | 本地网络本身差 / 源服务器限速 | 检查到源机的iperf3吞吐,确认服务端分配的带宽上限 |
| 连接超时 | 防火墙拦截 UDP 流量 | 检查防火墙是否放行 UDP 大包、是否做了 QoS 限速 |
| 本地文件不完整 | 磁盘空间不足 / 下载被强杀 | 清理磁盘,重跑时用--overwrite=diff续传 |
Permission denied | 密钥文件权限过松,SSH 会拒绝加载 | 执行chmod 600 密钥文件,重新运行 |
其中 “密钥文件权限过松” 是一个特别隐蔽的坑。SSH 对私钥文件的权限要求极其严格,我之前有一次从服务器拷贝密钥到另一台机器,解压后权限变成了 644,结果 Aspera 怎么连都是 Permission denied,还以为是账号密码错了。后来把权限改成 600,立刻就好了。
6.2 排查思路的几条独家经验
经验一:遇到 Aspera 连接问题,先不要急着怀疑 Aspera 本身。我通常第一步是ping目标主机看延迟和丢包,第二步nc -zv 目标主机 33001看端口通不通。TCP 层都不通的话,Aspera 是肯定连不上的。
经验二:确认前一定要区分“服务器端控制通道”和“数据通道”。FASP 传输时,控制通道走 TCP,数据通道走 UDP。很多机房防火墙默认放行 TCP 但限制 UDP,这会导致你能连上服务器,但是数据传输非常慢甚至卡住不动。要检查本地出口 UDP 的丢包率,比较简单的办法是用mtr -u或者iperf3 -u做测试。
经验三:下载大批量数据时,不要在一次命令里放太多文件路径。ascp 的--file-list虽然能追踪一个长清单,但这类任务一旦中途出问题,重启后的日志分析很麻烦。我更倾向将清单拆成多个小批次,比如每个批次 50 个文件,跑完一批再跑下一批,这样可以把失败影响控制在最小范围。
经验四:服务器上配了防火墙并做了 SNAT(源地址转换)的情况下,大量 UDP 连接可能导致 conntrack 表溢出。如果多次下载都在高峰期失败,可以检查一下服务器的 conntrack 状态,适当调大net.netfilter.nf_conntrack_max值。
7. 批量下载后续处理与自动化
7.1 把下载任务嵌入定时流程
实际工作中,数据源往往不是一次性下载就完事,而是需要定期同步。比如每天凌晨去同步某个数据库的新增文件,或者每周把远程目录的新文件拉到本地归档。Aspera 的--overwrite=diff参数在这种增量同步场景下非常好用,因为只要本地文件已经存在且完整,它就会自动跳过。
我写过一套简单的定时同步脚本,核心流程是:
- 用
curl或者 FTP 方式远程获取最新文件清单; - 与本地文件清单比对,筛选出需要下载的文件;
- 调用 ascp 批量下载;
- 下载完成后做完整性校验(通常是检查文件大小或 md5);
- 校验通过后写入日志,更新同步状态文件。
整套逻辑用 cron 定时任务跑起来,基本能做到无人值守。特别要注意的是步骤 4,公共数据库的文件往往同时提供了md5校验文件,用 Aspera 下载完成后顺手校验一下,能避免很多隐藏的数据损坏问题。
7.2 结合 Python 写更灵活的任务调度
Bash 脚本够用,但遇到复杂业务逻辑时,我还是会更喜欢用 Python。比如需要根据元数据动态生成下载清单、需要重试多次、需要推送通知的场景,Python 写起来更顺手。
import subprocess import sys ASCP = "/path/to/ascp" KEY = "/path/to/asperaweb_id_dsa.openssh" HOST = "ftp.ebi.ac.uk" USER = "era-fasp" LIST = [ ("/vol1/fastq/SRR000/SRR000001/SRR000001_1.fastq.gz", "/data/"), ] def download(remote, local): cmd = [ ASCP, "-i", KEY, "-Q", "-T", "-l", "500m", "--host", HOST, "--user", USER, "--overwrite=diff", remote, local, ] result = subprocess.run(cmd, capture_output=True, text=True) return result.returncode == 0 for remote, local in LIST: ok = download(remote, local) print(remote, ok)这里我把每次下载的返回值都收集起来,后续可以接入短信、邮件或者企业微信机器人通知。我自己的习惯是,如果一批任务里有超过 3 个文件失败,就发告警通知有人工介入,不闷头重试。
8. 一些补充的想法
Aspera 是很成熟高效的传输方案,但我个人认为,它更值得我们学习的是一种思路——在网络传输中,协议的设计必须尊重现实环境。TCP 的可靠是针对通用场景的,但当带宽延迟积极高、传输数据量极大时,通用方案就未必是最优解。FASP 用 UDP 构建可靠传输,本质上是抛弃了“均质可靠”的假设,改用更精细的自适应控制,这是做系统设计时很值得借鉴的一点。
作为一个长期跟大数据打交道的人,我特别建议做数据工作的朋友早点把 Aspera 纳入工具箱。刚开始接触时,花点时间把命令行参数、密钥管理、批量脚本这几块基础打好,后面不管是从公共数据库拉数据,还是在跨机房同步、上云迁移的场景里,都能省下大把的时间。我个人现在最常用的组合是:Aspera 负责传输,md5sum负责校验,日志脚本负责追踪,一套跑下来基本不会再被下载问题折腾。