SlideShare a Scribd company logo
Роман Иманкулов-«Быстрые и масштабируемые приложения с Sync API»
План доклада
• Начать с какого-нибудь банального утверждения
• Раскритиковать проверенную временем технологию
• Представить собственное сомнительное решение
• ???
• PROFIT!!!
Все приличные веб-сервисы 

предоставляют RESTful API
C RESTful API 

что-то не так!
Response Times: The 3 Important Limits
• до 0.1 секунды

Пользователь манипулирует объектами напрямую
• до 1 секунды

Пользователь замечает задержку, но может работать с
интерфейсом
• 10 секунд

Предел терпения
Источник: http://www.nngroup.com/articles/response-times-3-important-limits/
Индексы для коллекций ресурсов
Например github.com issues
GET /issues

GET /user/issues

GET /orgs/:org/issues

GET /repos/:owner/:repo/issues
(и фильтры для milestone, state, assignee, creator, labels …)
Search API?
ElasticSearch, Solr, Sphinx?
Sync API
MySQL, Redis, мозг
Sync API
• Дополняет, а не заменяет RESTful API
• Клиенты: толстые, локально хранят копию данных с сервера
• Сервер: туповат, просто предоставляет API 

для получения кусочков данных
• Примеры применения:
• списки задач, заметок и т.д.
• панели управления ресурсами
• системы мониторинга, мгновенных уведомлений
Sync API в Todoist
• Основной API для всех официальных клиентов c 2012 года
• Работает на Redis и MySQL
• Обслуживает 1’000’000 активных пользователей
• Синхронизирует задачи между устройствами за 5 секунд
• Поддерживается командой из трех разработчиков
Sync API. Реализация
id content … deleted seq_no
1 foo FALSE 56
2 null TRUE 83
Таблица с объектами
seq_no:<uid1> 85
seq_no:<uid2> 167
Счетчик в Redis для каждого пользователя
Sync API. INSERT/UPDATE/DELETE
Получить следующий Sequence Number


INCR seq_no:<uid>

Манипулируя объектом, не забыть обновить seq_no
INSERT INTO table (…, seq_no) VALUES (..., <seq_no>)
UPDATE table SET … seq_no = <seq_no>
UPDATE table SET … is_deleted = TRUE, seq_no = <seq_no>
Sync API. Первоначальная синхронизация
Запрос


GET /api/sync
Подготовка ответа


MySQL: SELECT ... WHERE user_id=<uid> AND deleted=FALSE

Redis: GET seq_no:<uid>
Ответ


{"seq_no": <seq_no>: "objects": [...]}
Sync API. Частичная синхронизация
Запрос


GET /api/sync?seq_no=1234
Подготовка ответа


MySQL: SELECT ... WHERE user_id=<uid> AND seq_no > 1234

Redis: GET seq_no:<uid>
Ответ


{"seq_no": <seq_no>: "objects": [...]}
Sync API. Почему это хорошо
• Простая реализация
• Данные рядом с клиентом
• Один индекс в базе
• Push уведомления
Sync API. Что можно сделать лучше?
• Не хотим хранить удаленные объекты в базе!
• Не хотим B-tree индекс, который O(log n)
Синхронизация 

master-slave в Redis
Учимся у @antirez
slave master клиенты
sync
создаем буфер
готовим данные 

для отправки
Буфер
1 2 3 4
команды: A, B, C
A B C
возвращаем данные,



A, B, C, offset=3
команды: D, E, F
DE F
5 6
sync, offset=3
DEF, offset=6
Sync API v2. Redis backlog
Счетчик. Храним seq_no самого последнего сообщения в очереди


INCR seq_no:<uid>

Очередь. Добавляем id измененного объекта и подрезаем очередь


RPUSH queue:<user_id> <object_id>
LTRIM queue:<user_id> -1 -100
СерверКлиент Другие клиенты
счетчик буфер (redis list, max length: 4, хранит только ids)
создать объекты A, B, C
3
GET /api/sync
{seq_no: 3, objects: [A, B, C]}
создать D, изменить А, B
A
1
B
2
C
3
D
4
A
5
B
6
6
GET /api/sync?seq_no=3
{seq_no: 6, objects: [D, A, B]}
...
GET /api/sync?seq_no=1
Error: full sync required
Sync API v2. Redis backlog
• Индексы только по id и user_id.

Время поиска и вставки O(1)
• Очередь фиксированной длины, и только для активных клиентов. 

Память О($), где $ — количество платящих клиентов, 

1.5Kb на очередь из 200 сообщений

11 млн клиентов на 16Gb (m4.xlarge, 126$ в месяц)
• Клиент должен быть готов к "полной перезагрузке"
• Используется Evernote и Google Calendar?
Sync API. Ограничения localStorage
User Agent
Размер (тыс
символов)
Чтение из
10k (мс)
Чтение из
500k (мс)
Чтение из
макс (мс)
Chrome 33 5,120 3 20 1,026
Chrome
Mobile 32
5,120 28 164 1,066
Firefox 27 5,120 1 14 143
IE 11 4,883 15 32 872
Opera 19 5,120 7 36 313
Mobile Safari
7
2,560 16 37 104
Safari 7 2,560 11 44 177
Источник: https://www.stevesouders.com/blog/2014/02/11/measuring-localstorage-performance/
Ограничения localStorage. Что делать?
• Считывать данные в память при первой загрузке

для ускорения доступа
• Не хранить данные в JSON

преобразование списка объектов в CSV экономит до 50% места
• Сжимать данные

См. http://pieroxy.net/blog/pages/lz-string/index.html, до 95%
• Использовать вытесняющий кеш
Жизнеутверждающий финал
Sync API — это
• Простая реализация
• Данные рядом с клиентом
• Redis: память O(n), n — количество активных клиентов
• Бесплатные push уведомления

More Related Content

PDF
Юрий Насретдинов-«Сбор логов в «облаке» в Badoo»
PDF
Управление контейнерами в облаках
PPTX
Дмитрий Лазаренко-«Живая миграция и отказоустойчивость контейнеров в гибридно...
PDF
Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»
PDF
Архитектура хранения фотографий в Badoo
PDF
Юрий Насретдинов, Badoo
PPTX
Docker в работе: взгляд на использование в Badoo через год
PDF
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Юрий Насретдинов-«Сбор логов в «облаке» в Badoo»
Управление контейнерами в облаках
Дмитрий Лазаренко-«Живая миграция и отказоустойчивость контейнеров в гибридно...
Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»
Архитектура хранения фотографий в Badoo
Юрий Насретдинов, Badoo
Docker в работе: взгляд на использование в Badoo через год
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)

What's hot (20)

PPTX
обзор архитектуры и подсистем деплоя и мониторинга
PDF
Облако в Badoo год спустя
PDF
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
PPTX
Денис Иванов
PPTX
DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)
PDF
DC/OS – больше чем PAAS, Никита Борзых (Express 42)
PPTX
Антон Турецкий
PDF
«Миллион открытых каналов с данными по сети» – Илья Биин (Zenhotels)
PDF
Что нового и полезного в PostgreSQL 9.5 / Илья Космодемьянский (PostgreSQL-Co...
PDF
Реализация восстановления после аварий / Сергей Бурладян (Avito)
PDF
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
PDF
Twisted Framework - сетевые приложения в Python
PPTX
Системный администратор Vkontakte. Как? / Антон Кирюшкин (Vkontakte)
PDF
Консольные приложения на Go
PDF
Андрей Федоренчик- «Высоконагруженная система с аналитикой на InfoBright»
PDF
Twisted Framework - фреймворк для написания сетевых приложений на Python (Анд...
PPTX
SOA: строим свой service mesh / Иван Круглов (Booking.com)
PDF
Внедрение Docker в процесс разработки демонов. Доклад Константина Карпова на ...
PDF
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
PPTX
Что нового в nginx? / Максим Дунин (Nginx, Inc.)
обзор архитектуры и подсистем деплоя и мониторинга
Облако в Badoo год спустя
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
Денис Иванов
DNS в условиях хостинг-провайдера / Константин Новаковский (Selectel)
DC/OS – больше чем PAAS, Никита Борзых (Express 42)
Антон Турецкий
«Миллион открытых каналов с данными по сети» – Илья Биин (Zenhotels)
Что нового и полезного в PostgreSQL 9.5 / Илья Космодемьянский (PostgreSQL-Co...
Реализация восстановления после аварий / Сергей Бурладян (Avito)
Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)
Twisted Framework - сетевые приложения в Python
Системный администратор Vkontakte. Как? / Антон Кирюшкин (Vkontakte)
Консольные приложения на Go
Андрей Федоренчик- «Высоконагруженная система с аналитикой на InfoBright»
Twisted Framework - фреймворк для написания сетевых приложений на Python (Анд...
SOA: строим свой service mesh / Иван Круглов (Booking.com)
Внедрение Docker в процесс разработки демонов. Доклад Константина Карпова на ...
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Что нового в nginx? / Максим Дунин (Nginx, Inc.)
Ad

Viewers also liked (9)

PPTX
Дмитрий Дурасов-«Технологии контейнеризации в Windows Server 2016»
PPTX
Михаил Серченя-«Построение отказоустойчивой масштабируемой среды для WEB и бе...
PPTX
Павел Вейник-«Программирование и лингвистика: как понять язык и как извлечь з...
PDF
Максим Барышиков-«WoT: Geographically distributed cluster of clusters»
PDF
Левон Авакян-«Эволюция кланов в Wargaming. От веб страницы на танковом портал...
PDF
Александр Ломов-«Как перестать беспокоиться и начать использовать Cloud Foundry»
PDF
Дмитрий Хоревич "Cloud native security with UAA \ Как защитить микросервисы с...
PPTX
Максим Барышников (Wargaming.net)
PPTX
Как мы считали трафик на Вертике, Николай Голов (Avito)
Дмитрий Дурасов-«Технологии контейнеризации в Windows Server 2016»
Михаил Серченя-«Построение отказоустойчивой масштабируемой среды для WEB и бе...
Павел Вейник-«Программирование и лингвистика: как понять язык и как извлечь з...
Максим Барышиков-«WoT: Geographically distributed cluster of clusters»
Левон Авакян-«Эволюция кланов в Wargaming. От веб страницы на танковом портал...
Александр Ломов-«Как перестать беспокоиться и начать использовать Cloud Foundry»
Дмитрий Хоревич "Cloud native security with UAA \ Как защитить микросервисы с...
Максим Барышников (Wargaming.net)
Как мы считали трафик на Вертике, Николай Голов (Avito)
Ad

Similar to Роман Иманкулов-«Быстрые и масштабируемые приложения с Sync API» (20)

PPTX
RESTful API: Best practices, versioning, design documentation
PPTX
Industrial Programming Java - Lection Pack 02 - Distributed applications - La...
PDF
PDF
noBackend, или Как выжить в эпоху толстеющих клиентов / Самохвалов Николай
PDF
#noBackend, или Как выжить в эпоху толстеющих клиентов
PDF
Вебинар "Разработка высоконагруженных и надежных систем": Введение
PDF
Обзор Redis storage / Symfony Camp UA 2011
PDF
AVITO. Решардинг Redis без даунтайма. DevConf 2012
PDF
Рефакторинг монолита в микросервисы на Go
PDF
Рефакторинг монолита в микросервисы на Go / Refactoring of Monolithe to Micro...
PPT
Redis: возможности, выгоды, примеры использования
PPTX
Проектирование высоконагруженного масштабируемого веб-сервиса в облаке на при...
PDF
Распределенные системы в Одноклассниках
PDF
Анатомия веб-сервиса, Андрей Смирнов
PDF
Анатомия веб-сервиса (РИТ-2014)
PDF
Распределенные системы в Одноклассниках / Олег Анастасьев (Одноклассники)
PDF
Борис Каплуновский, Aviasales.ru
PDF
DUMP-2015 «Микросервисная архитектура в теории и на практике» Иван Бурмистров...
PDF
Юлия Цисык «RESTFul API в вашем.NET приложении: как, зачем и почему?»
PPT
Rybak Big Projects New
RESTful API: Best practices, versioning, design documentation
Industrial Programming Java - Lection Pack 02 - Distributed applications - La...
noBackend, или Как выжить в эпоху толстеющих клиентов / Самохвалов Николай
#noBackend, или Как выжить в эпоху толстеющих клиентов
Вебинар "Разработка высоконагруженных и надежных систем": Введение
Обзор Redis storage / Symfony Camp UA 2011
AVITO. Решардинг Redis без даунтайма. DevConf 2012
Рефакторинг монолита в микросервисы на Go
Рефакторинг монолита в микросервисы на Go / Refactoring of Monolithe to Micro...
Redis: возможности, выгоды, примеры использования
Проектирование высоконагруженного масштабируемого веб-сервиса в облаке на при...
Распределенные системы в Одноклассниках
Анатомия веб-сервиса, Андрей Смирнов
Анатомия веб-сервиса (РИТ-2014)
Распределенные системы в Одноклассниках / Олег Анастасьев (Одноклассники)
Борис Каплуновский, Aviasales.ru
DUMP-2015 «Микросервисная архитектура в теории и на практике» Иван Бурмистров...
Юлия Цисык «RESTFul API в вашем.NET приложении: как, зачем и почему?»
Rybak Big Projects New

More from Tanya Denisyuk (19)

PDF
Николай Сивко "Хорошо поддерживаемое в продакшне приложение"
PDF
Артем Маринов "Сегментируем 600 млн. пользователей в режиме реального времени...
PDF
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
PDF
Вадим Мадисон "Опыт разработки через микросервисы"
PDF
Сергей Аверин "Распространенные ошибки применения баз данных"
PPTX
Сергей Сверчков "Want to build a secure private cloud for IoT with high avail...
PDF
Левон Авакян "Архитектура мета игры Wargaming. Глобальная карта 2.0"
PDF
Артем Маринов "Сегментируем 600 млн. пользователей в режиме реального времени...
PDF
Артем Гавриченков "The Dark Side of Things: Distributed Denial of Service Att...
PDF
Алексей Лесовский "Тюнинг Linux для баз данных. "
PPTX
Александр Краковецкий "Разработка интеллектуальных ботов с помощью Microsoft ...
PDF
Алексей Залесов-«Управление контейнерами в облаках»
PDF
Антон Щербаков, Отказоустойчивость на примере aviasales — почему даже если на...
PDF
Александр Тоболь, Кадры решают все, или стриминг видео в Одноклассниках
PDF
Денис Баталов, Принципы построения высоконагруженных сайтов на платформе АWS
PDF
Кирилл Алешин, Ламбда Архитектура на практике
PDF
Михаил Табунов, Аналитическая платформа на несколько миллиардов событий в месяц
PDF
Alvaro Videla, Building a Distributed Data Ingestion System with RabbitMQ
PDF
Антон Тюрин, Евгений Сафронов, Инфраструктура под Cocaine
Николай Сивко "Хорошо поддерживаемое в продакшне приложение"
Артем Маринов "Сегментируем 600 млн. пользователей в режиме реального времени...
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Вадим Мадисон "Опыт разработки через микросервисы"
Сергей Аверин "Распространенные ошибки применения баз данных"
Сергей Сверчков "Want to build a secure private cloud for IoT with high avail...
Левон Авакян "Архитектура мета игры Wargaming. Глобальная карта 2.0"
Артем Маринов "Сегментируем 600 млн. пользователей в режиме реального времени...
Артем Гавриченков "The Dark Side of Things: Distributed Denial of Service Att...
Алексей Лесовский "Тюнинг Linux для баз данных. "
Александр Краковецкий "Разработка интеллектуальных ботов с помощью Microsoft ...
Алексей Залесов-«Управление контейнерами в облаках»
Антон Щербаков, Отказоустойчивость на примере aviasales — почему даже если на...
Александр Тоболь, Кадры решают все, или стриминг видео в Одноклассниках
Денис Баталов, Принципы построения высоконагруженных сайтов на платформе АWS
Кирилл Алешин, Ламбда Архитектура на практике
Михаил Табунов, Аналитическая платформа на несколько миллиардов событий в месяц
Alvaro Videla, Building a Distributed Data Ingestion System with RabbitMQ
Антон Тюрин, Евгений Сафронов, Инфраструктура под Cocaine

Роман Иманкулов-«Быстрые и масштабируемые приложения с Sync API»

  • 2. План доклада • Начать с какого-нибудь банального утверждения • Раскритиковать проверенную временем технологию • Представить собственное сомнительное решение • ??? • PROFIT!!!
  • 3. Все приличные веб-сервисы 
 предоставляют RESTful API
  • 4. C RESTful API 
 что-то не так!
  • 5. Response Times: The 3 Important Limits • до 0.1 секунды
 Пользователь манипулирует объектами напрямую • до 1 секунды
 Пользователь замечает задержку, но может работать с интерфейсом • 10 секунд
 Предел терпения Источник: http://www.nngroup.com/articles/response-times-3-important-limits/
  • 6. Индексы для коллекций ресурсов Например github.com issues GET /issues
 GET /user/issues
 GET /orgs/:org/issues
 GET /repos/:owner/:repo/issues (и фильтры для milestone, state, assignee, creator, labels …)
  • 9. Sync API • Дополняет, а не заменяет RESTful API • Клиенты: толстые, локально хранят копию данных с сервера • Сервер: туповат, просто предоставляет API 
 для получения кусочков данных • Примеры применения: • списки задач, заметок и т.д. • панели управления ресурсами • системы мониторинга, мгновенных уведомлений
  • 10. Sync API в Todoist • Основной API для всех официальных клиентов c 2012 года • Работает на Redis и MySQL • Обслуживает 1’000’000 активных пользователей • Синхронизирует задачи между устройствами за 5 секунд • Поддерживается командой из трех разработчиков
  • 11. Sync API. Реализация id content … deleted seq_no 1 foo FALSE 56 2 null TRUE 83 Таблица с объектами seq_no:<uid1> 85 seq_no:<uid2> 167 Счетчик в Redis для каждого пользователя
  • 12. Sync API. INSERT/UPDATE/DELETE Получить следующий Sequence Number 
 INCR seq_no:<uid>
 Манипулируя объектом, не забыть обновить seq_no INSERT INTO table (…, seq_no) VALUES (..., <seq_no>) UPDATE table SET … seq_no = <seq_no> UPDATE table SET … is_deleted = TRUE, seq_no = <seq_no>
  • 13. Sync API. Первоначальная синхронизация Запрос 
 GET /api/sync Подготовка ответа 
 MySQL: SELECT ... WHERE user_id=<uid> AND deleted=FALSE
 Redis: GET seq_no:<uid> Ответ 
 {"seq_no": <seq_no>: "objects": [...]}
  • 14. Sync API. Частичная синхронизация Запрос 
 GET /api/sync?seq_no=1234 Подготовка ответа 
 MySQL: SELECT ... WHERE user_id=<uid> AND seq_no > 1234
 Redis: GET seq_no:<uid> Ответ 
 {"seq_no": <seq_no>: "objects": [...]}
  • 15. Sync API. Почему это хорошо • Простая реализация • Данные рядом с клиентом • Один индекс в базе • Push уведомления
  • 16. Sync API. Что можно сделать лучше? • Не хотим хранить удаленные объекты в базе! • Не хотим B-tree индекс, который O(log n)
  • 17. Синхронизация 
 master-slave в Redis Учимся у @antirez
  • 18. slave master клиенты sync создаем буфер готовим данные 
 для отправки Буфер 1 2 3 4 команды: A, B, C A B C возвращаем данные,
 
 A, B, C, offset=3 команды: D, E, F DE F 5 6 sync, offset=3 DEF, offset=6
  • 19. Sync API v2. Redis backlog Счетчик. Храним seq_no самого последнего сообщения в очереди 
 INCR seq_no:<uid>
 Очередь. Добавляем id измененного объекта и подрезаем очередь 
 RPUSH queue:<user_id> <object_id> LTRIM queue:<user_id> -1 -100
  • 20. СерверКлиент Другие клиенты счетчик буфер (redis list, max length: 4, хранит только ids) создать объекты A, B, C 3 GET /api/sync {seq_no: 3, objects: [A, B, C]} создать D, изменить А, B A 1 B 2 C 3 D 4 A 5 B 6 6 GET /api/sync?seq_no=3 {seq_no: 6, objects: [D, A, B]} ... GET /api/sync?seq_no=1 Error: full sync required
  • 21. Sync API v2. Redis backlog • Индексы только по id и user_id.
 Время поиска и вставки O(1) • Очередь фиксированной длины, и только для активных клиентов. 
 Память О($), где $ — количество платящих клиентов, 
 1.5Kb на очередь из 200 сообщений
 11 млн клиентов на 16Gb (m4.xlarge, 126$ в месяц) • Клиент должен быть готов к "полной перезагрузке" • Используется Evernote и Google Calendar?
  • 22. Sync API. Ограничения localStorage User Agent Размер (тыс символов) Чтение из 10k (мс) Чтение из 500k (мс) Чтение из макс (мс) Chrome 33 5,120 3 20 1,026 Chrome Mobile 32 5,120 28 164 1,066 Firefox 27 5,120 1 14 143 IE 11 4,883 15 32 872 Opera 19 5,120 7 36 313 Mobile Safari 7 2,560 16 37 104 Safari 7 2,560 11 44 177 Источник: https://www.stevesouders.com/blog/2014/02/11/measuring-localstorage-performance/
  • 23. Ограничения localStorage. Что делать? • Считывать данные в память при первой загрузке
 для ускорения доступа • Не хранить данные в JSON
 преобразование списка объектов в CSV экономит до 50% места • Сжимать данные
 См. http://pieroxy.net/blog/pages/lz-string/index.html, до 95% • Использовать вытесняющий кеш
  • 24. Жизнеутверждающий финал Sync API — это • Простая реализация • Данные рядом с клиентом • Redis: память O(n), n — количество активных клиентов • Бесплатные push уведомления