Я пытаюсь реорганизовать существующую базу кода для загрузки нескольких файлов с S3. Если я правильно понимаю документацию, я выполняю слишком много запросов за короткий период времени (1), (2) и (3).
Глядя на документацию AWS SDK, кажется, что существует правильная реализация, как описано по адресу:
Однако пока мне не удалось его использовать. Я проверил страницу примера:
См. раздел «Загрузка или скачивание больших файлов» по адресу:
Кто-нибудь знает, как использовать AWS SDK (или альтернативу C#) для правильной загрузки нескольких файлов из S3 с использованием предварительно подписанных URL-адресов? У меня есть воспроизводимый случай, когда базовая настройка HTTP-клиента не удалась, поскольку количество файлов равно 7000.
Использованная литература:
@jarmod, не хочешь опубликовать реализацию предложения в качестве ответа? Следующий фрагмент кода мне не подходит.
вы можете клонировать корзину s3 в свой локальный каталог, который автоматически загрузит ваши видео.
Как сейчас написано, ваш ответ неясен. Пожалуйста, отредактируйте , чтобы добавить дополнительную информацию, которая поможет другим понять, как это относится к заданному вопросу. Более подробную информацию о том, как писать хорошие ответы, вы можете найти в справочном центре.
Да, работа с большим количеством файлов, например 7000, с использованием предварительно подписанных URL-адресов с помощью AWS SDK — не самый подходящий подход.
Вы можете использовать HttpClient
с Exponential Backoff
. Но перед этим вам необходимо будет указать все предварительно подписанные URL-адреса для каждого файла, который вы хотите загрузить.
HttpClient
поможет вам отправлять отдельные запросы на загрузку с каждым предварительно подписанным URL-адресом, а механизм повтора Exponential backoff
поможет повторить неудачные загрузки.
public async Task DownloadFilesWithBackoff(List<string> preSignedUrls)
{
int retryCount = 0;
TimeSpan delay = TimeSpan.FromSeconds(1);
foreach (string url in preSignedUrls)
{
using (var httpClient = new HttpClient())
{
HttpResponseMessage response;
while (true)
{
try
{
response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
break; // Success, exit loop
}
catch (HttpRequestException ex)
{
retryCount++;
Console.WriteLine($"Download failed (attempt {retryCount}): {ex.Message}");
if (retryCount >= 3) // Adjust retry limit as needed
{
throw; // Re-throw exception after exceeding retries
}
await Task.Delay(delay);
delay *= 2; // Increase delay for next attempt
}
}
// Process downloaded content from the response
}
}
}
Вы также можете рассмотреть возможность реализации многопоточности, которая поможет вам загружать файлы одновременно.
Я не голосовал против, но предполагаю, что причина, по которой это сделал кто-то другой, заключается в стратегии отсрочки. У .Net Foundation есть проект под названием Polly и его платформа отказов и толерантности с Retry и JittedBacksOffs, которая лучше вашей реализации. например stackoverflow.com/q/62913614/495455 но с алгоритмом JittedBackOff.
ИМО, вам следует контролировать запросы, а не полагаться на стратегии автоматической отсрочки, потому что в этой ситуации вы ЗНАЕТЕ, что они достигнут пределов. https://docs.aws.amazon.com/athena/latest/ug/ Performance-tuning-s3-throttling.html#:~:text=Amazon%20S3%20has%20a%20limit,be%20throttled%20by %20Amazon%20S3. AWS ограничивает вас со скоростью 5500 GET в секунду, что меньше вашего 7000 splat.
Поскольку у вас уже есть заранее назначенные URL-адреса, вам не нужно использовать какой-либо AWS SDK для фактического получения данных. Похоже, вы извлекаете данные из одного клиента, поэтому вам следует просто получать подмножество объектов в пакетном режиме, например. получить 1000 за раз.
Если это распространяется на 7000 отдельных клиентов, обращающихся к одному и тому же объекту S3, вам следует реализовать кэширование CloudFront + и использовать заранее назначенные URL-адреса CloudFront (а не URL-адреса s3) и позволить CF распределять запросы.
Вы не используете AWS SDK для получения объекта по заранее подписанному URL-адресу. Используйте стандартную библиотеку HTTP. При необходимости реализуйте собственную отсрочку/повторную попытку или найдите библиотеку, которая поможет.