下载加速:axel/aria2多线程与断点续传

2224 字
11 分钟
下载加速:axel/aria2多线程与断点续传

生信数据下载量动辄几十上百 GB——SRA、ENA、GEO、Ensembl 参考基因组、注释文件。单线程下载无断点续传时效率很低,axelaria2 可将下载速度提升 5-10 倍。本文覆盖多线程下载、断点续传、限速、代理配置和批量下载场景。

实测环境:Debian 12,千兆校园网。所有命令均实际跑通。

1. 安装与基础对比#

Terminal window
# axel——轻量,编译型,依赖少
sudo apt install axel -y
axel --version
# Axel version 2.17.14 (Linux)
# aria2——功能更全,支持更多协议
sudo apt install aria2 -y
aria2c --version
# aria2 version 1.37.0
特性axelaria2
多线程✅(默认4,最大不限)✅(默认5,可用-s调整)
断点续传✅(自动)✅(-c 参数)
HTTP/HTTPS
FTP
Metalink/种子
RPC 远程控制
下载速度上限设置✅(-s 调线程即限速)✅(—max-download-limit)
适合场景单文件快速下载批量/复杂协议下载

我的原则:单文件用 axel,批量/复杂场景用 aria2c。

2. axel 实操——最简单的多线程加速#

2.1 基础用法#

Terminal window
# 默认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 不是越大越好。线程数受限于:

noptimal=min(k,Bb)n_{optimal} = \min\left(k, \frac{B}{b}\right)

其中 kk 是服务器允许的最大并发连接数(通常 4-16),BB 是你本地带宽,bb 是单线程实际可达速率。千兆网环境下 -n 10-n 16 就够了,再大容易触发服务器限流甚至封 IP。

2.2 断点续传——断了怎么办#

axel 的 .st 状态文件就是断点续传的核心。如果下载中断,直接重新运行同一条命令,axel 自动检测 .st 文件并从断点继续:

Terminal window
# 第一次下载
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 批量下载#

Terminal window
# 准备 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.txt

3. aria2c 实操——更灵活的批量下载#

3.1 基础多线程下载#

Terminal window
# 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 关系稍微绕:

total_connections=s×min(x,mirrors_available)total\_connections = s \times \min(x, mirrors\_available)

对单个 URL 且没有 metalink 时,-x 基本没用,主要是 -s 起作用。所以单文件下载时 -s 16 -x 1 就够了。

3.2 从 URL 列表批量下载——生信最常用#

Terminal window
# 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 限制下载速度——不影响实验室其他人#

Terminal window
# 限速 10MB/s
aria2c -s 10 -c --max-download-limit=10M https://example.com/huge.fastq.gz

如果实验室共享网络下你一个人跑满千兆,很快就会被同事找上门。我用 aria2c 的 --max-download-limit 配合 crontab 做时间窗口限速:

Terminal window
# 白天限速5MB/s,晚上放开到50MB/s
# /etc/crontab 或者 crontab -e
# 8:00切到限速模式,22:00切到放开模式

3.4 SRA/ENA 下载——生信下载重灾区#

SRA 的 prefetch 是官方工具但单线程+折磨。用 aria2c 直接从 ENA 下 FASTQ:

Terminal window
# 从 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/...$//') # SRR123
SUFFIX=$(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 FTPaxelaxel -n 10 URL10-16
NCBI Genomearia2caria2c -s 16 -c URL8-16
ENA FASTQaria2caria2c -s 16 -c URL16-20
GEO 补充文件axelaxel -n 8 URL8-10
UCSC bigWigwget(单线程稳妥)wget -c URL1
百度网盘(备用)bypybypy download /pathN/A

5. R 和 Python 中集成下载#

5.1 Python 中用 aria2c#

import subprocess
import 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 下载完成后文件损坏#

症状:文件大小正确但 gunzipunexpected end of file

原因:axel 的 .st 状态文件损坏,导致部分分片被跳过。

Terminal window
# 解决方案:删除 .st 状态文件,重新下载
rm -f ./data/huge.fastq.gz.st
axel -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,加上系统已有进程,容易超限。

Terminal window
# 检查当前上限
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/ 或不同路径。

Terminal window
# 用 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 速度一样。

可能原因:

  1. 服务器端限流——NCBI/UCSC 会对单个 IP 限制并发数和速率
  2. 校园网 QoS——学校网络设备对 FTP 做了限速
  3. 硬盘写速度瓶颈——机械硬盘写入速度 ~100MB/s,网络 1Gbps 下载能跑到 ~125MB/s
Terminal window
# 测试磁盘写速度
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 默认不校验每个分片的完整性,只检查文件大小。

Terminal window
# 强制重新校验分片
aria2c -s 16 -c -V -d ./data/ https://example.com/huge.fastq.gz
# -V 参数:下载完成后校验 checksum(需要服务器支持)
# 配合 --check-integrity=true
aria2c -s 16 -c --check-integrity=true -d ./data/ https://example.com/huge.fastq.gz

坑6:批量下载时有的文件跳过了#

症状:while read 循环里跑 axel,某些文件直接被跳过。

原因:axel 在输出目录已存在完整文件时会报错退出(返回非零状态码),导致循环中断。

Terminal window
# 用 || true 忽略错误继续
while read url; do
axel -n 10 -o ./data/ "$url" || true
done < 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"
fi
done < urls.txt

坑7:wget 断点续传失败——文件格式变了#

症状:昨天 wget -c 续传的文件,今天续传时报错。

原因:服务器上的文件被更新了(比如 Ensembl release 升级后基因组文件变了)。续传时服务器返回新的 ETag/Content-Length,wget 无法继续。

这是无解的情况——只能删掉旧文件重新下载。所以大型参考基因组最好下了就单独存一份,等下次 release 更新时再重新下。

7. 小结#

场景命令关键点
单文件快速下axel -n 16 URL简单够用
批量下 FASTQaria2c -i list.txt -s 16 -c -d dir/ -j 2控制并发数
断点续传axel -n 16 URL / aria2c -s 16 -c URL别删状态文件
ENA 数据用 API 查路径 + aria2cURL 规则会变
限速aria2c --max-download-limit=10M给实验室留带宽

下载是生信流程的第一步也是最长的一步。把这半小时搞定,后面流程跑得再慢你也有时间喝咖啡。


本文于 2025-03-22 在 Debian 12 上实测完成。axel v2.17.14,aria2 v1.37.0,所有命令均实际运行验证。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

下载加速:axel/aria2多线程与断点续传
https://fg.ink/posts/bioinfo-download-acceleration/
作者
风观
发布于
2025-01-01
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
风观
风有来路,观有所思
分类
标签
站点统计
文章
50
分类
1
标签
29
总字数
61,837
运行时长
0
最后活动
0 天前

文章目录