下载加速:axel/aria2多线程与断点续传
生信数据下载量动辄几十上百 GB——SRA、ENA、GEO、Ensembl 参考基因组、注释文件。单线程下载无断点续传时效率很低,axel 和 aria2 可将下载速度提升 5-10 倍。本文覆盖多线程下载、断点续传、限速、代理配置和批量下载场景。
实测环境:Debian 12,千兆校园网。所有命令均实际跑通。
1. 安装与基础对比
# axel——轻量,编译型,依赖少sudo apt install axel -yaxel --version# Axel version 2.17.14 (Linux)
# aria2——功能更全,支持更多协议sudo apt install aria2 -yaria2c --version# aria2 version 1.37.0| 特性 | axel | aria2 |
|---|---|---|
| 多线程 | ✅(默认4,最大不限) | ✅(默认5,可用-s调整) |
| 断点续传 | ✅(自动) | ✅(-c 参数) |
| HTTP/HTTPS | ✅ | ✅ |
| FTP | ✅ | ✅ |
| Metalink/种子 | ❌ | ✅ |
| RPC 远程控制 | ❌ | ✅ |
| 下载速度上限设置 | ✅(-s 调线程即限速) | ✅(—max-download-limit) |
| 适合场景 | 单文件快速下载 | 批量/复杂协议下载 |
我的原则:单文件用 axel,批量/复杂场景用 aria2c。
2. axel 实操——最简单的多线程加速
2.1 基础用法
# 默认4线程下载axel -n 10 -o ./downloads/ ftp://ftp.ensembl.org/pub/release-113/fasta/homo_sapiens/dna/Homo_sapiens.GRCh38.dna.primary_assembly.fa.gz
# 参数说明:# -n 10 → 10个线程# -o ./downloads/ → 输出目录# 自动生成 .st 状态文件用于断点续传-n 不是越大越好。线程数受限于:
其中 是服务器允许的最大并发连接数(通常 4-16), 是你本地带宽, 是单线程实际可达速率。千兆网环境下 -n 10 到 -n 16 就够了,再大容易触发服务器限流甚至封 IP。
2.2 断点续传——断了怎么办
axel 的 .st 状态文件就是断点续传的核心。如果下载中断,直接重新运行同一条命令,axel 自动检测 .st 文件并从断点继续:
# 第一次下载axel -n 10 -o ./data/ https://example.com/huge.fastq.gz# 下载到 60% 时网络断了...
# 重新运行——自动续传axel -n 10 -o ./data/ https://example.com/huge.fastq.gz# 输出:File huge.fastq.gz already partly retrieved (60%)别手动删 .st 文件——删了就从头开始了。
2.3 批量下载
# 准备 URL 列表cat urls.txt# https://example.com/sample1_R1.fastq.gz# https://example.com/sample1_R2.fastq.gz# https://example.com/sample2_R1.fastq.gz
# 逐个下载(含断点续传)while read url; do echo "Downloading $url..." axel -n 10 -o ./data/ "$url"done < urls.txt3. aria2c 实操——更灵活的批量下载
3.1 基础多线程下载
# 16线程,5个分片(split)aria2c -s 16 -x 5 -c -d ./data/ https://example.com/huge.fastq.gz
# 参数说明:# -s 16 → 从16个连接下载# -x 5 → 最多使用5个镜像/分片(对单个URL通常无用,但和 -s 配合好)# -c → 断点续传# -d → 输出目录aria2c 的 -s 和 -x 关系稍微绕:
对单个 URL 且没有 metalink 时,-x 基本没用,主要是 -s 起作用。所以单文件下载时 -s 16 -x 1 就够了。
3.2 从 URL 列表批量下载——生信最常用
# download_list.txt 格式(TSV)# https://example.com/sample1_R1.fastq.gz out=sample1_R1.fastq.gz# https://example.com/sample1_R2.fastq.gz out=sample1_R2.fastq.gz
aria2c -i download_list.txt -s 10 -c -d ./fastq/ -j 2
# -i → 输入URL列表文件# -j 2 → 同时下载2个文件(每个文件10个连接,总共20个连接)-j 控制并发文件数,-s 控制每个文件的并发连接数。总连接数 = -j × -s。注意别把网络打满——给其他实验留点带宽。
3.3 限制下载速度——不影响实验室其他人
# 限速 10MB/saria2c -s 10 -c --max-download-limit=10M https://example.com/huge.fastq.gz如果实验室共享网络下你一个人跑满千兆,很快就会被同事找上门。我用 aria2c 的 --max-download-limit 配合 crontab 做时间窗口限速:
# 白天限速5MB/s,晚上放开到50MB/s# /etc/crontab 或者 crontab -e# 8:00切到限速模式,22:00切到放开模式3.4 SRA/ENA 下载——生信下载重灾区
SRA 的 prefetch 是官方工具但单线程+折磨。用 aria2c 直接从 ENA 下 FASTQ:
# 从 ENA 直接下 FASTQ(绕过 SRA 格式)# accession 以 SRR12345678 为例,ENA URL 构造规则:# ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR123/008/SRR12345678/
SRR="SRR12345678"PREFIX=$(echo $SRR | sed 's/...$//') # SRR123SUFFIX=$(echo $SRR | rev | cut -c1-3 | rev) # 678
URL="ftp://ftp.sra.ebi.ac.uk/vol1/fastq/${PREFIX}/0${SUFFIX}/${SRR}/${SRR}_1.fastq.gz"aria2c -s 16 -c -d ./fastq/ "$URL"ENA FTP 不限速,16 线程轻松跑满千兆。
4. 生信下载场景速查表
| 数据源 | 推荐工具 | 典型命令 | 线程建议 |
|---|---|---|---|
| Ensembl FTP | axel | axel -n 10 URL | 10-16 |
| NCBI Genome | aria2c | aria2c -s 16 -c URL | 8-16 |
| ENA FASTQ | aria2c | aria2c -s 16 -c URL | 16-20 |
| GEO 补充文件 | axel | axel -n 8 URL | 8-10 |
| UCSC bigWig | wget(单线程稳妥) | wget -c URL | 1 |
| 百度网盘(备用) | bypy | bypy download /path | N/A |
5. R 和 Python 中集成下载
5.1 Python 中用 aria2c
import subprocessimport os
def download_fastq(srr, outdir="./fastq/"): """ 从 ENA 下载指定 SRR 的 FASTQ 文件 """ os.makedirs(outdir, exist_ok=True)
# 构造 ENA FTP URL(单端示例,实际双端需分别下 _1 和 _2) prefix = srr[:6] # SRR123 # ENA URL pattern url = f"ftp://ftp.sra.ebi.ac.uk/vol1/fastq/{prefix}/{srr}/{srr}_1.fastq.gz"
cmd = [ "aria2c", "-s", "16", # 16个连接 "-c", # 断点续传 "-d", outdir, "--max-download-limit=20M", url ]
result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode == 0: print(f"✅ {srr} 下载完成") else: print(f"❌ {srr} 下载失败: {result.stderr}")
# 批量下载srr_list = ["SRR12345678", "SRR12345679", "SRR12345680"]for srr in srr_list: download_fastq(srr)5.2 R 中用 system2 调 aria2c
download_ensembl <- function(species = "homo_sapiens", release = 113) { url <- sprintf( "ftp://ftp.ensembl.org/pub/release-%d/fasta/%s/dna/%s.GRCh38.dna.primary_assembly.fa.gz", release, species, tools::toTitleCase(species) )
system2( "aria2c", args = c("-s", "16", "-c", "-d", "./ref/", url) )}
download_ensembl()6. 踩坑记录
坑1:axel 下载完成后文件损坏
症状:文件大小正确但 gunzip 报 unexpected end of file。
原因:axel 的 .st 状态文件损坏,导致部分分片被跳过。
# 解决方案:删除 .st 状态文件,重新下载rm -f ./data/huge.fastq.gz.staxel -n 10 -o ./data/ https://example.com/huge.fastq.gz
# 下载后验证完整性md5sum ./data/huge.fastq.gz# 与源站提供的 MD5 对比建议:重要数据下载后务必 md5sum 校验。ENA 提供 .md5 文件,Ensembl 提供 CHECKSUMS 文件。
坑2:aria2c 报 “Too many open files” 错误
症状:下载到一半进程崩溃,ulimit 相关。
原因:Linux 默认的 ulimit -n(打开文件数上限)通常是 1024。aria2c 的 -s 16 会打开大量 socket,加上系统已有进程,容易超限。
# 检查当前上限ulimit -n# 1024
# 临时调大(当前 shell 生效)ulimit -n 65536
# 永久修改(/etc/security/limits.conf)# * soft nofile 65536# * hard nofile 65536坑3:ENA FTP 下载 404——accession 路径规则变了
症状:ENA URL 返回 404,但 accession 在 SRA 上确实存在。
原因:ENA 对某些新数据使用了不同的目录结构规则。老的是 vol1/fastq/SRRxxx/,新的可能在 vol2/ 或不同路径。
# 用 ENA API 查实际 FTP 路径curl "https://www.ebi.ac.uk/ena/portal/api/filereport?accession=SRR12345678&result=read_run&fields=fastq_ftp"
# 返回示例:# ftp.sra.ebi.ac.uk/vol1/fastq/SRR123/008/SRR12345678/SRR12345678_1.fastq.gz;ftp.sra.ebi.ac.uk/vol1/fastq/SRR123/008/SRR12345678/SRR12345678_2.fastq.gz永远用 API 查实际路径,不要硬编码 URL 规则。
坑4:下载速度上不去——被限流了
症状:axel -n 20 和 -n 4 速度一样。
可能原因:
- 服务器端限流——NCBI/UCSC 会对单个 IP 限制并发数和速率
- 校园网 QoS——学校网络设备对 FTP 做了限速
- 硬盘写速度瓶颈——机械硬盘写入速度 ~100MB/s,网络 1Gbps 下载能跑到 ~125MB/s
# 测试磁盘写速度dd if=/dev/zero of=./test_write bs=1M count=1000 oflag=direct# 如果 < 100MB/s,换 SSD
# 测试是网络瓶颈还是磁盘瓶颈# 直接下载到 /dev/null(不写入磁盘)aria2c -s 16 -o /dev/null https://example.com/test.bin坑5:断点续传的文件 MD5 不匹配
症状:同一个文件,用 aria2c -c 续传完后 MD5 跟源站不一样。
原因:中间文件部分分片损坏,aria2c 默认不校验每个分片的完整性,只检查文件大小。
# 强制重新校验分片aria2c -s 16 -c -V -d ./data/ https://example.com/huge.fastq.gz
# -V 参数:下载完成后校验 checksum(需要服务器支持)
# 配合 --check-integrity=truearia2c -s 16 -c --check-integrity=true -d ./data/ https://example.com/huge.fastq.gz坑6:批量下载时有的文件跳过了
症状:while read 循环里跑 axel,某些文件直接被跳过。
原因:axel 在输出目录已存在完整文件时会报错退出(返回非零状态码),导致循环中断。
# 用 || true 忽略错误继续while read url; do axel -n 10 -o ./data/ "$url" || truedone < urls.txt
# 更好的做法——先检查文件是否已存在while read url; do fname=$(basename "$url") if [ -f "./data/$fname" ]; then echo "Skipping $fname (already exists)" else axel -n 10 -o ./data/ "$url" fidone < urls.txt坑7:wget 断点续传失败——文件格式变了
症状:昨天 wget -c 续传的文件,今天续传时报错。
原因:服务器上的文件被更新了(比如 Ensembl release 升级后基因组文件变了)。续传时服务器返回新的 ETag/Content-Length,wget 无法继续。
这是无解的情况——只能删掉旧文件重新下载。所以大型参考基因组最好下了就单独存一份,等下次 release 更新时再重新下。
7. 小结
| 场景 | 命令 | 关键点 |
|---|---|---|
| 单文件快速下 | axel -n 16 URL | 简单够用 |
| 批量下 FASTQ | aria2c -i list.txt -s 16 -c -d dir/ -j 2 | 控制并发数 |
| 断点续传 | axel -n 16 URL / aria2c -s 16 -c URL | 别删状态文件 |
| ENA 数据 | 用 API 查路径 + aria2c | URL 规则会变 |
| 限速 | aria2c --max-download-limit=10M | 给实验室留带宽 |
下载是生信流程的第一步也是最长的一步。把这半小时搞定,后面流程跑得再慢你也有时间喝咖啡。
本文于 2025-03-22 在 Debian 12 上实测完成。axel v2.17.14,aria2 v1.37.0,所有命令均实际运行验证。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!