Việc lưu trữ và quản lý file trên đám mây đã trở thành một phần quan trọng trong quá trình phát triển ứng dụng. Việc upload nhiều files đồng thời không chỉ giúp tiết kiệm thời gian mà còn tối ưu hiệu suất, đặc biệt quan trọng đối với các ứng dụng yêu cầu xử lý lượng lớn dữ liệu.
Giả sử chúng ta có 1000 files cần upload lên S3 Storage.
Thông thường, chúng ta sẽ làm như sau:
foreach ($uploadFiles as $uploadFile) {
$response = $this->s3StorageClient->putObject([
'Bucket' => ****,
'Key' => $uploadFile['filename'],
'SourceFile' => $uploadFile['content'],
'ACL' => 'public-read'
// ....
]);
}
Theo cách trên, nếu chúng ta upload 10 files thì sẽ mất 10 lần để xử lý putObject, nếu upload 1000 files thì sẽ lần lượt xử lý putObject 1000 lần.
Để giải quyết việc này, AWS PHP SDK có cung cấp một class CommandPool, class này có thể thực thi nhiều lệnh AWS cùng lúc.
$commands = [];
foreach ($uploadFiles as $uploadFile) {
$commands[] = $this->s3StorageClient->getCommand('PutObject', [
'Bucket' => ****,
'Key' => $uploadFile['filename'],
'SourceFile' => $uploadFile['content'],
'ACL' => 'public-read'
]);
}
Đầu tiên, không thực thi lệnh putObject trong vòng lặp mà hãy sử dụng getCommand để tạo lệnh cho putObject và lưu trữ nó trong một mảng.
Sau đó, bạn có thể dễ dàng thực thi các lệnh đồng thời bằng cách đưa s3 instance và mảng commands được vào phương thức CommandPool::batch.
CommandPool::batch($this->s3StorageClient, $commands);
Ở đây chúng ta có thể lấy files đồng thời sau khi gọi hàm CommandPool::batch
$responses = CommandPool::batch($this->s3StorageClient, $commands);
foreach ($responses as $response) {
// code here
}
Em cũng đã triển khai cách trên áp dụng vào dự án và cũng khá hiệu quả về performance.
Đối với những bài toán upload số lượng files lên đến hàng trăm nghìn, hàng triệu, chúng ta có thể zip từng nhóm files rồi thực hiện upload đồng thời theo cách trên, nhưng cần sử dụng thêm một service để giải nén file zip sau khi upload (AWS Lambda chẳng hạn).
Tài liệu tham khảo: