Multiple file upload into Amazon s3 bucket
- Tháng Một 5, 2021
- Posted by: Le Thi Bich Ha
- Category: Technology
Đây là bài toán bulk upload (Với số lượng files lớn). Nếu bạn muốn upload hàng trăm files, ngàn files lên AWS S3 bucket, có 3 cách như sau:
- Upload one by one — tức là chỉ upload 1 thread, kiểu này thì đơn giản nhưng yêu cầu thời gian. Nếu bạn có 1000 files chẳng hạn, thì bạn cũng mất ít nhất 250 phút chẳng hạn. Too low.
- Upload asynchronously — đây là kiểu upload nhiều threads, ví dụ 100 files thì sẽ là 100 threads bất đồng bộ. Điều này yêu cầu về CPU và network usage. Chúng ta sẽ bị limit maximum số thread để cân bằng được performance của hệ thống.
- Zip all the files and upload into s3, then extract it — Tức là sẽ zip tất cả các files sau đó upload lên s3. Chúng ta sẽ sử dụng AWS Lambda service để extract file zip sau khi upload lên.
- Thực ra mình cũng nghĩ đến cách thứ 4 là kết hợp giữa cách thứ 1 và cách thứ 4. Tức là có 1000 files chẳng hạn, mình sẽ zip theo các nhóm file (100 file 1 zip) sau đó upload asynchronously. Để tận dụng được 2 điểm mạnh của 2 option trên là giảm kích thước file và tăng tốc quá trình upload nhanh chóng. Và cũng để tránh trường hợp timeout của lambda function nữa. Vì nó chỉ giới hạn là 15 phút thôi nha.
Bài viết này mình sẽ thực hành đơn giản option 3 thôi nhé. Đó là tạo và cấu hình Lamda Service để unzip file ở s3.
The following are the steps to create and configure Lambda service to unzip into the s3 buckets.
1. create an IAM role
Truy cập IAM console và select Lambda như hình nhé, click Next
Search s3
trong policy list và select AmazonS3FullAccess
và search lambda
và select AWSLambdaBasicExecutionRole
và click next. Bây giờ bạn sẽ thấy 1 page như dưới. Hãy nhập tên cho role nhé.
Bây giờ hãy click Create role
. Và bạn đã tạo thành công 1 role cho lamda service.
2. Create Lambda function
Mở Lambda console. Và tạo function. Click Create function
.
Bây giờ điền tên cho function, chọn ngôn ngữ nhé, ở đây mình sử dụng Python.
Trong phần permission hay lựa chọn Use and existing role
và chọn role đã tạo ở step 1 nhé.
Cuối cùng click create function nhé.
3. Add trigger
Bây giờ thêm trigger, click add trigger
Vì lambda function của chúng ta mục đích là unzip file từ s3 khi có file zip được upload lên. Vì vậy hãy select S3
sau đó chọn bucket mà bạn upload lên.
Select PUT
và event type.
Prefix – là folder name trong bucket mà chúng ta upload file zip lên nhé.
Lực chọn suffix
là .zip
nhé.
Bây giờ click add
để tạo trigger thôi.
4. Write the code in the lambda function
Code ở đây mình lựa chọn là code python. Với mục đích là unzip file. Mọi người có thể lựa chọn ngôn ngữ, nền tảng mà mình biết nhé. Như nodejs chẳng hạn.
import boto3
import string
import random
import os
import zipfile
def lambda_handler(event, context):
s3_resource= boto3.resource('s3')
s3_client= boto3.client('s3')
bucketName = event['Records'][0]['s3']['bucket']['name']
bucket = s3_resource.Bucket(bucketName)
zip_key = event['Records'][0]['s3']['object']['key']
chars=string.ascii_uppercase + string.digits
randomName = ''.join(random.choice(chars) for _ in range(8))
tmpFolder = '/tmp/' + randomName + '/'
os.makedirs(tmpFolder)
unzipTmpFile= randomName + '.zip'
attachmentFolder=''
extension = ".zip"
targetDirectory = 'folder-to-which-files-to-be-extracted'
s3_client.download_file(bucketName, zip_key, tmpFolder + unzipTmpFile)
dir_name = tmpFolder
os.chdir(dir_name)
for item in os.listdir(tmpFolder):
if item.endswith(extension):
file_name = os.path.abspath(item)
zip_ref = zipfile.ZipFile(file_name)
zip_ref.extractall(dir_name)
zip_ref.close()
os.remove(file_name)
mrssFiles = []
# r=root, d=directories, f = files
for r, d, f in os.walk(tmpFolder):
for file in f:
mrssFiles.append(os.path.join(r, file))
for file_name in mrssFiles:
s3_client.upload_file(file_name, bucketName, targetDirectory + '/' + file_name.replace(tmpFolder, '', 1))
os.remove(file_name)
return {
'statusCode': 200,
'body': zip_key
}
5. Testing
Để kiểm tra quá trình mình tạo có ok không. Hãy thử tự upload 1 file zip lên folder chứa file zip (bulk-upload
) của bucket và xem nó có extract thành file bạn cần không nhé. Và hãy thử map phần này vào phần code upload file s3 của project của bạn. Cũng như thử áp dụng option 4, kết hợp giữa multi upload (asynchronous) và zip file ở trên để đạt được performance tốt nhất nhé. Bài viết được tham khảo từ https://medium.com/@princekfrancis/multiple-file-upload-into-amazon-s3-bucket-9888d51001bb . Cảm ơn mọi người đã đọc bài 😀