Caleb Blog

返回

1. 场景#

在现代大文件存储和传输场景中,尤其是云存储和对象存储服务中,大文件上传常常需要分片(multipart upload)策略以提升上传效率和容错能力。本研究关注以下场景:

  • 文件大小从几 MB 到数 TB 不等
  • 对分片上传的效率、并发处理和服务器端限制敏感
  • 需要在上传速度、分片数量和系统资源消耗之间进行平衡

2. 目的#

  1. 分析现有大文件上传的分片策略与优缺点
  2. 提出针对不同大小文件的分片优化方案
  3. 提供一个可编程的算法实现,实现上传效率最大化,同时保证系统稳定性

3. 常规分片方案#

3.1 固定分片大小#

  • 说明:上传时每个文件切成固定大小分片,例如 5MB、50MB 或 100MB。
  • 优点:实现简单,易于并行处理。
  • 缺点:对于非常大或非常小的文件,可能导致分片数量过多或过少,影响性能或上传稳定性。

3.2 动态分片策略#

  • 说明:根据文件大小动态计算分片大小,尝试保持分片数量在合理范围。
  • 优点:平衡上传并发、服务器负载和传输效率。
  • 缺点:算法复杂度高,边界条件(超大文件或超小文件)需要额外处理。

3.3 云厂商推荐策略#

  • AWS S3、阿里云 OSS 等均推荐:
    • 最小分片 5MB
    • 最大分片 500MB
    • 最大分片数 10,000
  • 对超大文件,通常直接建议使用较大分片(例如 500MB),避免分片数超过上限。

4. 提出的优化想法#

针对不同大小文件,提出如下策略:

  1. 小文件(<=5MB):直接作为单片上传,避免无意义的分片开销。
  2. 中等文件:根据目标分片数(如 100 片)动态计算分片大小,保证上传并发和效率平衡。
  3. 超大文件(>50,000MB):直接采用最大分片大小(500MB),确保分片数不超过系统上限,同时提升上传效率。
  4. 边界调整:确保分片大小始终在最小 5MB 与最大 500MB 之间,防止出现分片数量过多或过少的异常情况。

5. 方法与实现#

  • 语言:Go
  • 核心算法
    1. 根据文件大小计算初步分片大小
    2. 检查是否满足最小/最大分片约束
    3. 对超大文件直接设置最大分片
    4. 分片数量向上取整计算,确保覆盖整个文件
    5. 超过最大分片数的情况返回异常提示

6. 未来优化#

智能分片预测:结合网络带宽和服务器负载动态调整分片大小。

8. 附录#

  • Go 示例函数

    func CalcOptimalPart(fileSize int64) (partSize int64, partCount int) {
    	const (
    		MinPartSize int64 = 5 * 1024 * 1024   // 5MB
    		MaxPartSize int64 = 500 * 1024 * 1024 // 500MB
    		MaxParts    int64 = 10000
    		MinFileSize int64 = 30 * 1024 * 1024 // 30MB,小文件直接 1 片
    	)
    
    	// 对于小文件,直接返回 1 片
    	if fileSize <= MinFileSize {
    		return fileSize, 1
    	}
    
    	// 根据文件大小动态确定目标分片数
    	var targetParts int64
    	switch {
    	case fileSize <= 100*1024*1024: // <=100MB
    		targetParts = 5 + fileSize/(10*1024*1024) // 小文件分片数 5~10
    	case fileSize <= 1*1024*1024*1024: // <=1GB
    		targetParts = 10 + fileSize/(100*1024*1024) // 中等文件 10~50
    	case fileSize <= 10*1024*1024*1024: // <=10GB
    		targetParts = 50 + fileSize/(500*1024*1024) // 大文件 50~200
    	default:
    		targetParts = 200 + fileSize/(1*1024*1024*1024) // 超大文件
    	}
    
    	// 计算分片大小
    	partSize = (fileSize + targetParts - 1) / targetParts
    
    	// 限制在最小/最大范围
    	if partSize < MinPartSize {
    		partSize = MinPartSize
    	}
    	if partSize > MaxPartSize {
    		partSize = MaxPartSize
    	}
    
    	// 计算分片数量
    	partCount64 := (fileSize + partSize - 1) / partSize
    	if partCount64 > MaxParts {
    		return 0, 0
    	}
    	partCount = int(partCount64)
    	return partSize, partCount
    }
    go
S3 Multipart Upload 分片大小分配优化
https://see.ckangle.com/blog/dev-notes/s3-dynamic-chunking
作者 Caleb
发布日期 October 21, 2025
Comment seems to stuck. Try to refresh?✨