Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Comet-серверсвоими руками           Макс Лапшин        Дмитрий Демещук
Эволюция веба
Никакого real-time
Немного real-time
Сплошной real-time
После загрузки,современная страница    продолжаетжить своей жизнью.
Возможные варианты• Периодические запросы на сервер• Comet: • Long polling • Websockets • Server Sent Events
Периодические запросы• Много запросов впустую• Постоянная загрузка• Задержки
Long-polling• Не требует немедленного ответа• Совместим с keepalive• Моментальное обновление    • Много одновременных подк...
• Постоянное соединение• Намного быстрее, чем HTTP• Не везде поддерживаются• Еще не устоялись как стандарт
Выбор очевиден:** часто в сочетании с таймером
• Ruby EventMachine• Python Twisted• Node.JS• Erlang
“Стойте, я же могу простосделать это на чистом PHP!”
Лимит одновременных   подключений • CGI - ~1000-2000 • Apache - 1000-5000 • Node.JS - 1000000 (?) • Erlang - 2277845
Хранение    внутреннего состояния• MySQL — надежно и очень медленно• Redis/memcached — ненадежно и медленно• Внутри VM — б...
Внутреннее состояние хочется       реплицировать
Почти всегда нужнадоставка сообщений
А еще, очень хочется failover
Нет решений дляраспределенного комета      из коробки • Redis - master-slave репликация • RabbitMQ - нет истории • Memcach...
Все приходится делать самим
Нельзя просто так взятьи написать распределенный       comet-сервер
Почему Erlang• Феноменальная для веба производительность• Феноменальная для веба многоядерность• Распределенность из короб...
DPS - distributed pub/sub https://github.com/doubleyou/dps
Основные проблемыРазные профили нагрузки: есть большиеканалы и много маленьких.Лаг между HTTP-ответом и коннектом ккомету:...
Хроника событий1. Реализация pub/sub-механизма2. Написание тестов3. Прикручивание веб-сервера4. Доработка напильником5. Бе...
Первый рабочий pub/sub   • Распределенный   • Автоматический failover   • Написан за 2.5 часа   • Меньше 300 строк кода   ...
dps:subscribe("Channel").dps:publish("Channel", “Message”).
Тесты• Выявили race condition• Очень помогли в дальнейшей разработке• Отняли несколько часов• Покрыли примерно 80% кода pu...
Comet добавляется за час
Прикрутили чатик на JS.Попутно оказалось, чтокроссдоменный long-poll  не работает в Safari.
Все круто,все работает.
Спасибо за внимание
И тут пришли они
Попытка №0:   подозрительнохорошие результаты
Мы просто слали сообщения     и измеряли rps.     (Redis проиграл    уже на этом этапе)
Вывод:бенчмарки должны соответствовать    продакшну
Попытка №1• Amazon EC2 large instances• 1000 клиентских подключений• 1 rps с каждого клиента
На этот раз,  бенчмарк-процессыработают приближенно  к живым клиентам
• 20-140% CPU на одной машине• Репликация все убила
Структура на одной ноде
Репликация между нодами
Асинхронный publish   на соседние ноды облегчил ситуацию,но не решил проблему.
Все дело в очередях
Низкое время ответаможет быть вредно
Выходы*       • Таймаут на клиенте       • Таймаут на сервере       • Пользовательские сессии* лучше - в комбинации
Сессии - почти те же каналы
Производительность• В памяти хранить минимум истории• Полную историю хранить на диске, если нужно• Гарантированное время о...
Long polling рассчитанна редкие ответы с сервера.
Как правило, лучше отправить один большой HTTP-ответ,    чем много маленьких.
Попытка №2: сервер тянет    2000 rps,хоть и с трудом.
Перевели каналыцеликом на ETS.
Попытка №3:  4000 rps!
Итого
Сервер написан      и протестированза несколько человеко-дней
Неплохая производительность:  WhatsApp - ~11500 rps  DPS - ~4000 rps  Функциональность и железо разные,  но порядок цифр п...
Важные моменты• Не следует хранить всю историю в памяти• Следите, какие процессы перегружаются• Избегайте избыточных сообщ...
Erlang - не серебряная пуля,но позволяет фокусироваться           на более  высокоуровневых задачах
Технические компромиссы могут заметно ускорить     работу сервера.
Тесты и бенчмаркис лихвой окупили себя.
Вопросы?Дмитрий Демещук           Макс Лапшинdemeshchuk@gmail.com   max@maxidoors.ru
Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий Демещук)
Практическая реализация распределенного отказоустойчивого Comet сервера на Erlang (Максим Лапшин, Дмитрий Демещук)
Upcoming SlideShare
Loading in …5
×

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

1,951 views

Published on

  • Be the first to comment

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

  1. 1. Comet-серверсвоими руками Макс Лапшин Дмитрий Демещук
  2. 2. Эволюция веба
  3. 3. Никакого real-time
  4. 4. Немного real-time
  5. 5. Сплошной real-time
  6. 6. После загрузки,современная страница продолжаетжить своей жизнью.
  7. 7. Возможные варианты• Периодические запросы на сервер• Comet: • Long polling • Websockets • Server Sent Events
  8. 8. Периодические запросы• Много запросов впустую• Постоянная загрузка• Задержки
  9. 9. Long-polling• Не требует немедленного ответа• Совместим с keepalive• Моментальное обновление • Много одновременных подключений • Требуется переподключение
  10. 10. • Постоянное соединение• Намного быстрее, чем HTTP• Не везде поддерживаются• Еще не устоялись как стандарт
  11. 11. Выбор очевиден:** часто в сочетании с таймером
  12. 12. • Ruby EventMachine• Python Twisted• Node.JS• Erlang
  13. 13. “Стойте, я же могу простосделать это на чистом PHP!”
  14. 14. Лимит одновременных подключений • CGI - ~1000-2000 • Apache - 1000-5000 • Node.JS - 1000000 (?) • Erlang - 2277845
  15. 15. Хранение внутреннего состояния• MySQL — надежно и очень медленно• Redis/memcached — ненадежно и медленно• Внутри VM — быстро и опасно• Репликация
  16. 16. Внутреннее состояние хочется реплицировать
  17. 17. Почти всегда нужнадоставка сообщений
  18. 18. А еще, очень хочется failover
  19. 19. Нет решений дляраспределенного комета из коробки • Redis - master-slave репликация • RabbitMQ - нет истории • Memcached - нет сообщений
  20. 20. Все приходится делать самим
  21. 21. Нельзя просто так взятьи написать распределенный comet-сервер
  22. 22. Почему Erlang• Феноменальная для веба производительность• Феноменальная для веба многоядерность• Распределенность из коробки• Отказоустойчивость• Изоляция данных
  23. 23. DPS - distributed pub/sub https://github.com/doubleyou/dps
  24. 24. Основные проблемыРазные профили нагрузки: есть большиеканалы и много маленьких.Лаг между HTTP-ответом и коннектом ккомету: нужна история.Нет времени на сохранение в SQL БД.
  25. 25. Хроника событий1. Реализация pub/sub-механизма2. Написание тестов3. Прикручивание веб-сервера4. Доработка напильником5. Бенчмарки6. ...7. PROFIT!
  26. 26. Первый рабочий pub/sub • Распределенный • Автоматический failover • Написан за 2.5 часа • Меньше 300 строк кода • Один race condition • Один баг-опечатка
  27. 27. dps:subscribe("Channel").dps:publish("Channel", “Message”).
  28. 28. Тесты• Выявили race condition• Очень помогли в дальнейшей разработке• Отняли несколько часов• Покрыли примерно 80% кода pub/sub-части• По размеру сравнимы с кодом
  29. 29. Comet добавляется за час
  30. 30. Прикрутили чатик на JS.Попутно оказалось, чтокроссдоменный long-poll не работает в Safari.
  31. 31. Все круто,все работает.
  32. 32. Спасибо за внимание
  33. 33. И тут пришли они
  34. 34. Попытка №0: подозрительнохорошие результаты
  35. 35. Мы просто слали сообщения и измеряли rps. (Redis проиграл уже на этом этапе)
  36. 36. Вывод:бенчмарки должны соответствовать продакшну
  37. 37. Попытка №1• Amazon EC2 large instances• 1000 клиентских подключений• 1 rps с каждого клиента
  38. 38. На этот раз, бенчмарк-процессыработают приближенно к живым клиентам
  39. 39. • 20-140% CPU на одной машине• Репликация все убила
  40. 40. Структура на одной ноде
  41. 41. Репликация между нодами
  42. 42. Асинхронный publish на соседние ноды облегчил ситуацию,но не решил проблему.
  43. 43. Все дело в очередях
  44. 44. Низкое время ответаможет быть вредно
  45. 45. Выходы* • Таймаут на клиенте • Таймаут на сервере • Пользовательские сессии* лучше - в комбинации
  46. 46. Сессии - почти те же каналы
  47. 47. Производительность• В памяти хранить минимум истории• Полную историю хранить на диске, если нужно• Гарантированное время ответа
  48. 48. Long polling рассчитанна редкие ответы с сервера.
  49. 49. Как правило, лучше отправить один большой HTTP-ответ, чем много маленьких.
  50. 50. Попытка №2: сервер тянет 2000 rps,хоть и с трудом.
  51. 51. Перевели каналыцеликом на ETS.
  52. 52. Попытка №3: 4000 rps!
  53. 53. Итого
  54. 54. Сервер написан и протестированза несколько человеко-дней
  55. 55. Неплохая производительность: WhatsApp - ~11500 rps DPS - ~4000 rps Функциональность и железо разные, но порядок цифр похожий.
  56. 56. Важные моменты• Не следует хранить всю историю в памяти• Следите, какие процессы перегружаются• Избегайте избыточных сообщений• Не делайте запросы слишком часто• Используйте пользовательские сессии• Старайтесь не гонять лишние данные
  57. 57. Erlang - не серебряная пуля,но позволяет фокусироваться на более высокоуровневых задачах
  58. 58. Технические компромиссы могут заметно ускорить работу сервера.
  59. 59. Тесты и бенчмаркис лихвой окупили себя.
  60. 60. Вопросы?Дмитрий Демещук Макс Лапшинdemeshchuk@gmail.com max@maxidoors.ru

×