62
Comet-сервер своими руками Макс Лапшин Дмитрий Демещук

Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

  • Upload
    ontico

  • View
    1.170

  • Download
    4

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Comet-серверсвоими руками

Макс ЛапшинДмитрий Демещук

Page 2: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Эволюция веба

Page 3: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Никакого real-time

Page 4: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Немного real-time

Page 5: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Сплошной real-time

Page 6: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

После загрузки,

современная страница продолжает

жить своей жизнью.

Page 7: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Возможные варианты• Периодические запросы на сервер• Comet:• Long polling• Websockets• Server Sent Events

Page 8: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

• Много запросов впустую

• Постоянная загрузка

• Задержки

Периодические запросы

Page 9: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

• Не требует немедленного ответа• Совместим с keepalive• Моментальное обновление

• Много одновременных подключений• Требуется переподключение

Long-polling

Page 10: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

• Постоянное соединение• Намного быстрее, чем HTTP• Не везде поддерживаются• Еще не устоялись как стандарт

Page 11: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Выбор очевиден:*

* часто в сочетании с таймером

Page 12: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

• Ruby EventMachine• Python Twisted• Node.JS• Erlang

Page 13: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

“Стойте, я же могу простосделать это на чистом PHP!”

Page 14: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий
Page 15: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

• CGI - ~1000-2000• Apache - 1000-5000• Node.JS - 1000000 (?)• Erlang - 2277845

Лимит одновременных

подключений

Page 16: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий
Page 17: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Хранениевнутреннего состояния

• MySQL — надежно и очень медленно• Redis/memcached — ненадежно и медленно• Внутри VM — быстро и опасно• Репликация

Page 18: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Внутреннее состояние хочетсяреплицировать

Page 19: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Почти всегда нужнадоставка сообщений

Page 20: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

А еще, очень хочется failover

Page 21: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Нет решений для распределенного комета

из коробки

• Redis - master-slave репликация• RabbitMQ - нет истории• Memcached - нет сообщений

Page 22: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Все приходится делать самим

Page 23: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Нельзя просто так взять

и написать распределенныйcomet-сервер

Нельзя просто так взять

и написать распределенныйcomet-сервер

Page 24: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Почему Erlang• Феноменальная для веба производительность• Феноменальная для веба многоядерность• Распределенность из коробки• Отказоустойчивость• Изоляция данных

Page 25: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

DPS - distributed pub/sub

https://github.com/doubleyou/dps

Page 26: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Основные проблемы

Разные профили нагрузки: есть большие каналы и много маленьких.

Лаг между HTTP-ответом и коннектом к

комету: нужна история.

Нет времени на сохранение в SQL БД.

Page 27: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Хроника событий1. Реализация pub/sub-механизма2. Написание тестов3. Прикручивание веб-сервера4. Доработка напильником5. Бенчмарки6. ...

7. PROFIT!

Page 28: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

• Распределенный• Автоматический failover• Написан за 2.5 часа• Меньше 300 строк кода• Один race condition• Один баг-опечатка

Первый рабочий pub/sub

Page 29: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

dps:subscribe("Channel").

dps:publish("Channel", “Message”).

Page 30: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Тесты• Выявили race condition• Очень помогли в дальнейшей разработке• Отняли несколько часов• Покрыли примерно 80% кода pub/sub-части• По размеру сравнимы с кодом

Page 31: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Comet добавляется за час

Page 32: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Прикрутили чатик на JS.

Попутно оказалось, чтокроссдоменный long-pollне работает в Safari.

Page 33: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Все круто,

все работает.

Page 34: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Спасибо за внимание

Page 35: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

И тут пришли они

Page 36: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Попытка №0:подозрительно

хорошие результаты

Page 37: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Мы просто слали сообщенияи измеряли rps.

(Redis проигралуже на этом этапе)

Page 38: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Вывод:бенчмарки должны

соответствоватьпродакшну

Page 39: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Попытка №1

• Amazon EC2 large instances• 1000 клиентских подключений• 1 rps с каждого клиента

Page 40: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

На этот раз,бенчмарк-процессы

работают приближеннок живым клиентам

Page 41: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

• 20-140% CPU на одной машине• Репликация все убила

Page 42: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Структура на одной ноде

Page 43: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Репликация между нодами

Page 44: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Асинхронный publishна соседние нодыоблегчил ситуацию,

но не решил проблему.

Page 45: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Все дело в очередях

Page 46: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Низкое время ответаможет быть вредно

Page 47: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Выходы*

• Таймаут на клиенте• Таймаут на сервере• Пользовательские сессии

* лучше - в комбинации

Page 48: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Сессии - почти те же каналы

Page 49: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

• В памяти хранить минимум истории• Полную историю хранить на диске, если нужно• Гарантированное время ответа

Производительность

Page 50: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Long polling рассчитанна редкие ответы с сервера.

Page 51: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Как правило, лучше отправитьодин большой HTTP-ответ,чем много маленьких.

Page 52: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Попытка №2:

сервер тянет2000 rps,

хоть и с трудом.

Page 53: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Перевели каналыцеликом на ETS.

Page 54: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Попытка №3:

4000 rps!

Page 55: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Итого

Page 56: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Сервер написани протестирован

за несколько человеко-дней

Page 57: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Неплохая производительность:

WhatsApp - ~11500 rpsDPS - ~4000 rps

Функциональность и железо разные,но порядок цифр похожий.

Page 58: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Важные моменты• Не следует хранить всю историю в памяти• Следите, какие процессы перегружаются• Избегайте избыточных сообщений• Не делайте запросы слишком часто• Используйте пользовательские сессии• Старайтесь не гонять лишние данные

Page 59: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Erlang - не серебряная пуля,но позволяет фокусироваться

на болеевысокоуровневых задачах

Page 60: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Технические компромиссымогут заметно ускорить

работу сервера.

Page 61: Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий

Тесты и бенчмаркис лихвой окупили себя.