Загрузите 2 миллиона файлов (каждый примерно 30 КБ из EC2 в S3) с помощью concurrent.futures, ThreadPool отнимает много времени - PullRequest
0 голосов
/ 23 июня 2019

У нас есть требование, когда нам нужно загрузить около 2 миллионов файлов (каждый примерно 30 КБ из экземпляра EC2 в S3).Мы используем модули python, boto3 и concurrent.futures, чтобы попытаться достичь этого.Ниже приведен псевдокод

import concurrent.futures
from concurrent.futures import ThreadPoolExecutor

class UploadToS3:

    def upload(self, file_path):
        try:
            s3 = boto3.resource('s3')
            bucket = s3.Bucket('xxxxxxxxxx')
            destination_file_path =  'yyyyy'
            bucket.upload_file(file_path,destination_file_path)
            del s3
        except (Exception)  as e :
            print(e)

    def upload_files(self, file_paths):
        with concurrent.futures.ThreadPoolExecutor(max_workers=2000) as executor:  
            tracker_futures = []  
            for file_path in file_paths:
                tracker_futures.append(executor.submit(self.upload,file_path)) 
        for future in concurrent.futures.as_completed(tracker_futures):
                tracker_futures.remove(future)
                del future

Однако мы выясняем, что мы можем загружать только ~ 78000 файлов в час. Увеличение количества потоков не имеет большого эффекта, мы считаем, что это из-за GIL, когдамы попытались использовать ProcessPoolExecutor, мы столкнулись с проблемами, потому что объекты boto3 не являются Pickable.Любые предложения о том, как преодолеть этот сценарий

1 Ответ

1 голос
/ 23 июня 2019

Исходя из моего общего опыта, это звучит довольно неплохо - ~ 21 файл в секунду.

Что может работать лучше, так это:

  • Сжать (или иным образом соединить) 2 миллиона файлов в один гигантский архивный файл.
  • Загрузите этот архивный файл в экземпляр EC2 в том же центре обработки данных AWS, что и корзина S3.
  • Разархивируйте файл в экземпляре EC2.
  • Запустите скрипт Python для экземпляра EC2.

Это сократит время в оба конца для каждой маленькой загрузки S3, так как все будет внутри AWS. Однако вы все равно можете ограничивать количество одновременных загрузок и / или количество загрузок в секунду.

В общем случае - от DOS до Windows, от Linux до S3 и т. Д. - множество и много маленьких файлов имеют тенденцию занимать лот дольше для обработки / загрузки / и т. Д. чем тот же объем данных в меньшем количестве больших файлов.

Хотя S3, кажется, работает лучше, чем во многих других системах, вы также можете подумать, если вы еще этого не сделали, настроить папки S3 так, чтобы 2 миллиона файлов не находились в (эквивалентном) одном каталоге. Однако это может или не может быть так легко сделать в зависимости от схемы именования файлов и конечного использования файлов.

...