migrating from php/mysql to redis/lua, my talk on high load++ (russian)
DESCRIPTION
TRANSCRIPT
Опыт переезда соцсети с Livestreet
(PHP/MySQL) на NodeJS/Redis/LUA
Дмитрий Дегтярев
Чего в докладе нет
Highload
Silver bullet
Авторитет Гуру
План доклада
• Что лечим: Область применения, постановка задачи.
• Тестируем лекарство: Синтетические бенчмарки.
• Механика применения: Советы по использованию.
• Обмен опытом, обсуждение
Область применения: онлайн каталоги• Интернет-магазины, блоги, аукционы, сайты объявлений,
знакомств, соц. сети…• Основные запросы: чтение списка «товаров» с фасетным
поиском, страница «товара»• Информация часто меняется – счетчики лайков, цены, наличие,
дата последнего комментария• Множество блоков «смотрите также», «аксессуары», «еще на эту
тему», «сейчас обсуждают» и т.д.
7dach
Что имеем сейчас: время отдачи страниц
Livestr
eet
Livestr
eet noca
che
Mag
ento
Mag
ento noca
che
Custom PHP
Custom PHP noca
che
0
1000
2000
3000
4000
5000
6000
SQL запросовmsec
Постановка задачи
• Сокращение времени генерации страницы• Избавление от кэшей и необходимости их валидации• Применение удобных для разработки языков• Упрощение архитектуры, сокращение кол-ва элементов
Предпосылки к изменению: RAM
Источник: http://www.jcmit.com/mem2013.htm
Предпосылки: Junk-информацияJunk информация:• Посты, лайки, комменты, описания товаров, рекомендации
товаров, статистика кликов, чат-сообщения, счетчики нового• Не требует 100% целостности
Транзакционная информация:• Цены, платежи, заказы
Медиа информация: • Картинки, видео, аудио
Предпосылки: умные и быстрые клиенты• Развитие стандартов HTML5, JavaScript: ECMA-262, edition 5• Развитие клиентских библиотек: AngularJS, EmberJS, … много• Развитие клиентского железа: память, процессоры• Развитие поисковиков: Google _escaped_fragment_
Типичный представитель логики в веб-сервере: PHP+MySQL+MemCached
• постоянный маршаллинг данных PHP - MySQL - Memcached • процессы инициализации фреймворка при каждом вызове • кэши и механизмы их инвалидации • нормализованная структура данных и множество операций JOIN
таблиц • обращения к ФС, в том числе со стороны БД• часто борьба с транзакциями там, где они не нужны
“Обычная” архитектура
СУБД
Кэш
Доступ к даннымЛогикаШаблонизаторБраузер
Результатызапросов, объекты
Фрагменты HTML
HTML
Разносим логику
Варианты реализации:• Redis + LUA• Postgres + PL/SQL (умеет делать JSON)• …другие варианты
КэшДоступ к даннымЛогикаШаблонизаторБраузер
JSONJSONЛогикаПрокси
HandleBars Ember Ember-data NodeJS LUA Redis
Тестируем на данных блога• Топик - id, название, дата, анонс, картинка, пара счетчиков, author_id • Автор - id, имя, аватар• 3000 топиков, 1200 авторов• Получаем JSON со списком всех топиков и списком уникальных авторов
• Embedding = SQL JOIN, дублирование данных• Sideloading = сокращение объема данных, передача только уникальных
объектов
Результаты тестирования
PHP MySQL PHP MySQL MemCached
Postgres Redis Lua0.00
5.00
10.00
15.00
20.00
25.00
30.00
35.00
Один поток8 потоков
Postgres: работа с JSON
Redis+LUA
Выводы
• MySQL + Memcached это очень быстро для простых запросов• JSON функции в Postgres медленные• Redis не хватает многопоточной версии
Исходные коды тестов: https://github.com/Mitek99/dblogic-benchmark
Тестируем выборки с суммированием
PHP + MySQL Redis + Lua0
5
10
15
20
25
1 поток8 потоков
* ZUNIONSTORE + Sorted Set = очень медленно
MySQL
Redis + LUA: как устроеноtopic1_tags topic2_tags topic3_tags topic4_tags topic5_tags
ZUNIONSTORE sum_tags 5 topic1_tags topics2_tags topic3_tags topic5_tags AGGREGATE SUM
5 3 3 3 2 1 1
sum_tags
ZRANGE sum_tags 0 -1
Выводы
• MySQL и Postgres сами по себе очень быстрые• Медленными оказываются «движки» с плагинами• Логику на Redis+Lua писать можно и даже приятно• Сразу проектировать Master-Master репликацию уровня
приложения• Redis можно и нужно оптимизировать
Хранение, индексы, сортировки и выборки• WHERE FIELD=VALUE
• ORDER BY … LIMIT N
• GROUP BY
Создаем тэг “FIELD=VALUE” и ключ типа SET со множеством ID записей имеющих этот тэг. Используем SINTERSTORE или SUNIONSTORE
Создаем SORTED SET и используем ZINTERSTORE для выборки отсортированных элементов, потом ZRANGE для выбора N первых элементов
Создаем SORTED SET и используем ZINTERSTORE для выборки отсортированных элементов
Возможности библиотеки RNode
• Создание и обновление индексов• Выборки с ограничениями по тэгам• Суммирование по тэгам для построения фильтров• Sideloading связанных объектов• …Постоянно развивается• Доступно на GitHub: https://github.com/Mitek99/rnode