Сергей Чистович "Подходы к кешированию на UGC-сервисе"
-
Upload
yandex -
Category
Technology
-
view
302 -
download
2
description
Transcript of Сергей Чистович "Подходы к кешированию на UGC-сервисе"
Я.Субботник, Санкт-‐Петербург, 3 декабря 2011 года
Руководитель группы сервисов общения Сергей Чистович
Подходы к кешированию в UGC-‐сервисе
2
Какую проблему решаем?
— Повышение надёжности и производительности — уменьшение нагрузки на базу данных
для определённого типа сервисов
3
Что за сервис?
Социальная сеть, форум, блогохостинг:
— Много пользователей
— Много статей
— Много настроек
— Уведомления, сообщения, ограничения доступа и т.д.
например, Я.ру
4
В каком смысле кеширование?
Кеширование – это набор средств и приёмов для повышения надёжности и/или производительности системы за счёт уменьшения потребности в формировании и/или передачи данных.
5
Что насчёт архитектуры?
Типичный веб-‐сервис:
— Снаружи пользователи
— Перед ними веб-‐сервер
— За ним бэкэнд
— А за ним база данных (MySQL, да?)
6
Где может тормозить?
— Получить данные из БД
— Сформировать html/json/whatever
— Передать по сети
— Отобразить в браузере
Как будем лечить?
7
8
Есть проблема? Есть решение!
— Тормозит форматирование? Поставь больше бэкэндов!
— Работает всегда
— Просто в реализации
— Тормозят запросы? Шардируй базу!
— Работает отчасти
— Требует программирования
Будем фокусироваться на проблемах с БД.
9
Коллективное бессознательное
Рекомендации по кешированию из интернетов:
— Закешируйте самые популярные блоки
— В query cache БД или в memcache
— Прямо готовым html
не работают (в нашем случае)
10
Кто виноват?
— У нас нет «популярных» блоков
— У каждого пользователя свой взгляд на сервис — Ограничения доступа
— Настройки
— Уведомления и счётчики
— Френдлента
— Активных данных гораздо больше
11
Что делать?
База не справляется со сложными запросами?
— Оптимизируй их! — Настрой её! — Прокачай её! — Не помогло? Слишком много данных? — Включи голову!
12
Корни проблемы
— Данные меняются очень быстро — Кеш инвалидируется, не успев сработать
— Слишком много параметров — Засорение кеша, низкий hit rate
но мы всё-‐таки попробуем.
13
Где можно кешировать?
— В приложении
— В базе
— Во внешнем кеше
(и в чём разница?)
14
Пример: глобальные константы
— Можно кешировать в приложении
— Экономия на запросах или
— Экономия на сложности запросов
15
Пример: счётчики
Счётчики уведомлений, друзей и т.д.
SELECT COUNT(*) FROM messages WHERE uid=12345;
При большом объёме данных начинает тормозить.
16
Счётчики – в кеш
— Очень компактные данные
— Ключ – только один uid
— Изменяются не очень часто
Положим результат запроса в кеш?
работает до какого-‐то предела.
17
Счётчики -‐ инкрементальные
— Изменяем значение в ответ на действия
— триггерами/процедурами в БД
— или просто в коде
— Храним в БД (персистентность)
— Нужно иногда пересчитывать
18
Пример: френдлента
— Тоже может быть инкрементальной
— Но очень много данных
— И очень много обновлений
19
А если более мощный ключ?
— Количество общих друзей (UID1, UID2)
— Информация о записи (FEED, ITEM, UID)
— Блоки в анкете (UID1, CATEGORY, UID2)
20
Это ни в какой кеш не лезет!
— Хранить только для избранных
— предсказывать востребованность ключа
— Уменьшать кардинальность ключа
21
Пример: информация о посте
В лоб:
return getMessage(FEED, ITEM, VIEWER)
Мощность пространства ключей – N2, и к тому же объём данных большой.
Фактически зависит не от VIEWER, а от relation(FEED, VIEWER).
22
Пример: информация о посте
По уму:
rel = relation(FEED, VIEWER);
return getMessage(FEED, ITEM, rel);
Мощность пространства ключей – N * C
Вдобавок rel можно повторно использовать в пределах одного вызова или даже закешировать.
23
Пример: блоки в анкете В лоб:
return getCategories(FEED, UID, category_list)
(нам нужны некоторые блоки, с учётом доступов)
Сложность: N * N * 2c
24
Пример: блоки в анкете По уму: rel = relation(FEED, VIEWER)
return [c for c in getCategories(FEED, rel) \
if c.name in category_list)]
Сложность: N, повторно используем rel из предыдущего примера.
25
СУБД vs кеш
Кеш
— Гибкая схема
— Гибкое управление ключами
— Самоочищается
— Глупый – значит, быстрый!
СУБД
— Не требует инвалидации
— Есть репликация
— Гарантирует наличие данных
— Джойны и сложные запросы
26
Инвалидация кеша — Всегда явная, по событию — Протухание по времени – только для
очистки кеша
— Не замусоривать невостребованными ключами
Пара слов о фронтэнде
27
28
Фронтэнд может помочь бэкэнду
Отделить мясное от молочного:
— OMG фреймы
— AJAX
— localStorage и т.д.
29
Кеширование статики
— Условное: If-‐Modified-‐Since, Etag
— Лишний запрос
— Нечёткая инвалидация
— Безусловное: Expires, Cache-‐Control — Без запроса
— Требует версионирования для инвалидации: css/v2.0/index.css или css/index.css?v=2.0
Руководитель группы сервисов общения
theigel@yandex-‐team.ru
@theigel
Сергей Чистович