為什么在內(nèi)存中下載比從AWS S3在文件系統(tǒng)中下載慢?
在下載文件時(shí),我們通常會選擇從AWS S3存儲桶中下載到本地文件系統(tǒng)。然而,有時(shí)候我們會發(fā)現(xiàn),使用內(nèi)存中的下載方式比直接從S3下載到文件系統(tǒng)要慢。這是因?yàn)樵趦?nèi)存中下載涉及到一些額外的步驟和資源消耗。首先,內(nèi)存中的下載需要將文件內(nèi)容讀取到內(nèi)存中,然后再將其寫入到文件系統(tǒng)中。這個(gè)過程中涉及到了額外的內(nèi)存操作和IO操作,相比直接從S3下載到文件系統(tǒng),會導(dǎo)致下載速度變慢。另外,內(nèi)存中的下載還可能受到內(nèi)存限制的影響,當(dāng)下載的文件較大時(shí),可能會導(dǎo)致內(nèi)存不足的問題,進(jìn)而影響下載速度。因此,在選擇下載方式時(shí),需要根據(jù)具體情況權(quán)衡利弊,選擇最適合的方式來進(jìn)行下載操作。
問題內(nèi)容
我正在使用aws gosdk從某個(gè)存儲桶下載。下面是下載的兩種實(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ù)制
對于 100 mb 的文件,下載到內(nèi)存中需要 30 秒,下載到文件系統(tǒng)中只需要 8 秒。我的期望是內(nèi)存下載應(yīng)該快得多。我的系統(tǒng)(apple m1、ventura、8gb ram)有足夠的可用 ram,所以這不是問題。有人可以幫助我理解這種行為嗎?
解決方法
將大的 S3 對象下載到動態(tài)緩沖區(qū)中效率非常低。該緩沖區(qū)被重新分配多次以處理 100M 數(shù)據(jù)和多個(gè)下載線程。內(nèi)存重新分配需要大量 CPU 時(shí)間。
嘗試在開始時(shí)分配 100M,而不是使用空字節(jié)片。
如果對象大小未知,您可以使用 S3.HeadObject 實(shí)時(shí)獲取對象長度。