Инструменты 
высоконагруженных проектов: 
кеширование (Memcached, Redis), 
очереди (RabbitMQ) 
Вячеслав Москаленко
Содержание 
Инструменты кеширования данных 
• Memcached 
• Redis 
• Основные различия Memcached & Redis 
• Практическое использование Memcached & Redis 
Очереди 
• RabbitMQ, основные понятия и принцип работы 
• Различные типы обменников – Direct, Fanout, Topic 
• Практическое применение очередей
Кеширование 
Кеш - посредник между клиентом, который запрашивает данные, и основным 
хранилищем, способный очень быстро отдавать данные 
• скорость получения данных из кеша на порядок выше, чем из основной 
большой и медленной БД 
• как правило, кеш хранится в оперативной памяти сервера, за счет чего доступ 
к таким данным происходит моментально 
• эффективное использование кеша снижает нагрузку на сервер 
Когда, что и какими инструментами кешировать? 
• полезно кешировать часто запрашиваемые данные 
• необходимо понимать, какие данные можно кешировать, а какие нет 
• инструменты: Memcached, Redis и др.
Memcached 
• Memcached - сервис для кеширования данных в оперативной 
памяти, обладающий высокой производительностью 
• История – разработан Brad Fitzpatrick для Livejournal в 2003 
г. 
• Цели - кеширование часто запрашиваемых данных, для 
снижения нагрузки на БД 
• Используют – Livejournal, Twitter, Youtube и др.
Memcached. Возможности 
Возможности: 
1. Быстрая работа, нет зависимости от количества данных О(1) 
2. Простой интерфейс – set/get/del 
3. Атомарные операции – incr/decr, append/prepend 
4. Хранение ключей на нескольких серверах 
Ограничения: 
1. Длина ключа – 250 байт 
2. Объём данных по одному ключу – 1Mb 
3. Потеря ключей – при лимите памяти, по ttl, отказ сервера
Memcached. Пример 
Реализации для PHP: 
• расширение для libmemcached 
• расширение php-memcache 
Использование: простой интерфейс set / get / delete
Redis 
1. Поддержка различных типов данных – строки, хэши, списки, 
множества, сортированные множества 
2. Сохранение на диск 
3. Поддержка LRU, различные стратегии очистки ключей 
4. master-slave репликация 
5. Реализация очередей Sub/Pub 
6. Транзакции MULTI/EXEC 
7. Поддержка LUA скриптов 
8. Отличная документация
Redis. Типы данных 
1. Строки (String) 
2. Хэши (Hash)
Redis. Типы данных 
3. Множества (Sets) 
4. Сортированные множества (Sorted Sets)
Redis. Клиенты для PHP 
• phpredis – модуль для PHP, написан на С 
• Predis – библиотека, написанная на PHP 
• Rediska – PHP реализация 
• RedisServer – класс для работы с Redis, написанный на PHP 
• Resident – форк RedisServer, используется phpredis, если он установлен 
Рекомендации: 
использование расширения phpredis, написанного на C, по тестам - самый 
быстрый для работы с Redis
Memcached или Redis? 
Redis: 
• больше возможностей: очереди, 
транзакции, различные типы 
данных 
• позволяет хранить до 512 Mb в 
значениях 
• поддерживает master-slave 
репликацию, кластеризация с 
версии 3.0 (RC) 
• можно использовать как 
постоянное хранилище данных 
• производительность сравнима 
с Memcached 
Memcached : 
• быстрее, чем Redis, но на 
практике эта разница 
практически не заметна 
• хорош в качестве кеша, но есть 
множество задач с которыми 
Redis справится не хуже, а для 
некоторых задач и лучше, чем 
Memcached в силу своих 
возможностей
Пример 1. Кеш карточки товара 
Задача: реализация быстрого просмотра в Popup карточки товара, с минимальным 
обращением в бэкенд
Пример 1. Кеш карточки товара 
На схеме: 
1 - данные из Memcached 
2 - данных в Memcached нет 
2a - но есть в Redis 
2b - запрос в MySQL + 
сохранение в 
Redis/Memcached
Пример 2. Параметрический поиск 
Реализация: 
• хранение заранее 
обсчитанных множеств 
товаров (ID) для каждого 
варианта фильтра в Redis 
Используемы типы данных: 
• Hashes (информация о 
фильтрах) 
• Sets (множества товаров) 
• Sorted Sets (список фильтров 
и их вариантов)
Пример 2. Параметрический поиск 
Данные по фильтрам в категории “Телефоны” (id = 100): 
Фильтр / Вариант ID товаров Ключ в Redis 
1. Производитель / SAMSUNG { 201, 202, 203, 204 } plist:c:100:f:producer:v:samsung 
2. Производитель / PHILIPS { 301, 302, 303 } plist:c:100:f:producer:v:philips 
3. Цвет / Красный { 202, 303, 701 } plist:c:100:f:color:v:red 
Конкретные выборки: 
Телефоны Samsung + Philips (7 эл.): { 201, 202, 203, 204, 301, 302, 303 } 
Телефоны Samsung + Philips / красные (2 эл.): { 202, 303 } 
Особенности реализации: 
• существенно быстрее, чем сложные выборки из MySQL 
НО: необходимо обновлять необходимые множества при каждом 
изменении сущностей, которые могут повлиять на состав фильтров
Очереди. RabbitMQ 
Платформа, реализующая систему обмена сообщениями посредством протокола 
AQMP (Advanced Messaging Queue Protocol) 
Особенности: 
• надежность 
• гибкая система маршрутов сообщений 
• поддержка кластеризации 
• поддержка плагинов (мониторинг системы, кастомное поведение, и др.) 
• написан на Erlang 
• клиенты для большинства языков: Java, Ruby, Python, .NET, PHP, Perl, 
C/C++ и др.
RabbitMQ. Основные термины 
Producer – программа, которая посылает сообщения 
Exchange – обменник, все сообщения проходят через обменник 
Queue – очередь, хранится в «кролике», может содержать сколь 
угодно много сообщений (бесконечный буфер). Сообщения лежат 
именно в очередях. Посылать сообщения может один и более 
producer-ов, читать их тоже 
Consumer – программа получатель сообщений 
Простейший workflow:
Обменник с типом Direct 
• для задания маршрута 
необходимо «забиндить» 
очередь с обменником, 
используя binding_key 
• сообщения попадают в 
очередь согласно правилу 
равенства ключей: 
routing_key = binding_key
Обменник с типом Fanout 
• сообщения попадают во 
все очереди, связанные с 
обменником 
• не важно какой 
routing_key у сообщения
Обменник с типом Topic 
Правила для binding_key: 
1. * (звездочка) может быть заменена на 
ровно на одно слово 
2. # (решетка) может быть заменена на 0 
и более слов 
Routing Key Queue 
quick.orange.rabbit (*.orange.*, *.*.rabbit) Q1, Q2 
lazy.orange.elephant (lazy.#, *.orange.*) Q1, Q2 
quick.orange.fox (*.orange.*) Q1 
lazy.red.fox (lazy.#) Q2
RabbitMQ на практике 
• Использование брокера сообщений RabbitMQ для выполнения отложенных 
трудоемких задач 
• Пересчет множеств хранящихся в Redis при изменениях сущностей системы 
• Консьюмеры пишут в master 
• Фронтэнд читает со slave
Спасибо за внимание!

Конференция Highload++ 2014, "Инструменты высоконагруженных проектов: кеширование (Memcached, Redis), очереди (RabbitMQ)", Вячеслав Москаленко, "Ленвендо"

  • 1.
    Инструменты высоконагруженных проектов: кеширование (Memcached, Redis), очереди (RabbitMQ) Вячеслав Москаленко
  • 2.
    Содержание Инструменты кешированияданных • Memcached • Redis • Основные различия Memcached & Redis • Практическое использование Memcached & Redis Очереди • RabbitMQ, основные понятия и принцип работы • Различные типы обменников – Direct, Fanout, Topic • Практическое применение очередей
  • 3.
    Кеширование Кеш -посредник между клиентом, который запрашивает данные, и основным хранилищем, способный очень быстро отдавать данные • скорость получения данных из кеша на порядок выше, чем из основной большой и медленной БД • как правило, кеш хранится в оперативной памяти сервера, за счет чего доступ к таким данным происходит моментально • эффективное использование кеша снижает нагрузку на сервер Когда, что и какими инструментами кешировать? • полезно кешировать часто запрашиваемые данные • необходимо понимать, какие данные можно кешировать, а какие нет • инструменты: Memcached, Redis и др.
  • 4.
    Memcached • Memcached- сервис для кеширования данных в оперативной памяти, обладающий высокой производительностью • История – разработан Brad Fitzpatrick для Livejournal в 2003 г. • Цели - кеширование часто запрашиваемых данных, для снижения нагрузки на БД • Используют – Livejournal, Twitter, Youtube и др.
  • 5.
    Memcached. Возможности Возможности: 1. Быстрая работа, нет зависимости от количества данных О(1) 2. Простой интерфейс – set/get/del 3. Атомарные операции – incr/decr, append/prepend 4. Хранение ключей на нескольких серверах Ограничения: 1. Длина ключа – 250 байт 2. Объём данных по одному ключу – 1Mb 3. Потеря ключей – при лимите памяти, по ttl, отказ сервера
  • 6.
    Memcached. Пример Реализациидля PHP: • расширение для libmemcached • расширение php-memcache Использование: простой интерфейс set / get / delete
  • 7.
    Redis 1. Поддержкаразличных типов данных – строки, хэши, списки, множества, сортированные множества 2. Сохранение на диск 3. Поддержка LRU, различные стратегии очистки ключей 4. master-slave репликация 5. Реализация очередей Sub/Pub 6. Транзакции MULTI/EXEC 7. Поддержка LUA скриптов 8. Отличная документация
  • 8.
    Redis. Типы данных 1. Строки (String) 2. Хэши (Hash)
  • 9.
    Redis. Типы данных 3. Множества (Sets) 4. Сортированные множества (Sorted Sets)
  • 10.
    Redis. Клиенты дляPHP • phpredis – модуль для PHP, написан на С • Predis – библиотека, написанная на PHP • Rediska – PHP реализация • RedisServer – класс для работы с Redis, написанный на PHP • Resident – форк RedisServer, используется phpredis, если он установлен Рекомендации: использование расширения phpredis, написанного на C, по тестам - самый быстрый для работы с Redis
  • 11.
    Memcached или Redis? Redis: • больше возможностей: очереди, транзакции, различные типы данных • позволяет хранить до 512 Mb в значениях • поддерживает master-slave репликацию, кластеризация с версии 3.0 (RC) • можно использовать как постоянное хранилище данных • производительность сравнима с Memcached Memcached : • быстрее, чем Redis, но на практике эта разница практически не заметна • хорош в качестве кеша, но есть множество задач с которыми Redis справится не хуже, а для некоторых задач и лучше, чем Memcached в силу своих возможностей
  • 12.
    Пример 1. Кешкарточки товара Задача: реализация быстрого просмотра в Popup карточки товара, с минимальным обращением в бэкенд
  • 13.
    Пример 1. Кешкарточки товара На схеме: 1 - данные из Memcached 2 - данных в Memcached нет 2a - но есть в Redis 2b - запрос в MySQL + сохранение в Redis/Memcached
  • 14.
    Пример 2. Параметрическийпоиск Реализация: • хранение заранее обсчитанных множеств товаров (ID) для каждого варианта фильтра в Redis Используемы типы данных: • Hashes (информация о фильтрах) • Sets (множества товаров) • Sorted Sets (список фильтров и их вариантов)
  • 15.
    Пример 2. Параметрическийпоиск Данные по фильтрам в категории “Телефоны” (id = 100): Фильтр / Вариант ID товаров Ключ в Redis 1. Производитель / SAMSUNG { 201, 202, 203, 204 } plist:c:100:f:producer:v:samsung 2. Производитель / PHILIPS { 301, 302, 303 } plist:c:100:f:producer:v:philips 3. Цвет / Красный { 202, 303, 701 } plist:c:100:f:color:v:red Конкретные выборки: Телефоны Samsung + Philips (7 эл.): { 201, 202, 203, 204, 301, 302, 303 } Телефоны Samsung + Philips / красные (2 эл.): { 202, 303 } Особенности реализации: • существенно быстрее, чем сложные выборки из MySQL НО: необходимо обновлять необходимые множества при каждом изменении сущностей, которые могут повлиять на состав фильтров
  • 16.
    Очереди. RabbitMQ Платформа,реализующая систему обмена сообщениями посредством протокола AQMP (Advanced Messaging Queue Protocol) Особенности: • надежность • гибкая система маршрутов сообщений • поддержка кластеризации • поддержка плагинов (мониторинг системы, кастомное поведение, и др.) • написан на Erlang • клиенты для большинства языков: Java, Ruby, Python, .NET, PHP, Perl, C/C++ и др.
  • 17.
    RabbitMQ. Основные термины Producer – программа, которая посылает сообщения Exchange – обменник, все сообщения проходят через обменник Queue – очередь, хранится в «кролике», может содержать сколь угодно много сообщений (бесконечный буфер). Сообщения лежат именно в очередях. Посылать сообщения может один и более producer-ов, читать их тоже Consumer – программа получатель сообщений Простейший workflow:
  • 18.
    Обменник с типомDirect • для задания маршрута необходимо «забиндить» очередь с обменником, используя binding_key • сообщения попадают в очередь согласно правилу равенства ключей: routing_key = binding_key
  • 19.
    Обменник с типомFanout • сообщения попадают во все очереди, связанные с обменником • не важно какой routing_key у сообщения
  • 20.
    Обменник с типомTopic Правила для binding_key: 1. * (звездочка) может быть заменена на ровно на одно слово 2. # (решетка) может быть заменена на 0 и более слов Routing Key Queue quick.orange.rabbit (*.orange.*, *.*.rabbit) Q1, Q2 lazy.orange.elephant (lazy.#, *.orange.*) Q1, Q2 quick.orange.fox (*.orange.*) Q1 lazy.red.fox (lazy.#) Q2
  • 21.
    RabbitMQ на практике • Использование брокера сообщений RabbitMQ для выполнения отложенных трудоемких задач • Пересчет множеств хранящихся в Redis при изменениях сущностей системы • Консьюмеры пишут в master • Фронтэнд читает со slave
  • 22.