Здравствуйте.
Теоретическая модель такая. Есть простой сайт - соц. сеть. На сайте есть два вида страниц: которые постоянны, статические и с динамическим содержимым. Статические: данные забираются из БД из нормализованных таблиц разными JOIN'ами. Динамические: с различными блоками информации, например, отображение друзей текущего пользователя. Сайтом пользуется громадное количество людей. Нужно использовать memcached (это просто модель для изоляции сути вопроса). Описаний работы самого memcached в сети хватает, а вот про стратегии кеширования, к сожалению, ничего подходящего не нашел.
Memcached - это простое хранилище ключ => значение. Т.е., насколько я понимаю, наиболее распространенным бутылочным горлышком в производительности бывают запросы к БД. Т.е., чтобы увеличить производительность в этом аспекте, необходимо минимизировать количество запросов к БД (а они могут быть сложные и тяжелые, особенно в случае с нормализованными таблицами). Тут memcached выступает посредником между базой данных и веб-приложением. Если говорить про статические страницы в описанной выше модели сайта, то можно их выделить в отдельную сущность-таблицу "статические страницы" и сделать поле edited_at для страниц и, сравнивая значение этого поля с датой добавления данных в кеш, выводить содержимое страницы либо из кеша, либо собирать запросами из БД (по принципу создания простого файлового кеша).
А теперь другие конкретные и уже не самые очевидные в плане реализации варианты.
1) Страницы-каталоги (что-то, что отображается постранично и часто меняется: новости, списки, каталоги товаров, хоть это и не относится к теме, и пр.). Конкретно, пусть это будет очень часто обновляемая страница новостей.
2) Страницы с, условно говоря, виджетами, т.е. какими-то небольшими блоками информации, которые при каждой их загрузке могут иметь отличное от предыдущего содержимое. Например, список друзей пользователя. Если говорить конкретно, то пусть вторым вариантом будет он.
Как лучше реализовывать кеширование в этих двух случаях? Ну, и чтобы с чего-то начать, привожу свои мысли.
1. В данном случае целая страница не может быть объектом кеширования, тем, что я могу положить в значение той самой пары (ключ => значение). Т.к., в зависимости от количества новостей, содержимое страницы может меняться и новости могут "сдвигаться". Нужно "сужать" масштаб объекта кеширования. Новости - это отдельная сущность. То, как они группируются на странице, не имеет значения. Значит объектом кеширования может быть новость, которая в основной таблице может иметь поле edited_at, которое может изменяться каждый раз при изменении данной таблицы или связанных с ней таблиц. Каждый первый раз, когда новость забирается запросами (пусть это тоже будут сложные JOIN-запросы, чтобы появилось больше смысла) из БД, она ложится в кеш. А далее, при выводе каждой новости сравнивалось время помещения в кеш и время изменения и выводилась бы самая свежая новость. Все ничего, но, кажется, есть проблемы. Во-первых, если связей у таблицы много, в т.ч. и многие-ко-многим, то может быть заморочкой слежение за полем edited_at в главной таблице. Во-вторых, в цикле при выводе каждой новости, будет происходить проверка (сравнения времени данных в кеше и в бд, то, о чем выше написано) актуальности данных, а это - тоже время. Не сведут ли на нет эти временные затраты саму идею использования кеша таким образом?
2. Список друзей. Отображается у каждого пользователя. Запросов там может быть много (и получение самого списка, информации по каждому, картинки). И этот список запросов может повторяться для каждой открытой страницы у каждого пользователя. Получается серьезное узкое место в производительности. Мои мысли таковы. Каждый блок такой информации условно определять как виджет. У каждого такого виджета создается своя сущность-таблица и для каждого же виджета созается поле edited_at. И... та же самая схема, что и выше. Свежачок в memcached - забираю оттуда. Нет - стираю запись в кеше, забираю из базы, пишу в кеш. Но опять ловлю себя на мысли, что что-то тут не так. Ладно виджет, а как быть со странице друзей, на которой отображаются уже постранично еще большее количество друзей, каждый из которых волокет за собой "кучку" запросов?
Это на самом деле простым ответом не обойдётся... Тут вопрос на серию статей... Могу проконсультировать по скайпу в режиме голоса. Но при условии что вы напишите потом статью))
Да, двумя предложениями не обойтись. Наверное, формат вопроса не соответствует формату ресурса...Со статьей - не проблема. Информацию проще усваивать, если после этого пересказать. Вот только со скайпом беда. После одной из последних уборок bluetooth-гарнитура пропала. Но, если согласны поделиться информацией, то можно добавиться, а там видно будет...
Всю механику двумя предложениями действительно не решить, но есть одно предложение, от которого необходимо плясать. Если нужна высоконагруженная система с динамическими данными - забудьте про модель "если нет в кеше - обратились в базу, закешировали, отдали пользователю". Пользовательские запросы должны проходить только по двум каналам - максимально быстро отдавать статику (Varnish) и все остальное максимально быстро отдавать из Memcached. А обновления кешей должно идти от бекенда. Изменились данные в базе - принудительно сбросили кеш по этому ключу. То есть, с другой стороны заходим.