Multiple file upload into Amazon s3 bucket

2
Trịnh Minh Hung viết gần 5 năm trước

Đâ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

alt text

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é.

alt text

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.

alt text

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é.

alt text

3. Add trigger

Bây giờ thêm trigger, click add trigger

alt text

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.zip nhé.

alt text

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 :D

Bình luận


White
{{ comment.user.name }}
Hay Bỏ hay
{{ comment.like_count}}
White

Trịnh Minh Hung

73 bài viết.
1 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}

  Cùng một tác giả


{{like_count}}

kipalog

{{ comment_count }}

Bình luận


White
{{userFollowed ? 'Following' : 'Follow'}}
73 bài viết.
1 người follow

 Đầu mục bài viết

 Cùng một tác giả