Профайлинг Twisted-приложений 2

Написал Андрей (Февраль 15, 2010)

Часто сам забываю, как профилировать легко и быстро Twisted-приложения (с некоторым изменениями подойдет для любых Python-приложений). Кроме Twisted нам понадобится еще KCachegrind

Запускаем наше приложение с включенным профайлингом:

twistd -n --savestats --profile=myprog.hotshot myprog

Подаем нагрузку, профайл собирается. Теперь с помощью утилиты hotshot2cg из поставки KCachegrind превращаем hotshot-профайл в calltree-профайл, который уже умеет KCachegrind «кушать».

hotshot2cg myprog.hotshot > myprog.calltree

Запускаем KCachegrind, открываем в нем полученный профайл:

kcachegrind myprog.calltree

MySQL, ROW/STATEMENT/MIXED-репликация и триггеры

Написал Андрей (Февраль 15, 2010)

Описанная особенность MySQL попалась мне на глаза слишком поздно, пишу, чтобы кто-то не напоролся на те же грабли. Начнем с начала. Итак, необходимо было отслеживать изменения MySQL-базы данных и складывать эти изменения в очередь (не в БД) для дальнейшей обработки внешней системой. Для отслеживания изменений подходят триггеры, но они активируются в процессе выполнения запросов транзакции и в случае последующего «rollback» не будут откатываться (что совершенно нормально для триггеров, влияющих только на состояние БД, т.к. состояние БД будет корректно откатываться). Поэтому необходимо выполнять триггеры только для успешных транзакций: проще всего это достигнуть с помощью репликации – на слейв передаются только запросы зафиксированных транзакций. Таким образом, мастер-БД не содержит триггеров, после репликации данные попадают на слейв, таблицы на котором обвешаны триггерами, те активируются и данные попадают в очередь. Казалось бы, все замечательно?

Дальше…

HL++ (2009): Twisted Framework 15

Написал Андрей (Октябрь 13, 2009)

Сегодня выступал на HighLoad++ с докладом Twisted Framework – фреймворк для написания сетевых приложений в Python.

Введение

Последнее время в области web происходит смещение внимания с тяжелых application-серверов, которые тратят на обработку запроса сотни миллисекунд, а то и секунды, к более легковесным сервисам, передающим меньшие объемы данных с минимальной задержкой. Переход от генерации десятков и сотен килобайт HTML-кода в ответ на запрос к передаче изменений в данных, запакованных в JSON и измеряемых сотнями байт. В качестве примеров таких сервисов можно привести Gmail, FriendFeed, Twitter Live Search и т.п.

Для обеспечения минимальной задержки для пользователя необходимо либо поддерживать постоянное соединение (например, Adobe Flash, RTMP) или использовать технику HTTP long polling в сочетании с keep alive. Так или иначе на стороне сервера это приводит к появлению большого количества одновременных соединений (тысячи, десятки тысяч), по каждому из которых передается не такой большой объем данных. Эту ситуацию называют обычно проблемой C10k.

Дальше…

Mongrel vs. Phusion Passenger: выбор очевиден 4

Написал Андрей (Октябрь 05, 2009)

Предыдущая конфигурация:

  • nginx (главный proxy), который раздает трафик в
  • haproxy (ради возможности балансировать по нагрузке), который распределяет нагрузку по нескольким webapp-серверам
  • с 16-ю mongrelами на каждом

Проблемы:

  1. «Утекающая» память, периодический out of memory на серверах, лечится только перезапуском mongrelов.
  2. Запросы, занимающие десятки секунд из-за неверной балансировки (в нагруженный mongrel все-таки попадает несколько «тяжелых» запросов).
  3. Сложность управления кластером монгрелов – постоянные проблемы при перезапуске, «не стартующие» mongrelы и т.п.

Новая конфигурация:

Результат:

webapp01-passenger-mongrel

Комментарий: переход на Phusion Passenger на Week 39, объем занятой памяти – это белая область на графике, растущая сверху вниз. До перехода на Passenger объем свободной памяти стремительно уменьшался, иногда доходя до нуля, после перехода остается более-менее стабильным. Использование CPU осталось на прежнем уровне (как и ожидалось).

После перехода исчезли запросы, которые по непонятным причинам занимали десятки секунд – время выполнения коррелирует со сложностью запроса.

Так что если вы еще не переключились, мы идем к вам :)

P.S. Отдельное спасибо glebpom за подсказку.

HL++2009: Twisted Framework – фреймворк для написания сетевых приложений в Python 2

Написал Андрей (Сентябрь 25, 2009)

highload

На HighLoad++-2009 буду выступать с докладом Twisted Framework – фреймворк для написания сетевых приложений в Python. Конференция будет проходит 12-13 октября 2009 г. в Инфопространстве. Приглашаю всех желающих!

Тезисы доклада:

  1. Архитектура сетевых сервисов, нити, процессы, асинхронный ввод-вывод.
  2. Тенденции в изменении структуры нагрузки на сетевые сервисы: AJAX, Comet/BOSH, клиент-серверная архитектура, проблема 10k.
  3. Асинхронный ввод-вывод и параллельное программирование: достоинства и недостатки. Поддержка локального контекста, deadlock, lock contention, starvation, масштабирование на многоядерную архитектуру и т.д.
  4. Twisted Framework с высоты птичьего полета.
  5. Аналоги Twisted в других языках программирования: Ruby — EventMachine, Perl — POE.
  6. Центральная концепция Twisted: Deferred — как сохранить контекст выполнения в однопоточном коде с асинхронным вводом-выводом.
  7. Аналогии между последовательным кодом и асинхронным кодом с использованием Deferred.
  8. Twisted и использование нитей: модель worker, «оборачивание» legacy кода.
  9. Реальные примеры Twisted-приложений, цифры, факты, архитектурные решения, преимущества и недостатки:
    • pyFMS — сервер RTMP-вещаний, нагрузка, оптимизация Python-кода;
    • MDC-сервер, масштабирование;
    • Qik Push Engine, обслуживание тысяч клиентов, тестирование клиентов.
  10. Качество кода Twisted, модель разработки, перспективы развития проекта, экосистема Twisted. Что может Twisted дать моему проекту?

Qik Push Engine API: приглашаем разработчиков

Написал Андрей (Июль 12, 2009)

qik_logo Qik – это сервис стриминга (вещания) и загрузки видео с мобильных телефонов. Загруженное видео можно посмотреть на сайте или на его специальной версии с мобильного телефона. Доступна интеграция с другими сервисами, такими как Twitter, Facebook и другие. Клиенты для практически всех современных моделей телефонов: iPhone, Windows Mobile, Symbian, Android, Blackberry и другие.

Qik Push Engine – это механизм, который позволяет получать мгновенные оповещения о новых/изменившихся Qik-видео. Например, можно посмотреть постоянно обновляющийся список live-видео, все видео из района Новопеределкино или все видео со словом «кошка». На основе Qik Push Engine API можно построить интересные приложения, интегрированные с Qik, или добавить функциональность в уже существующие. Можно написать собственную систему нотификации, desktop-widget или что-то еще.

Сегодня мы открываем API для работы c Qik Push Engine. Это первая ласточка в большом списке API, открывающих доступ к платформе стриминга Qik. Если вам интересно посмотреть Qik Push Engine в действии, заходите на одну из страниц примеров.

Дальше…

AMQP по-русски 6

Написал Андрей (Июнь 08, 2009)

AMQP logo Сегодня довольно мало информации о протоколе AMQP (Advanced Message Queueing Protocol) и его применении, особенно русском языке. А вообще это – замечательный, уже достаточно широко поддерживаемый открытый протокол для передачи сообщений между компонентами системы с низкой задержкой и на высокой скорости. При этом семантика обмена сообщениями настраивается под нужды конкретного проекта. Такие решения существовали и ранее, но это первый стандарт, для которого существует большое количество свободных реализаций.

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

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

Я не ставлю своей целью сегодня рассказать о том, как писать приложения для AMQP. Хочу лишь немного рассказать о том, что это совсем не страшно, не очень сложно, и действительно работает, хотя стандарт находится еще в развитии, выходят новые версии протокола, брокеров и т.п. Но это уже вполне production-quality. Расскажу лишь базовые советы, чтобы помочь «въехать» в протокол.

Дальше…

FMSPy, релиз Alpha (0.1) 16

Написал Андрей (Июнь 07, 2009)

FMSPy Flash Media Server written in Python (FMSPy) – это еще один RTMP-сервер для приложений на Adobe Flash/Flex/Air. FMSPy является аналогом Adobe Flash Media Server, с гораздо меньшими возможностями, однако FMSPy – совершенно бесплатный проект с открытым исходным кодом. Проект находится на ранней стадии развития, но в активной разработке.

Итак, что есть на сегодняшний день:

  • Реализация RTMP-протокола: кодирование/декодирование пакетов, разрезание и склеивание из chunks и т.п.
  • Поддержка базового RPC (Invoke) клиент-сервер и сервер-клиент. То есть из Flash-приложения можно вызывать с помощью класса NetConnection методы приложения на стороне сервера, и наоборот со стороны сервера вызывать методы приложения.
  • Инфраструктура для написания приложений (в качестве плагинов к FMSPy) со своим API на Python.

    Дальше…

Deferred для JavaScript (Prototype)

Написал Андрей (Май 29, 2009)

Prototype and Twisted

Продолжая тему Deferred для JavaScript предлагаю еще одно переписывание Deferred, теперь в терминах Prototype. Подробнее о самом Deferred можно почитать в двух моих прошлых заметках: Асинхронное программирование: концепция Deferred и Deferred: все подробности. Если кратко, самое распространенное и полезное применение Deferred в JavaScript – это работа с AJAX или другими RPC-over-HTTP вызовами, когда необходимо совершить цепочку логически связанных вызовов, корректно обрабатывать возникающие ошибки и т.п. С моей точки зрения, Deferred крайне необходим в таких ситуациях.

Перейдем к примерам: обращение к некоторому JSON-RPC API на основе Prototype’овского Ajax.Request можеть быть обернуто в Deferred следующим образом:

Дальше…

Пожар на газопроводе и информационный вакуум

Написал Андрей (Май 11, 2009)

В ночь с 9-е на 10-е мая произошел разрыв газопровода, об этом знают все. Мы живем в Ново-Переделкино, примерно в шести километрах от места аварии. Как раз в момент взрыва (около 0:40) мы вышли на балкон, услышали сильный хлопок и небо осветилось. Повернув голову, мы увидели огромный гриб пламени, поднимающийся в небо. Раздался сильный гул, который не прекращался. Определить расстояние на глаз было невозможно, казалось, что пожар совсем близко, километрах в двух за Чоботовским лесом. Первая реакция – позвонить 01, но ни с городского телефона, ни с сотового двух разных операторов это не удавалось – сразу короткие гудки. Может быть, очень много позвонило в тот момент, может быть, уже какие-то кабели были повреждены на месте пожара. Сегодня я уже знаю, где место пожара, и что пожарная часть располагается буквально в 200 метрах, звонить было вряд ли полезно – все знали о произошедшем. Но если бы, не дай Бог, был где-то еще пожар, как дозвониться? Мне кажется, что телефоны оперативных служб должны быть организованы так, чтобы возможность дозвониться оставалась.

Через еще несколько минут возник вакуум информации, где горит? Что горит? По виду столба пламени можно было догадаться, что горит газ, но знать наверняка вряд ли было возможно. Есть ли угроза для нас, для нашего дома? По моим первым предположениям, что горит прямо за лесом, в случае, если огонь перекинется на лес, нам надо было будить нашу маленькую дочку и уезжать отсюда. По телевидению в новостных каналах тишина, никакой информации. Помогает поиск по блогам, уже через несколько минут первая информация – пожар где-то внутри МКАД, в районе Мичуринского проспекта. Становится чуточку легче. Спасибо вам, блоггеры!

Еще через несколько минут около часа ночи прекращает работать интернет (Стрим), с ним погибает и телевидение №1 (Стрим-ТВ). Тут же умирает и телевидение №2 (кабельное в доме). Интересно, как они связаны? По радио тишина. Остается последний источник информации, сотовый телефон, ленты новостных агентств. Через их сайты удается узнать какую-то информацию, действительно пожар около поста ДПС на пересечении Мичуринского и МКАД. Всё, можно спать.