Статьи

Пример использования — как Last.fm использует HornetQ для своей потоковой инфраструктуры

В этом примере описывается, как Last.fm использует HornetQ для повышения производительности и доступности своей потоковой инфраструктуры.

Что такое Last.fm?

Last.fm — это онлайновый музыкальный сервис, который отслеживает музыку, которую слушают люди, и генерирует рекомендации и пользовательские онлайн-радиостанции на основе этой информации. Это позволяет пользователю отслеживать песню, которую он слушает (путем скробблирования песни) с интернет-радиостанции, музыкального плеера или портативного устройства. Мошенники передаются на Last.fm и отображаются на странице профиля пользователя. Каждый трек, который проигрывает пользователь, говорит Last.fm о том, что ему или ей нравится. Он может связать пользователя с другими людьми, которым нравится та же песня, исполнитель, жанр и т. Д., И рекомендовать другие песни из своих музыкальных коллекций.
Более 40 миллионов уникальных пользователей посещают Last.fm каждый месяц и просматривают 500 миллионов страниц.
С момента запуска сервиса было зарегистрировано более 40 миллиардов мошенников. В настоящее время происходит 40 миллионов скробблов в день (до 800 в секунду на пике).

Инфраструктура Last.fm использует JMS , стандарт Java для службы сообщений, для управления своей службой потоковой передачи.

Недавно Last.fm перешел на HornetQ, чтобы улучшить службу обмена сообщениями и обеспечить ее качество, ожидаемое их пользователями.

Что такое HornetQ?

HornetQ — это проект сообщества от JBoss , подразделения промежуточного программного обеспечения Red Hat . HornetQ является службой обмена сообщениями по умолчанию для JBoss Application Server 6 и может также использоваться в качестве автономного сервера JMS или встраиваться в любое приложение Java. HornetQ — это проект с открытым исходным кодом (лицензированный Apache) для создания многопротокольной, встраиваемой, кластерной системы обмена сообщениями с очень высокой производительностью и доступностью.

Имея некоторые проблемы со своим текущим сервером обмена сообщениями, Last.fm заинтересовался интеграцией HornetQ в свою инфраструктуру для повышения производительности и доступности, сохраняя при этом аппаратные ресурсы под контролем.

Инфраструктура Last.fm

Бэкэнды Last.fm написаны как на C ++, так и на Java, причем последний используется для его потоковой инфраструктуры. Бэкэнды потоковой передачи Java состоят из веб-приложения, развернутого в Tomcat ( менеджер стримеров ) и автономных приложений Java ( стримеры ).

Стримеры разработаны так, чтобы быть простыми с минимальным количеством зависимостей, не требуя контейнеров вообще. Архитектурно, они независимы от остальной инфраструктуры Last.fm Они используют JMS для связи внутри себя и с другими частями инфраструктуры в слабосвязанной форме.

Для своей потоковой инфраструктуры Last.fm использует JMS в трех разных случаях.

Стример Контроль

Управляющие сообщения стримера используются при обновлении стримеров. Стримеры отправляют управляющие сообщения в очередь / queue / ControlQueueJMS, когда они запускаются или выключаются. Диспетчер стримеров будет использовать эти сообщения и соответственно начнет или прекратит отправку трафика на стримеры.
Это создает низкий объем сообщений (несколько сообщений в месяц).

Радио Слушай

Каждый раз, когда пользователь заканчивает прослушивание песни, от стримера отправляется сообщение радиоуправления в очередь JMS / queue / radioListenQueue. При получении этих сообщений менеджер стримеров обновляет базу данных. Это позволяет ограничить пользователей без подписки на определенное количество бесплатных прослушиваний.
Это генерирует большое количество сообщений (каждый раз, когда пользователь заканчивает слушать песню)

Контроль соединения

Каждый стример ведет список подключенных к нему пользователей. Когда пользователь запускает поток, сообщение управления подключением отправляется в раздел JMS / topic / connectionControl, на который подписаны все другие стримеры. Когда пользователь начинает слушать песню, об этом сообщают все стримеры, и стример, с которого пользователь ведет потоковую передачу, сохраняет идентификатор. Если пользователь затем попытается открыть второй поток, второй стример поместит идентификатор в тему, тогда первый стример подберет его и увидит, что пользователь уже подключен к нему, и отключит его. Это эффективно ограничивает пользователей одним потоком за раз.
Стримеры используют топологию публикации / подписки, поэтому каждый стример получает сообщения об управлении соединением, отправленные всеми из них.

На приведенной выше диаграмме Дэвид уже подключен к стримеру # 2, а затем пытается подключиться к другому стримеру.

  1. Streamer # 1 получает новый запрос на подключение от David
  2. Streamer # 1 уведомляет JMS / topic / connectionControl
  3. Все стримеры (которые подписаны на тему) информируются о том, что Дэвид запросил новое соединение
  4. Streamer # 2 замечает, что он уже обслуживает Дэвида, и сбрасывает соединение.
    В это же время стример №1 начинает обслуживать Дэвида

Like the radio scenario, this generates a high volume of messages.
The number of messages is directly proportional to the amount of listening traffic as each new connection request results in a message to the topic. As Last.fm increases the number of physical streamer boxes, they also increase the number of subscribers and consumers on the topic (each streamer acting as both roles). The JMS message volume follows the daily/weekly/monthly streaming traffic peaks and will also increase over time as Last.fm expand their streaming capacity. JMS scalability is a main requirement for Last.fm. By switching to HornetQ, they except its performance and scalability to meet their needs as their streaming capacity grows.

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

Требования и настройки Last.fm

Основные требования Last.fm к их потоковой инфраструктуре — максимальное время безотказной работы и контроль аппаратных ресурсов (использование памяти, процессора и диска) . В худшем случае они предпочитают потерять сообщения, чем что-либо вылетать или мешать обслуживать запросы пользователей.

Отключить постоянство

Чтобы увеличить время безотказной работы и стабильное использование ресурсов, они отключили сохранение сообщений в конфигурации сервера HornetQ. Это гарантирует, что HornetQ не записывает никаких сообщений на диск:

<persistence-enabled>false</persistence-enabled>

Непостоянные сообщения не выдержат крах сервера HornetQ или его клиентов. В случае Last.fm это допустимо, поскольку их управляющие сообщения носят временный характер. Например, сообщение управления соединением от пользователя заменит любые другие предыдущие сообщения для того же пользователя, нет необходимости сохранять эти виды управляющих сообщений.

Политика отказа

Они также используют политику DROP: если размер размера сообщения для данного места назначения JMS превышает настроенный порог, HornetQ просто отбрасывает новые сообщения, отправленные на этот адрес, а не перегружает сервер:

<address-settings>
<address-setting match="#">
<max-size-bytes>104857600</max-size-bytes>
<address-full-policy>DROP</address-full-policy>
</address-setting>
</address-settings>

С этим параметром HornetQ будет отбрасывать сообщения, отправленные производителями JMS, если общий размер всех сообщений в памяти был больше 100 МБ для любого адреса (определяемого подстановочным знаком #).

Другие политики, поддерживаемые HornetQ:

  • PAGE — после настраиваемого порога HornetQ записывает сообщения на диск (в файлы подкачки ) вместо заполнения памяти и в конечном итоге вызывает переполнение памяти.
  • BLOCK — клиенты производителей HornetQ блокируются до тех пор, пока на сервере не будет достаточно памяти для обработки их сообщений и их доставки.

Предварительное подтверждение

Другая оптимизация заключалась в использовании предварительного подтверждения для повышения производительности. Предварительно подтвержденные сообщения подтверждаются сервером HornetQ перед отправкой клиенту:

<pre-acknowledge>true</pre-acknowledge>

Предварительное подтверждение предотвращает надежную доставку (так как сервер не будет знать, действительно ли потребители получили сообщения или нет), но повышает производительность, так как избегает дополнительной сетевой передачи от клиента к серверу HornetQ для отправки подтверждения

Режим предварительного подтверждения HornetQ является дополнением к режимам, предоставляемым JMS (auto-ack, dups-ok-ack и client-ack).

Рефакторинг архитектуры Last.fm

До использования HornetQ Last.fm запускал другую систему обмена сообщениями с открытым исходным кодом JMS. Однако у них были проблемы с нитью.

Сначала Last.fm использовал пул потоков. Когда поступил потоковый запрос, из этого пула был создан поток для обслуживания запроса. Поток выполнил аутентификацию, выполнил некоторые действия, нашел файл для потоковой передачи и т. Д. В конце поток затем отправил бы сообщения JMS. Благодаря этой архитектуре на Last.fm были сотни или тысячи потоков, отправляющих сообщения.

Когда предыдущая система обмена сообщениями время от времени плохо себя вел, это приводило к тому, что потоки блокировались, а вся система становилась на колени, поскольку эти потоки никогда не предназначались для блокировки.
Last.fm решил переключиться на HornetQ, чтобы их ресурсы не были заблокированы. Параллельно они также реорганизовали и упростили свою архитектуру. Теперь они используют отдельный отдельный поток JMS для отправки сообщений и помещают сообщения во внутреннюю ограниченную очередь в памяти. Затем поток JMS извлекает сообщения из этой очереди и отправляет их на сервер JMS. В маловероятном случае, когда отправка сообщения JMS блокируется, блокируется только этот поток JMS. Поскольку очередь в памяти ограничена, новые сообщения будут отваливаться вместо того, чтобы занимать больше оперативной памяти и усугублять проблему.

При переходе на HornetQ Last.fm помог команде HornetQ выявить ошибки, которые вызывали проблемы с блокировкой. Эти ошибки были исправлены до выпуска HornetQ 2.0.0 в январе 2010 года. После перехода на HornetQ 2.0.0. и изменения в их архитектуре, инфраструктура обмена сообщениями Last.fm работала месяцами без каких-либо проблем с производительностью.

Основная проблема Last.fm с переходом на новую систему обмена сообщениями заключалась в работоспособности. Производительность была важна, но было важно, чтобы сервер обмена сообщениями не падал, не исчерпывал память или диск. Last.fm был готов выбросить сообщения, чтобы не отставать: доступность была важнее, чем надежная доставка .

Сервер Last.fm HornetQ расположен на двухъядерном процессоре AMD с частотой 2 ГГц и 8 ГБ ОЗУ и работает под управлением Debian Linux. Другие службы размещены на этом сервере, но в целом использование памяти не превышает 1 ГБ или ОЗУ, а загрузка ЦП следует за ежедневной загрузкой / пиковым режимом примерно с 4% до 6%.
Как память, так и загрузка процессора были стабильными в течение последнего месяца без каких-либо изменений. Их использование предсказуемо, а пики процессора соответствуют пикам использования Last.fm.

Количество связанных с потоковой передачей сообщений, обрабатываемых HornetQ, варьируется в зависимости от дня недели, времени месяца и других факторов. На пике HornetQ обрабатывает 20000 сообщений в минуту (около 330-350 в секунду).

Вывод

Столкнувшись с проблемами стабильности и простоя своей предыдущей системы обмена сообщениями, Last.fm решила переключиться на HornetQ, чтобы лучше использовать и контролировать свои ресурсы JMS для своей потоковой инфраструктуры.
Так как этот переключатель и рефакторинг их собственного кода для дезинфекции использования ресурсов JMS, аппаратные ресурсы были под контролем, максимальное время безотказной работы было достигнуто, в то время как производительность и доступность продолжают следовать за использованием Last.fm. С помощью HornetQ Last.fm теперь готов масштабировать свою систему обмена сообщениями, чтобы она соответствовала своим потоковым возможностям и, в конечном счете, росту бизнеса.