為什么在內(nèi)存中下載比從AWS S3在文件系統(tǒng)中下載慢?
在下載文件時(shí),我們通常會(huì)選擇從AWS S3存儲(chǔ)桶中下載到本地文件系統(tǒng)。然而,有時(shí)候我們會(huì)發(fā)現(xiàn),使用內(nèi)存中的下載方式比直接從S3下載到文件系統(tǒng)要慢。這是因?yàn)樵趦?nèi)存中下載涉及到一些額外的步驟和資源消耗。首先,內(nèi)存中的下載需要將文件內(nèi)容讀取到內(nèi)存中,然后再將其寫(xiě)入到文件系統(tǒng)中。這個(gè)過(guò)程中涉及到了額外的內(nèi)存操作和IO操作,相比直接從S3下載到文件系統(tǒng),會(huì)導(dǎo)致下載速度變慢。另外,內(nèi)存中的下載還可能受到內(nèi)存限制的影響,當(dāng)下載的文件較大時(shí),可能會(huì)導(dǎo)致內(nèi)存不足的問(wèn)題,進(jìn)而影響下載速度。因此,在選擇下載方式時(shí),需要根據(jù)具體情況權(quán)衡利弊,選擇最適合的方式來(lái)進(jìn)行下載操作。
問(wèn)題內(nèi)容
我正在使用aws gosdk從某個(gè)存儲(chǔ)桶下載。下面是下載的兩種實(shí)現(xiàn)
-
下載到文件
func (a *awsclient) downloadtofile(ctx context.context, objectkey string) (string, error) {
params := &awss3.getobjectinput{
bucket: aws.string(a.bucket),
key: aws.string(objectkey),
}
downloadpath := "some/valid/path"
f, err := os.create(downloadpath)
defer f.close()
_, err = a.downloader.download(ctx, f, params)
return downloadpath, err
}
登錄后復(fù)制
-
下載到內(nèi)存
func (a *AwsClient) DownloadToMemory(ctx context.Context, objectKey string) (string, error) {
params := &awsS3.GetObjectInput{
Bucket: aws.String(a.bucket),
Key: aws.String(objectKey),
}
buffer := manager.NewWriteAtBuffer([]byte{})
_, err = a.downloader.Download(ctx, buffer, params)
return buffer.Bytes(), err
}
登錄后復(fù)制
對(duì)于 100 mb 的文件,下載到內(nèi)存中需要 30 秒,下載到文件系統(tǒng)中只需要 8 秒。我的期望是內(nèi)存下載應(yīng)該快得多。我的系統(tǒng)(apple m1、ventura、8gb ram)有足夠的可用 ram,所以這不是問(wèn)題。有人可以幫助我理解這種行為嗎?
解決方法
將大的 S3 對(duì)象下載到動(dòng)態(tài)緩沖區(qū)中效率非常低。該緩沖區(qū)被重新分配多次以處理 100M 數(shù)據(jù)和多個(gè)下載線程。內(nèi)存重新分配需要大量 CPU 時(shí)間。
嘗試在開(kāi)始時(shí)分配 100M,而不是使用空字節(jié)片。
如果對(duì)象大小未知,您可以使用 S3.HeadObject 實(shí)時(shí)獲取對(duì)象長(zhǎng)度。






