SlideShare une entreprise Scribd logo
1  sur  44
Télécharger pour lire hors ligne
Использование асинхронного I/O для
снижения потребления ресурсов в
движке aviasales
Каплуновский Борис
aviasales.ru
facebook.com/boris.kaplounovsky
@bskaplou
Agenda
● Скриптовые языки и ресурсы
● Асинхронная модель выполнения
● Оптимизации и отзывчивость
● Странности Tornado
● Странности Python
● Tornado/Python в production
● И ещё пару советов по повышению
производительности...
Что делает движок aviasales
Модель памяти нативной
программы
process one
stack
data
process two
code
libdl
libc
data
stack
● Одна и та-же память с
исполняемым кодом
используется всеми
процессами
● Разделяемые
библиотеки грузятся в
память один раз
● Не разделяются
другими процессами
только сегменты
данных и стек
Модель памяти скрипта
runtime code
libdl
libc
stackstack
data data
script libs script libs
● Нативные код и
библиотеки
разделяются
● AST и байткод
скриптовых библиотек
хранятся в сегменте
данных и поэтому НЕ
разделяются
● Скриптовый код не так
компактен как
нативный и обычно
занимает в разы
больше памяти
code code
Сферический CGI Сервер в
вакууме
stack
data
native code
libc
libdl
datadatadatadata data
stack stackstack stack stack stack
Скриптовый CGI Сервер
stackstack
data data
script libs script libs
code code
stackstack
data data
script libs script libs
code code
stackstack
data data
script libs script libs
code code
native code
libc
libdl
Оптимизации над CGI
● fastcgi - Не порождаем отдельный процесс для каждого
запроса – экономим процессорного времени на
загрузку скриптов j2ee/rails/etc
● process pool - запуск и инициализация процесса до
прихода запроса – снижение времени отклика
● master -Запуск родительского процесса загружающего
код и делающего инициализацию. Родительский
процесс порождает обработчиков клонируя себя.
Процесс обрабатывающий запрос уже имеет в памяти
всё необходимое. unicorn/dalvik/etc
Copy on write
● После вызова fork() состояние
памяти и родителя и потомка
одинаковые
● Делать полную копию
адресного пространства при
fork() расточительно
● В момент вызова fork()
страницы данных родителя и
потомка метятся как read-only
parent childcode
libdl
libc
data
stack
fork()
Copy on write
● Как только один из процесс
записывает данные –
операционная система делает
личную копию страницы в
пространстве процесса
● Страницы памяти в которые не
пишут могут разделяться вечно
parent child
data
stack stack
data
clone pages
master process & copy on write
● После старта мастер процесс
грузит библиотеки и
подготавливает всё для
исполнения скрипта
● По мере необходимости мастер
порождает рабочие процессы
клонируя себя
● Так как в мастере уже были
загружены все библиотеки
дочерний процесс готов к работе
мгновенно
● COW позволяет не создавать
собственную копию кода в памяти
master child
stackstack
data data
script libs
code
native code
libc
libdl
Copy on write
НЕ РАБОТАЕТ!
COW не работает потому что
● GC скриптовой среды
меняют данные
неиспользуемых обьектов в
ходе своей работы
● Скриптовые языки со
счётчиками ссылок
модифицируют счётчики
ссылок при создании новой
ссылки на обьект, даже
если сам обьект неизменен
master child
stackstack
data data
script
libs
code
native code
libc
libdl
code
script
libs
COW не
просто заставить работать
● В ruby 2.0 обещали сделать
cow friendly gc. Не
получилось!
● COW работает у google в
dalvik, но для этого им
пришлось заменить jvm на
dalvik
master child
stackstack
data data
script
libs
code
native code
libc
libdl
code
script
libs
Типичное web приложение
Значительную часть времени веб приложения
ждут ответов внешних сервисов таких как
– SQL сервер
– Внешний API
– Файловый ввод вывод
Всё это время ничего не происходит!
Но память занята...
запрос ответ
logic SQL logicAPI
Rails приложение aviasales
● Ожидание ответа внешних API до 30 секунд
● Работа с SQL ~1 секунда
● Потребляемая память ~300mb (одним процессом)
● Разделяемая память ~4mb (код интерпретатора)
● ~300 одновременных поисков
87GB RAM/6 серверов
И вся эта память простаивала!
запрос ответ
logic SQL logicAPI
Синхронная модель VS
Асинхронная модель
cgi worker
stack
data
code
script
libs
cgi worker
stack
data
code
script
libs
async worker
stack
script
libs
code
native code
libc
thread
data
thread
data
thread
data
cgi worker
stack
data
code
script
libs
native code
libc
Асинхронная модель
Минусы
● Кооперативная многозадачность
● Если падает процесс падают все потоки
● Не для всего есть библиотеки
● Отсутствие изоляции
● Примитивный планировщик
● Нет готовых решений
Асинхронная модель
Плюсы
● Эффективное использование памяти
● Эффективное использование памяти
● Эффективное использование памяти
● Эффективное использование памяти
● Эффективное использование памяти
Почему Python
– Большое и доброе community
– Обилие библиотек
– Tornado живёт в python
– Реклама google
– Хотелось попробовать
Почему Tornado
– Низкий порог вхождения
– Асинхронный
– @gen.coroutine – отличная альтернатива
колбекам
– Казался зрелым
Приложение на python/tornado
● Один процесс:
– занимает 267mb памяти
– из них 162mb разделяемой
– обрабатывает до 10
одновременных запросов
– больше не ждёт SQL сервер, все
данные в адресном пространстве
процесса
– ~ 500 одновременных исходящих
соединений
– 2 сервера/8GB памяти
async worker
stack
script
libs
code
native code
libc
data data data
При работе с tornado помни!
● Как только вы начинаете использовать синхронный IO
всё останавливается
● Переключение контекста происходит ТОЛЬКО на I/O и
yield внутри @gen.coroutine
● Неделимый кусок кода не должен исполняться больше
XXXms (мы выбрали 100ms)
При работе с tornado помни!
● Декоратор @gen.coroutine не бесплатен
● Tornado/Python приложение может умирать
● У Tornado/Python приложения может течь память
● Только профилировщик точно покажет кто ест CPU
● Python используется как клей для нативных библиотек,
сложные алгоритмы на python реализовывать не надо
Странности Tornado
● Из коробки нет способа остановить приложение без
обрыва соединений
● Есть рецепты костылей на StackOverflow
● Но этого мало – пришлось изобретать ещё костылей
Резольвер
www.aviasales.ru → 194.87.255.204
● “Родные” резольверы операционных систем
синхронны
● Для асинхронный модели исполнения нужен
асинхронный резольвер
Странности Tornado – Резольвер
● tornado.netutil.BlockingResolver
– Используется по умолчанию
– Использует синхронный getaddrinfo
– Не кеширует результаты
– Обращение к DNS при каждом HTTP
запросе
– Пока DNS сервер не ответил всё стоит
Странности Tornado – Резольвер
● tornado.netutil.ThreadedResolver
– Вызывает getaddrinfo в отдельном потоке
python
– Overhead на потоки: память, cpu, GIL
– Работает но выглядит как костыль
Странности Tornado – Резольвер
● Мы написали простой
асинхронный резольвер для
Tornado IOLoop
– Только TCP
– Только записи A и CNAME
– Кеширование ответов DNS по
TTL
– Большинство
преобразований делается без
системных вызовов
Странности Tornado – HTTPClient
● HTTPClient создаёт не больше 10 исходящих
соединений по умолчанию
● HTTPClient умеет стримить ответ сервера только
если ответ chunked
Странности Tornado
● Документация зачастую избегает описывать узкие
места
● Будьте готовы читать исходный код tornado чтобы
понять поведение системы
Странности Python
● Сторонние библиотеки с нативным кодом текут и валят
приложение через одну
● Найти утечку памяти в нативном коде крайне сложно
● Встроенная библиотеку xml.etree может приводить к
SEGFAULT, мы используем lxml
● Сложные регулярные выражения могут остановить
приложение busy-wait
tornado/python в production
MONIT
– Убивает рабочие процессы если они
выедают CPU
– Убивает рабочие процессы если они
превысили лимит по памяти
– Стартует рабочие процессы если те
умерли сами или были убиты
– Простой и удобный web интерфейс
tornado/python в production
HAPROXY
– Раскидывает приходящие запросы по
доступным рабочим процессам
– Балансирует нагрузку отправляя
запросы к процессам с наименьшим
количеством активных соединений
– Адски быстрый и простой
– Простой и удобный веб интерфейс
tornado/python в production
BENCHMARKS
– Тотальное логирование времени выполения участков
кода
– Визуализация бенчмарков на видном месте
– Немедленная реакция на аномалии в скорости
ответов сервера
Что делать с ожиданием ответов
SQL сервера
Удалённый сервер DB
request
response
worker remote db
parse request
load value
build response
recv(syscall)
send(syscall)
Файловое key-value хранилище
● Содержимое файла должно быть смаплено в
адресное пространство процесса mmap
● Рабочий обьём должен умещаться в оперативной
памяти
● База должна позволять нескольким процессам
одновременно читать данные без блокировок
● Мы используем kyoto cabinet и он прекрасен
Быстрее чем redis и memcached
worker
load value
Плюсы
● Не нужен внешний
сервер
● Непревзойдённая
скорость
● Не нужно переключать
контекст и делать
syscall
● Высокая
отказоустойчивость
Быстрее чем redis и memcached
worker
load value
Минусы
● Медленный update
данных
● Избыточность при
работе в кластере
● Работает только для
небольшого кол-ва
данных
Q&A
facebook.com/boris.kaplounovsky
@bskaplou
Используйте потоковую обработку
для разбора XML
● Опция streaming_callback у AsyncHTTPClient
fetch позволяет получать данные по мере
поступления
● Метод lxml.etree.XMLParser.feed позволяет
парсить xml по кускам
● Если и это не помогает, делаем
IOLoop.instance().add_timeout(time()) чтобы
разбить поток исполнения
tornado/python в production
Приоритеты
● У разных запросов разные требования к скорости ответ
● Рабочие процессы привязываются к одной или
нескольким группа приоритета
● Haproxy отправляет запросы в соответствующую группу
рабочих процессов

Contenu connexe

Tendances

Константин Осипов
Константин ОсиповКонстантин Осипов
Константин ОсиповCodeFest
 
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Ontico
 
Олег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоОлег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоCodeFest
 
Алексей Федоров
Алексей ФедоровАлексей Федоров
Алексей ФедоровCodeFest
 
Why we did not choose Hadoop
Why we did not choose HadoopWhy we did not choose Hadoop
Why we did not choose HadoopSerguei Gitinsky
 
Erlang railsclub - 1
Erlang   railsclub - 1Erlang   railsclub - 1
Erlang railsclub - 1Max Lapshin
 
My talk on LeoFS, Highload++ 2014
My talk on LeoFS, Highload++ 2014My talk on LeoFS, Highload++ 2014
My talk on LeoFS, Highload++ 2014Alex Chistyakov
 
Максим Лапшин — введение в Erlang
Максим Лапшин — введение в ErlangМаксим Лапшин — введение в Erlang
Максим Лапшин — введение в ErlangАлександр Ежов
 
Опыт использования Erlang в разработке многопользовательской игры
Опыт использования Erlang в разработке многопользовательской игрыОпыт использования Erlang в разработке многопользовательской игры
Опыт использования Erlang в разработке многопользовательской игрыYuri Zhloba
 
JPHP - О проекте на простом языке
JPHP - О проекте на простом языкеJPHP - О проекте на простом языке
JPHP - О проекте на простом языкеDmitry Zaytsev
 
Erlang, который мы потеряли
Erlang, который мы потерялиErlang, который мы потеряли
Erlang, который мы потерялиIvan Grishaev
 
Эффективная отладка репликации MySQL / Света Смирнова (Percona)
Эффективная отладка репликации MySQL / Света Смирнова (Percona)Эффективная отладка репликации MySQL / Света Смирнова (Percona)
Эффективная отладка репликации MySQL / Света Смирнова (Percona)Ontico
 
Там, где Rails не справляются
Там, где Rails не справляютсяТам, где Rails не справляются
Там, где Rails не справляютсяMax Lapshin
 
Отличие Erlang от объектных языков
Отличие Erlang от объектных языковОтличие Erlang от объектных языков
Отличие Erlang от объектных языковMax Lapshin
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...corehard_by
 
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)Ontico
 
Мой modern Perl (весенняя встреча Piter United)
Мой modern Perl (весенняя встреча Piter United)Мой modern Perl (весенняя встреча Piter United)
Мой modern Perl (весенняя встреча Piter United)Alex Chistyakov
 

Tendances (19)

Константин Осипов
Константин ОсиповКонстантин Осипов
Константин Осипов
 
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
 
Олег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоОлег Бартунов и Иван Панченко
Олег Бартунов и Иван Панченко
 
Erlang&rails
Erlang&railsErlang&rails
Erlang&rails
 
Алексей Федоров
Алексей ФедоровАлексей Федоров
Алексей Федоров
 
Why we did not choose Hadoop
Why we did not choose HadoopWhy we did not choose Hadoop
Why we did not choose Hadoop
 
Erlang railsclub - 1
Erlang   railsclub - 1Erlang   railsclub - 1
Erlang railsclub - 1
 
My talk on LeoFS, Highload++ 2014
My talk on LeoFS, Highload++ 2014My talk on LeoFS, Highload++ 2014
My talk on LeoFS, Highload++ 2014
 
Максим Лапшин — введение в Erlang
Максим Лапшин — введение в ErlangМаксим Лапшин — введение в Erlang
Максим Лапшин — введение в Erlang
 
Sivko
SivkoSivko
Sivko
 
Опыт использования Erlang в разработке многопользовательской игры
Опыт использования Erlang в разработке многопользовательской игрыОпыт использования Erlang в разработке многопользовательской игры
Опыт использования Erlang в разработке многопользовательской игры
 
JPHP - О проекте на простом языке
JPHP - О проекте на простом языкеJPHP - О проекте на простом языке
JPHP - О проекте на простом языке
 
Erlang, который мы потеряли
Erlang, который мы потерялиErlang, который мы потеряли
Erlang, который мы потеряли
 
Эффективная отладка репликации MySQL / Света Смирнова (Percona)
Эффективная отладка репликации MySQL / Света Смирнова (Percona)Эффективная отладка репликации MySQL / Света Смирнова (Percona)
Эффективная отладка репликации MySQL / Света Смирнова (Percona)
 
Там, где Rails не справляются
Там, где Rails не справляютсяТам, где Rails не справляются
Там, где Rails не справляются
 
Отличие Erlang от объектных языков
Отличие Erlang от объектных языковОтличие Erlang от объектных языков
Отличие Erlang от объектных языков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
 
Мой modern Perl (весенняя встреча Piter United)
Мой modern Perl (весенняя встреча Piter United)Мой modern Perl (весенняя встреча Piter United)
Мой modern Perl (весенняя встреча Piter United)
 

En vedette

TFF2015, Gila Gfader, Booking.com, "Die Reise beginnt in Netz"
TFF2015, Gila Gfader, Booking.com, "Die Reise beginnt in Netz"TFF2015, Gila Gfader, Booking.com, "Die Reise beginnt in Netz"
TFF2015, Gila Gfader, Booking.com, "Die Reise beginnt in Netz"TourismFastForward
 
CodeFest 2014. Vedran Mikulic — Booking Fast Development
CodeFest 2014. Vedran Mikulic — Booking Fast DevelopmentCodeFest 2014. Vedran Mikulic — Booking Fast Development
CodeFest 2014. Vedran Mikulic — Booking Fast DevelopmentCodeFest
 
Internationalisation: 2200+ different ways to view a website
Internationalisation: 2200+ different ways to view a websiteInternationalisation: 2200+ different ways to view a website
Internationalisation: 2200+ different ways to view a websiteEduardo Shiota Yasuda
 
The anatomy of an A/B Test - JSConf Colombia Workshop
The anatomy of an A/B Test - JSConf Colombia WorkshopThe anatomy of an A/B Test - JSConf Colombia Workshop
The anatomy of an A/B Test - JSConf Colombia WorkshopEduardo Shiota Yasuda
 
Tag-it 2016 slides: UX + A/B Testing at Booking.com: Design focused on conver...
Tag-it 2016 slides: UX + A/B Testing at Booking.com: Design focused on conver...Tag-it 2016 slides: UX + A/B Testing at Booking.com: Design focused on conver...
Tag-it 2016 slides: UX + A/B Testing at Booking.com: Design focused on conver...Maria Lígia Klokner
 

En vedette (8)

TFF2015, Gila Gfader, Booking.com, "Die Reise beginnt in Netz"
TFF2015, Gila Gfader, Booking.com, "Die Reise beginnt in Netz"TFF2015, Gila Gfader, Booking.com, "Die Reise beginnt in Netz"
TFF2015, Gila Gfader, Booking.com, "Die Reise beginnt in Netz"
 
CodeFest 2014. Vedran Mikulic — Booking Fast Development
CodeFest 2014. Vedran Mikulic — Booking Fast DevelopmentCodeFest 2014. Vedran Mikulic — Booking Fast Development
CodeFest 2014. Vedran Mikulic — Booking Fast Development
 
ConnectIn Amsterdam 2014 - Beter beslissen met data - Booking.com & Netwerven
ConnectIn Amsterdam 2014 - Beter beslissen met data - Booking.com & NetwervenConnectIn Amsterdam 2014 - Beter beslissen met data - Booking.com & Netwerven
ConnectIn Amsterdam 2014 - Beter beslissen met data - Booking.com & Netwerven
 
Internationalisation: 2200+ different ways to view a website
Internationalisation: 2200+ different ways to view a websiteInternationalisation: 2200+ different ways to view a website
Internationalisation: 2200+ different ways to view a website
 
The anatomy of an A/B Test - JSConf Colombia Workshop
The anatomy of an A/B Test - JSConf Colombia WorkshopThe anatomy of an A/B Test - JSConf Colombia Workshop
The anatomy of an A/B Test - JSConf Colombia Workshop
 
Front-end Culture @ Booking.com
Front-end Culture @ Booking.comFront-end Culture @ Booking.com
Front-end Culture @ Booking.com
 
Tag-it 2016 slides: UX + A/B Testing at Booking.com: Design focused on conver...
Tag-it 2016 slides: UX + A/B Testing at Booking.com: Design focused on conver...Tag-it 2016 slides: UX + A/B Testing at Booking.com: Design focused on conver...
Tag-it 2016 slides: UX + A/B Testing at Booking.com: Design focused on conver...
 
Introduction of Booking.com
Introduction of Booking.comIntroduction of Booking.com
Introduction of Booking.com
 

Similaire à CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения потребления ресурсов в движке Aviasales.ru

Разработка API для большого, нагруженного сервиса
Разработка API для большого, нагруженного сервисаРазработка API для большого, нагруженного сервиса
Разработка API для большого, нагруженного сервисаITCrowd Almaty
 
Разработка API для большого, нагруженного сервиса
Разработка API для большого, нагруженного сервисаРазработка API для большого, нагруженного сервиса
Разработка API для большого, нагруженного сервисаendeveit
 
Павел Юрийчук - Разработка приложений под мобильные браузеры
Павел Юрийчук - Разработка приложений под мобильные браузерыПавел Юрийчук - Разработка приложений под мобильные браузеры
Павел Юрийчук - Разработка приложений под мобильные браузерыUA Mobile
 
Путь к Go на конкретном примере
Путь к Go на конкретном примереПуть к Go на конкретном примере
Путь к Go на конкретном примереSergey Xek
 
Multithreading in JS. Myth or reality?
Multithreading in JS. Myth or reality?Multithreading in JS. Myth or reality?
Multithreading in JS. Myth or reality?Alexander Syrotenko
 
SECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли UnitySECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли UnitySECON
 
AVITO. Решардинг Redis без даунтайма. DevConf 2012
AVITO. Решардинг Redis без даунтайма. DevConf 2012AVITO. Решардинг Redis без даунтайма. DevConf 2012
AVITO. Решардинг Redis без даунтайма. DevConf 2012Roman Pavlushko
 
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)Ontico
 
Как считать и анализировать сотни гигабит трафика в секунду, Станислав Николо...
Как считать и анализировать сотни гигабит трафика в секунду, Станислав Николо...Как считать и анализировать сотни гигабит трафика в секунду, Станислав Николо...
Как считать и анализировать сотни гигабит трафика в секунду, Станислав Николо...Ontico
 
"How to build powerful CI / CD based on GitLab and Docker", Aleksandr Matkovs...
"How to build powerful CI / CD based on GitLab and Docker", Aleksandr Matkovs..."How to build powerful CI / CD based on GitLab and Docker", Aleksandr Matkovs...
"How to build powerful CI / CD based on GitLab and Docker", Aleksandr Matkovs...Provectus
 
Другая виртуализация
Другая виртуализацияДругая виртуализация
Другая виртуализацияYandex
 
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?Cisco Russia
 
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)Pavel Tsukanov
 
20111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture320111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture3Computer Science Club
 
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...CodeFest
 
О создании компилятора с высокоуровневого языка на компьютер с программируемо...
О создании компилятора с высокоуровневого языка на компьютер с программируемо...О создании компилятора с высокоуровневого языка на компьютер с программируемо...
О создании компилятора с высокоуровневого языка на компьютер с программируемо...CEE-SEC(R)
 
My talk on HBase ops engineering at TBD Jun 2016
My talk on HBase ops engineering at TBD Jun 2016My talk on HBase ops engineering at TBD Jun 2016
My talk on HBase ops engineering at TBD Jun 2016Alex Chistyakov
 
2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, ParallelsNikolay Samokhvalov
 

Similaire à CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения потребления ресурсов в движке Aviasales.ru (20)

Разработка API для большого, нагруженного сервиса
Разработка API для большого, нагруженного сервисаРазработка API для большого, нагруженного сервиса
Разработка API для большого, нагруженного сервиса
 
Разработка API для большого, нагруженного сервиса
Разработка API для большого, нагруженного сервисаРазработка API для большого, нагруженного сервиса
Разработка API для большого, нагруженного сервиса
 
Павел Юрийчук - Разработка приложений под мобильные браузеры
Павел Юрийчук - Разработка приложений под мобильные браузерыПавел Юрийчук - Разработка приложений под мобильные браузеры
Павел Юрийчук - Разработка приложений под мобильные браузеры
 
Путь к Go на конкретном примере
Путь к Go на конкретном примереПуть к Go на конкретном примере
Путь к Go на конкретном примере
 
Multithreading in JS. Myth or reality?
Multithreading in JS. Myth or reality?Multithreading in JS. Myth or reality?
Multithreading in JS. Myth or reality?
 
SECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли UnitySECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли Unity
 
AVITO. Решардинг Redis без даунтайма. DevConf 2012
AVITO. Решардинг Redis без даунтайма. DevConf 2012AVITO. Решардинг Redis без даунтайма. DevConf 2012
AVITO. Решардинг Redis без даунтайма. DevConf 2012
 
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)
 
Как считать и анализировать сотни гигабит трафика в секунду, Станислав Николо...
Как считать и анализировать сотни гигабит трафика в секунду, Станислав Николо...Как считать и анализировать сотни гигабит трафика в секунду, Станислав Николо...
Как считать и анализировать сотни гигабит трафика в секунду, Станислав Николо...
 
"How to build powerful CI / CD based on GitLab and Docker", Aleksandr Matkovs...
"How to build powerful CI / CD based on GitLab and Docker", Aleksandr Matkovs..."How to build powerful CI / CD based on GitLab and Docker", Aleksandr Matkovs...
"How to build powerful CI / CD based on GitLab and Docker", Aleksandr Matkovs...
 
Другая виртуализация
Другая виртуализацияДругая виртуализация
Другая виртуализация
 
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
 
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
 
20111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture320111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture3
 
Breaking logs
Breaking logsBreaking logs
Breaking logs
 
Async Python
Async PythonAsync Python
Async Python
 
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
 
О создании компилятора с высокоуровневого языка на компьютер с программируемо...
О создании компилятора с высокоуровневого языка на компьютер с программируемо...О создании компилятора с высокоуровневого языка на компьютер с программируемо...
О создании компилятора с высокоуровневого языка на компьютер с программируемо...
 
My talk on HBase ops engineering at TBD Jun 2016
My talk on HBase ops engineering at TBD Jun 2016My talk on HBase ops engineering at TBD Jun 2016
My talk on HBase ops engineering at TBD Jun 2016
 
2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels
 

Plus de CodeFest

Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander GraebeCodeFest
 
Никита Прокопов
Никита ПрокоповНикита Прокопов
Никита ПрокоповCodeFest
 
Денис Баталов
Денис БаталовДенис Баталов
Денис БаталовCodeFest
 
Елена Гальцина
Елена ГальцинаЕлена Гальцина
Елена ГальцинаCodeFest
 
Александр Калашников
Александр КалашниковАлександр Калашников
Александр КалашниковCodeFest
 
Ирина Иванова
Ирина ИвановаИрина Иванова
Ирина ИвановаCodeFest
 
Marko Berković
Marko BerkovićMarko Berković
Marko BerkovićCodeFest
 
Денис Кортунов
Денис КортуновДенис Кортунов
Денис КортуновCodeFest
 
Александр Зимин
Александр ЗиминАлександр Зимин
Александр ЗиминCodeFest
 
Сергей Крапивенский
Сергей КрапивенскийСергей Крапивенский
Сергей КрапивенскийCodeFest
 
Сергей Игнатов
Сергей ИгнатовСергей Игнатов
Сергей ИгнатовCodeFest
 
Николай Крапивный
Николай КрапивныйНиколай Крапивный
Николай КрапивныйCodeFest
 
Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander GraebeCodeFest
 
Вадим Смирнов
Вадим СмирновВадим Смирнов
Вадим СмирновCodeFest
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин ОсиповCodeFest
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele RialdiCodeFest
 
Максим Пугачев
Максим ПугачевМаксим Пугачев
Максим ПугачевCodeFest
 
Rene Groeschke
Rene GroeschkeRene Groeschke
Rene GroeschkeCodeFest
 
Иван Бондаренко
Иван БондаренкоИван Бондаренко
Иван БондаренкоCodeFest
 
Mete Atamel
Mete AtamelMete Atamel
Mete AtamelCodeFest
 

Plus de CodeFest (20)

Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander Graebe
 
Никита Прокопов
Никита ПрокоповНикита Прокопов
Никита Прокопов
 
Денис Баталов
Денис БаталовДенис Баталов
Денис Баталов
 
Елена Гальцина
Елена ГальцинаЕлена Гальцина
Елена Гальцина
 
Александр Калашников
Александр КалашниковАлександр Калашников
Александр Калашников
 
Ирина Иванова
Ирина ИвановаИрина Иванова
Ирина Иванова
 
Marko Berković
Marko BerkovićMarko Berković
Marko Berković
 
Денис Кортунов
Денис КортуновДенис Кортунов
Денис Кортунов
 
Александр Зимин
Александр ЗиминАлександр Зимин
Александр Зимин
 
Сергей Крапивенский
Сергей КрапивенскийСергей Крапивенский
Сергей Крапивенский
 
Сергей Игнатов
Сергей ИгнатовСергей Игнатов
Сергей Игнатов
 
Николай Крапивный
Николай КрапивныйНиколай Крапивный
Николай Крапивный
 
Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander Graebe
 
Вадим Смирнов
Вадим СмирновВадим Смирнов
Вадим Смирнов
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин Осипов
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele Rialdi
 
Максим Пугачев
Максим ПугачевМаксим Пугачев
Максим Пугачев
 
Rene Groeschke
Rene GroeschkeRene Groeschke
Rene Groeschke
 
Иван Бондаренко
Иван БондаренкоИван Бондаренко
Иван Бондаренко
 
Mete Atamel
Mete AtamelMete Atamel
Mete Atamel
 

CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения потребления ресурсов в движке Aviasales.ru

  • 1. Использование асинхронного I/O для снижения потребления ресурсов в движке aviasales Каплуновский Борис aviasales.ru facebook.com/boris.kaplounovsky @bskaplou
  • 2. Agenda ● Скриптовые языки и ресурсы ● Асинхронная модель выполнения ● Оптимизации и отзывчивость ● Странности Tornado ● Странности Python ● Tornado/Python в production ● И ещё пару советов по повышению производительности...
  • 4. Модель памяти нативной программы process one stack data process two code libdl libc data stack ● Одна и та-же память с исполняемым кодом используется всеми процессами ● Разделяемые библиотеки грузятся в память один раз ● Не разделяются другими процессами только сегменты данных и стек
  • 5. Модель памяти скрипта runtime code libdl libc stackstack data data script libs script libs ● Нативные код и библиотеки разделяются ● AST и байткод скриптовых библиотек хранятся в сегменте данных и поэтому НЕ разделяются ● Скриптовый код не так компактен как нативный и обычно занимает в разы больше памяти code code
  • 6. Сферический CGI Сервер в вакууме stack data native code libc libdl datadatadatadata data stack stackstack stack stack stack
  • 7. Скриптовый CGI Сервер stackstack data data script libs script libs code code stackstack data data script libs script libs code code stackstack data data script libs script libs code code native code libc libdl
  • 8. Оптимизации над CGI ● fastcgi - Не порождаем отдельный процесс для каждого запроса – экономим процессорного времени на загрузку скриптов j2ee/rails/etc ● process pool - запуск и инициализация процесса до прихода запроса – снижение времени отклика ● master -Запуск родительского процесса загружающего код и делающего инициализацию. Родительский процесс порождает обработчиков клонируя себя. Процесс обрабатывающий запрос уже имеет в памяти всё необходимое. unicorn/dalvik/etc
  • 9. Copy on write ● После вызова fork() состояние памяти и родителя и потомка одинаковые ● Делать полную копию адресного пространства при fork() расточительно ● В момент вызова fork() страницы данных родителя и потомка метятся как read-only parent childcode libdl libc data stack fork()
  • 10. Copy on write ● Как только один из процесс записывает данные – операционная система делает личную копию страницы в пространстве процесса ● Страницы памяти в которые не пишут могут разделяться вечно parent child data stack stack data clone pages
  • 11. master process & copy on write ● После старта мастер процесс грузит библиотеки и подготавливает всё для исполнения скрипта ● По мере необходимости мастер порождает рабочие процессы клонируя себя ● Так как в мастере уже были загружены все библиотеки дочерний процесс готов к работе мгновенно ● COW позволяет не создавать собственную копию кода в памяти master child stackstack data data script libs code native code libc libdl
  • 12.
  • 13. Copy on write НЕ РАБОТАЕТ!
  • 14. COW не работает потому что ● GC скриптовой среды меняют данные неиспользуемых обьектов в ходе своей работы ● Скриптовые языки со счётчиками ссылок модифицируют счётчики ссылок при создании новой ссылки на обьект, даже если сам обьект неизменен master child stackstack data data script libs code native code libc libdl code script libs
  • 15. COW не просто заставить работать ● В ruby 2.0 обещали сделать cow friendly gc. Не получилось! ● COW работает у google в dalvik, но для этого им пришлось заменить jvm на dalvik master child stackstack data data script libs code native code libc libdl code script libs
  • 16. Типичное web приложение Значительную часть времени веб приложения ждут ответов внешних сервисов таких как – SQL сервер – Внешний API – Файловый ввод вывод Всё это время ничего не происходит! Но память занята... запрос ответ logic SQL logicAPI
  • 17. Rails приложение aviasales ● Ожидание ответа внешних API до 30 секунд ● Работа с SQL ~1 секунда ● Потребляемая память ~300mb (одним процессом) ● Разделяемая память ~4mb (код интерпретатора) ● ~300 одновременных поисков 87GB RAM/6 серверов И вся эта память простаивала! запрос ответ logic SQL logicAPI
  • 18. Синхронная модель VS Асинхронная модель cgi worker stack data code script libs cgi worker stack data code script libs async worker stack script libs code native code libc thread data thread data thread data cgi worker stack data code script libs native code libc
  • 19. Асинхронная модель Минусы ● Кооперативная многозадачность ● Если падает процесс падают все потоки ● Не для всего есть библиотеки ● Отсутствие изоляции ● Примитивный планировщик ● Нет готовых решений
  • 20. Асинхронная модель Плюсы ● Эффективное использование памяти ● Эффективное использование памяти ● Эффективное использование памяти ● Эффективное использование памяти ● Эффективное использование памяти
  • 21. Почему Python – Большое и доброе community – Обилие библиотек – Tornado живёт в python – Реклама google – Хотелось попробовать
  • 22. Почему Tornado – Низкий порог вхождения – Асинхронный – @gen.coroutine – отличная альтернатива колбекам – Казался зрелым
  • 23. Приложение на python/tornado ● Один процесс: – занимает 267mb памяти – из них 162mb разделяемой – обрабатывает до 10 одновременных запросов – больше не ждёт SQL сервер, все данные в адресном пространстве процесса – ~ 500 одновременных исходящих соединений – 2 сервера/8GB памяти async worker stack script libs code native code libc data data data
  • 24. При работе с tornado помни! ● Как только вы начинаете использовать синхронный IO всё останавливается ● Переключение контекста происходит ТОЛЬКО на I/O и yield внутри @gen.coroutine ● Неделимый кусок кода не должен исполняться больше XXXms (мы выбрали 100ms)
  • 25. При работе с tornado помни! ● Декоратор @gen.coroutine не бесплатен ● Tornado/Python приложение может умирать ● У Tornado/Python приложения может течь память ● Только профилировщик точно покажет кто ест CPU ● Python используется как клей для нативных библиотек, сложные алгоритмы на python реализовывать не надо
  • 26. Странности Tornado ● Из коробки нет способа остановить приложение без обрыва соединений ● Есть рецепты костылей на StackOverflow ● Но этого мало – пришлось изобретать ещё костылей
  • 27. Резольвер www.aviasales.ru → 194.87.255.204 ● “Родные” резольверы операционных систем синхронны ● Для асинхронный модели исполнения нужен асинхронный резольвер
  • 28. Странности Tornado – Резольвер ● tornado.netutil.BlockingResolver – Используется по умолчанию – Использует синхронный getaddrinfo – Не кеширует результаты – Обращение к DNS при каждом HTTP запросе – Пока DNS сервер не ответил всё стоит
  • 29. Странности Tornado – Резольвер ● tornado.netutil.ThreadedResolver – Вызывает getaddrinfo в отдельном потоке python – Overhead на потоки: память, cpu, GIL – Работает но выглядит как костыль
  • 30. Странности Tornado – Резольвер ● Мы написали простой асинхронный резольвер для Tornado IOLoop – Только TCP – Только записи A и CNAME – Кеширование ответов DNS по TTL – Большинство преобразований делается без системных вызовов
  • 31. Странности Tornado – HTTPClient ● HTTPClient создаёт не больше 10 исходящих соединений по умолчанию ● HTTPClient умеет стримить ответ сервера только если ответ chunked
  • 32. Странности Tornado ● Документация зачастую избегает описывать узкие места ● Будьте готовы читать исходный код tornado чтобы понять поведение системы
  • 33. Странности Python ● Сторонние библиотеки с нативным кодом текут и валят приложение через одну ● Найти утечку памяти в нативном коде крайне сложно ● Встроенная библиотеку xml.etree может приводить к SEGFAULT, мы используем lxml ● Сложные регулярные выражения могут остановить приложение busy-wait
  • 34. tornado/python в production MONIT – Убивает рабочие процессы если они выедают CPU – Убивает рабочие процессы если они превысили лимит по памяти – Стартует рабочие процессы если те умерли сами или были убиты – Простой и удобный web интерфейс
  • 35. tornado/python в production HAPROXY – Раскидывает приходящие запросы по доступным рабочим процессам – Балансирует нагрузку отправляя запросы к процессам с наименьшим количеством активных соединений – Адски быстрый и простой – Простой и удобный веб интерфейс
  • 36. tornado/python в production BENCHMARKS – Тотальное логирование времени выполения участков кода – Визуализация бенчмарков на видном месте – Немедленная реакция на аномалии в скорости ответов сервера
  • 37. Что делать с ожиданием ответов SQL сервера
  • 38. Удалённый сервер DB request response worker remote db parse request load value build response recv(syscall) send(syscall)
  • 39. Файловое key-value хранилище ● Содержимое файла должно быть смаплено в адресное пространство процесса mmap ● Рабочий обьём должен умещаться в оперативной памяти ● База должна позволять нескольким процессам одновременно читать данные без блокировок ● Мы используем kyoto cabinet и он прекрасен
  • 40. Быстрее чем redis и memcached worker load value Плюсы ● Не нужен внешний сервер ● Непревзойдённая скорость ● Не нужно переключать контекст и делать syscall ● Высокая отказоустойчивость
  • 41. Быстрее чем redis и memcached worker load value Минусы ● Медленный update данных ● Избыточность при работе в кластере ● Работает только для небольшого кол-ва данных
  • 43. Используйте потоковую обработку для разбора XML ● Опция streaming_callback у AsyncHTTPClient fetch позволяет получать данные по мере поступления ● Метод lxml.etree.XMLParser.feed позволяет парсить xml по кускам ● Если и это не помогает, делаем IOLoop.instance().add_timeout(time()) чтобы разбить поток исполнения
  • 44. tornado/python в production Приоритеты ● У разных запросов разные требования к скорости ответ ● Рабочие процессы привязываются к одной или нескольким группа приоритета ● Haproxy отправляет запросы в соответствующую группу рабочих процессов