Как стать автором
Обновить
0
True Engineering
Лаборатория технологических инноваций

Облака на службе СМИ, или Как Amazon помогает обрабатывать большие объемы видеоконтента

Время на прочтение6 мин
Количество просмотров7.8K
Нашему заказчику, одному из крупнейших мировых издательств, потребовалось увеличить производительность приложения для публикации видео новостей в связи с возросшим объемом трафика. Пользователи приложения — редакторы media-ресурсов. В день через него проходит порядка 200 новостных роликов, средний размер каждого из них ~ 500 мб, итого около 100 Гб свежих новостей в сутки.

Сегодня мы поделимся опытом, как CloudFront и S3 помогли нам построить высоконагруженную и устойчивую систему обработки контента.



Надеемся, наш опыт заинтересует разработчиков/проектировщиков систем по хранению и обработке медиаконтента (видео, аудио, изображения) и технических специалистов, активно использующим сервисы AWS.


Определимся с инструментами и терминологией


Amazon Web Services предлагает набор сервисов для хранения и доставки контента, а их использование становится неотъемлемой частью современных IT платформ.



Предыстория — что мы выяснили?


Для создания видео новости редакторы, используя web интерфейс, загружают исходный видеофайл и заполняют форму с метаданными (описание, ключевые слова, тэги, категории и т. п.). После этого загруженная информация отправляется на обработку (конвертация видео в разные форматы, генерация субтитров и т. д.) в том числе при помощи сторонних сервисов.



Проанализировав архитектуру системы, мы выявили следующие узкие места:


#1 Проблема загрузки большого объема данных из разных точек земного шара
Систему используют редакторы из разных точек земного шара, а оригинальный видеоконтент имеет, как правило, весьма большой объем (сотни Mb для 10 минутного ролика). Процесс передачи данных, а стало быть и время их обработки и публикации, зависит от удаленности редактора от сервера приложений.

#2 Проблема нагрузки сервера
Загружаемое редакторами видео первым шагом попадает на сервер, где развернуто приложение. Далее нам требуется перекодировать это видео в различные форматы, добавить для него субтитры. Для этого мы используем сторонние сервисы обработки видео. Работа с каждым сервисом проходит по следующей схеме:



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

Что мы сделали?


В первую очередь, мы перешли к поиску решения проблемы нагрузки сервера. Для уменьшения объема передаваемой информации решили перенести хранение и раздачу контента на плечи сторонних файловых хранилищ или сервисов.
Мы рассматривали сервисы, которые удовлетворяли бы следующим основным критериям:
возможность стороним системам забирать контент на обработку;
возможность ограничивать доступ до контента как по времени, так и по ссылкам;
Первым основным кандидатом для нас стал AWS S3, который позволяет использовать подписанные урлы (детали -> docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html).

С использованием S3 процесс обработки контента сторонними сервисами меняется. Приложение теперь отправляет только ссылку на контент, сторонняя система забирает его самостоятельно из S3 по подписанной ссылке.



Но в нашем случае такой вариант не подходил, так как не решалась задача ускорения загрузки данных в хранилище.



Следующей альтернативой стал CDN CloudFront. В отличие от других популярных CDN, он позволяет, используя http-методы POST, PUT, DELETE, управлять контентом на S3, т.е. фактически CDN становится полноценной оберткой для своего источника-хранилища. CloudFront шлёт данные по оптимизированным маршрутам, использует постоянные соединения TCP / IP и ускоряет доставку контента ( aws.amazon.com/ru/about-aws/whats-new/2013/10/15/amazon-cloudfront-now-supports-put-post-and-other-http-methods).

Как видим, схема работы с сервисами обработки контента остается практически такой же, что и в случае с S3.



Но для пользователей системы все стало значительно лучше: контент загружается на ближайший CloudFront сервер быстрее, чем напрямую в хранилище S3.



Таким образом, мы убиваем сразу двух зайцев: быстрая загрузка данных и их сохранение напрямую в AWS S3, минуя сервер приложения и файловую систему.

В результате реструктуризации получаем следующую систему:
  • приложение видео-менеджер работает непосредственно только с метаданными;
  • исходные видеофайлы сохраняются напрямую с пользовательского интерфейса на S3 через CloudFront;
  • сторонние сервисы, которым нужен видеоконтент, получают его по подписанным ссылкам
через CloudFront.



Технические детали



Несколько ключевых моментов по конфигурации S3 и CloudFront
Конфигурация S3


Настройка CORS
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
	<CORSRule>
    	<AllowedOrigin>*</AllowedOrigin>
    	<AllowedMethod>GET</AllowedMethod>
    	<AllowedMethod>POST</AllowedMethod>
    	<AllowedMethod>PUT</AllowedMethod>
    	<AllowedHeader>*</AllowedHeader>
	</CORSRule>
</CORSConfiguration>


Настройка CloudFront

Настраиваем два distribution CloudFront'a на наш целевой S3-бакет. Первый нужен только для загрузки контента.
Ключевые конфигурации:

Origin Settings
Restrict Bucket Access - Yes;
Allowed Http Methods - GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE;	
Default Cache Behavior Settings
Restrict Viewer Access (Use Signed URLs) - Yes;
Trusted Signer - Self

Второй настраиваем для отдачи:
Origin Settings
Restrict Bucket Access - Yes;
Allowed Http Methods - GET, HEAD;
Default Cache Behavior Settings
Restrict Viewer Access (Use Signed URLs) - Yes;
Trusted Signer - Self


Интеграция с приложением


Работа на стороне пользователя


Для того чтобы новая схема взаимодействия заработала, пришлось решить несколько интеграционных задач.

Популярные загрузчики контента используют multipart/form-data, который не получится использовать с CloudFront, т.к. он не разбирает тело запроса, а сохраняет его как есть. Пришлось немного модифицировать плагин angular-file-upload (на проекте используется в основном AngularJS): для загрузки файла методом PUT использовали xhr.send(Blob) (детали тут -> dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#the-send%28%29-method).

Как выяснилось, загруженные таким образом файлы по умолчанию доступны AWS системе только для псевдо-пользователя cloudfront-identity и не доступны по подписанным урлам. Мы начали искать способ настроить права доступа для загружаемых файлов на AWS. Пришлось штудировать документацию и экспериментировать, т.к. в сети подобной информации крайне мало. В итоге установили, что права при загрузке файлов через CloudFront настраиваются http-заголовками S3 docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html.

Пример кода

Мы использовали angular-file-upload для загрузки файлов

Определяем FileUploader:
$scope.videoUploader = new FileUploader({
    	autoUpload: true,
    	method: "PUT",
    	useDirectUpload: true, // а это наша кастомизация для FileUploader - используем html5 XmlHttpRequest загрузка без FormData
    	headers: {
        	'x-amz-acl': 'authenticated-read' // тот самый magic header (http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html)
    	}
	});


Определяем handler для генерации конечной ссылки загрузки на cloudfront:
$scope.videoUploader.onBeforeUploadItem = function(item) {
    	$.ajax({
        	url: "base-url.com/file/generateUploadUrl", // генерируем подписанный урл для загрузки на CloudFront
        	type: 'GET',
        	data: {fileName: item.file.name, fileSize:item.file.size},
        	async: false,
        	success: function(data) {
            	item.url = data.uploadUrl; // выставляем аплоадеру полученный урл
        	}
    	});
	};


Определяем handler успешного окончания загрузки
$scope.videoUploader.onSuccessItem = function (item, response, status, headers) {
    	if (200 <= status && status < 300) {
    	… // некие действия, например, шлем серверу подтверждение загрузки файла.
}}



На сервере

Чтобы получить подписанную ссылку на скачивание файла, используем стандартный класс из AWS SDK com.amazonaws.services.cloudfront.CloudFrontUrlSigner .

Сгенерированные ссылки мы отдаём пользователям для заливки файлов на s3 или сервисам для их скачивания.

Пример кода

public class CloudFrontConfig {
   /**
    * for example http://get.example.cf.com/ or http://put.example.cf.com/
    */
   private String cloudFrontDomainNameForGet;
   private String cloudFrontDomainNameForPut;
  
   private String cloudFrontPrivateKey;
   private String cloudFrontKeyPairId;
  
   public String getDownloadUrlForUser(String s3key) throws Exception {
       return getSignedURL(cloudFrontDomainNameForGet, s3key);
   }

   public String getPutUrlForService(String s3key) throws Exception {
       return getSignedURL(cloudFrontDomainNameForPut, s3key);
   }

   private String getSignedURL(String domain, String s3Key) throws Exception {
       PrivateKey privateKey = loadPrivateKey(cloudFrontPrivateKey);

       Date dateLessThan = getDateLessThan();

       String url = CloudFrontUrlSigner.getSignedURLWithCannedPolicy(domain + s3Key,
               cloudFrontKeyPairId, privateKey, dateLessThan);
       return url;
   }

   private Date getDateLessThan() {
       LocalDateTime dateNow = LocalDateTime.now();
       ZonedDateTime zdt = dateNow.plusDays(1).atZone(ZoneId.systemDefault());
       return Date.from(zdt.toInstant());
   }

   private PrivateKey loadPrivateKey(String cloudFrontPrivateKey) {
       // конструируем объект PrivateKey с помощью приватного ключа
   }

}



Что мы получили в результате?



Редакторы издательства остались довольны обновленной системой: по их словам, она стала работать намного быстрее, что позволило ускорить выпуск новостей.

По статистике от AWS мы получили:
  • уменьшение входящего трафика на сервер с 3Tb до 1 Gb в месяц;
  • уменьшение исходящего трафика с сервера с 12Tb до 1 Gb в месяц;
  • размер используемой файловой системы уменьшился с 500Гб до 2Гб.


В итоге:
  • Мы оптимизировали загрузку и управление доступом к контенту посредством использования S3 и CloudFront;
  • Снизили сетевую и файловую нагрузку на сервере;
  • Написали статью :)
Теги:
Хабы:
Всего голосов 13: ↑10 и ↓3+7
Комментарии2

Публикации

Информация

Сайт
www.trueengineering.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия

Истории