Tập lệnh tải xuống nhiều tệp song song với sự hỗ trợ cho s3. //. http. //. https. // giao thức
Sự miêu tả
downloader.py
Cách sử dụng. python downloader.py url1 url2 url3
Cài đặt
hệ điều hành Mac. Một phiên bản Python đã được cài đặt
các cửa sổ. Bạn sẽ cần phải cài đặt một trong 2. phiên bản x có sẵn tại python. tổ chức
phụ thuộc
Một số gói Python bổ sung bắt buộc cần được cài đặt để chạy trên dòng lệnh. Dưới đây là danh sách các gói
AWS Boto3 là SDK Python dành cho AWS. Boto3 có thể được sử dụng để tương tác trực tiếp với tài nguyên AWS từ tập lệnh Python
API S3 của Boto3 không có bất kỳ phương pháp nào để tải xuống song song nhiều tệp từ một nhóm S3. Bạn có tùy chọn tải xuống từng tệp một nhưng điều đó tốn thời gian
Trong hướng dẫn này, chúng tôi sẽ xem xét cách chúng tôi có thể tải xuống nhiều tệp song song để tăng tốc quá trình tải xuống nhiều tệp từ S3
Mục lục
Đa xử lý và đa luồng Python
Có hai cách để tải xuống nhiều tệp song song
- đa xử lý
- đa luồng
Do khóa trình thông dịch toàn cầu [GIL] trong Python, Đa xử lý là cách thực sự duy nhất để đạt được chủ nghĩa thực dụng thực sự. Đa xử lý tận dụng nhiều CPU và lõi. Đa xử lý là lý tưởng khi các tác vụ bị ràng buộc bởi CPU
Mặt khác, đa luồng rất hữu ích khi các tác vụ bị ràng buộc IO. Phân luồng thường có dung lượng bộ nhớ thấp hơn và khả năng truy cập bộ nhớ dùng chung làm cho nó trở thành một lựa chọn tuyệt vời cho các ứng dụng liên kết I/O
Để hiểu chi tiết hơn về sự khác biệt giữa hai loại này, hãy xem chủ đề này trên Stackoverflow
Boto3 w/Đa luồng
Theo tài liệu Boto3, clients
an toàn cho luồng. Tuy nhiên, Tài nguyên và Phiên không an toàn cho luồng. Do đó, chúng tôi sẽ sử dụng client
cấp thấp để đảm bảo mã của chúng tôi an toàn cho luồng
Bài viết này đi sâu hơn vào sự khác biệt giữa Khách hàng và Tài nguyên
Tải xuống nhiều tệp bằng Đa xử lý
Chúng tôi sẽ tận dụng ProcessPoolExecutor
từ thư viện concurrent.futures
để tạo Nhóm quy trình nhằm tải xuống song song nhiều tệp từ S3
import boto3.session
from concurrent import futures
from concurrent.futures import ProcessPoolExecutor
from pathlib import Path
KEYS_TO_DOWNLOAD = [...] # all the files that you want to download
BUCKET_NAME = "my-test-bucket"
LOCAL_DOWNLOAD_PATH = "files/"
def download_object[file_name]:
"""Downloads an object from S3 to local."""
s3_client = boto3.client["s3"]
download_path = Path[LOCAL_DOWNLOAD_PATH] / file_name
print[f"Downloading {file_name} to {download_path}"]
s3_client.download_file[
BUCKET_NAME,
file_name,
str[download_path]
]
return "Success"
def download_parallel_multiprocessing[]:
with ProcessPoolExecutor[] as executor:
future_to_key = {executor.submit[download_object, key]: key for key in KEYS_TO_DOWNLOAD}
for future in futures.as_completed[future_to_key]:
key = future_to_key[future]
exception = future.exception[]
if not exception:
yield key, future.result[]
else:
yield key, exception
if __name__ == "__main__":
for key, result in download_parallel_multiprocessing[]:
print[f"{key}: {result}"]
Đầu ra của chương trình
Downloading sitemap.xml to files/sitemap.xml
Downloading feed.xml to files/feed.xml
Downloading robots.txt to files/robots.txt
Downloading index.html to files/index.html
index.html result: Success
robots.txt result: Success
sitemap.xml result: Success
feed.xml result: Success
Tải xuống nhiều tệp bằng Đa luồng
Chúng tôi sẽ sử dụng ThreadPoolExecutor
từ thư viện concurrent.futures
để tạo Nhóm luồng để tải xuống song song nhiều tệp từ S3. Không giống như ví dụ đa xử lý, chúng tôi sẽ chia sẻ máy khách S3 giữa các luồng vì đó là luồng an toàn
import boto3.session
from concurrent import futures
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
KEYS_TO_DOWNLOAD = [...] # all the files that you want to download
BUCKET_NAME = "my-test-bucket"
LOCAL_DOWNLOAD_PATH = "files/"
def download_object[s3_client, file_name]:
download_path = Path[DOWNLOAD_PATH] / file_name
print[f"Downloading {file_name} to {download_path}"]
s3_client.download_file[
BUCKET_NAME,
file_name,
str[download_path]
]
return "Success"
def download_parallel_multithreading[]:
# Create a session and use it to make our client
session = boto3.session.Session[]
s3_client = session.client["s3"]
# Dispatch work tasks with our s3_client
with ThreadPoolExecutor[max_workers=8] as executor:
future_to_key = {executor.submit[download_object, s3_client, key]: key for key in KEYS_TO_DOWNLOAD}
for future in futures.as_completed[future_to_key]:
key = future_to_key[future]
exception = future.exception[]
if not exception:
yield key, future.result[]
else:
yield key, exception
if __name__ == "__main__":
for key, result in download_parallel_multithreading[]:
print[f"{key} result: {result}"]
Đầu ra của việc chạy chương trình này là
Downloading feed.xml to files/feed.xml
Downloading index.html to files/index.html
Downloading robots.txt to files/robots.txt
Downloading sitemap.xml to files/sitemap.xml
sitemap.xml result: Success
index.html result: Success
robots.txt result: Success
feed.xml result: Success
Hiệu suất
Hiệu suất giữa Đa xử lý và Đa luồng tương tự nhau trong các thử nghiệm mà tôi đã chạy. Có một cải tiến đáng kể so với việc tải xuống từng tệp một