Как использовать Zend_cache с memcached распределенным способом? - PullRequest
1 голос
/ 06 июля 2011

Название этого вопроса может сбивать с толку, но проблема проста.

Я использую Zend_Cache с memcached в качестве бэкэнда.У меня есть два модуля под названием «Последние статьи» и «Популярные статьи».Оба эти модуля находятся на каждой странице и используют похожий запрос, например:

Select * from table where status = 'published' and category = '' order by dateCreated|/popularity\

Моя таблица пока имеет 1,5 миллиона строк.У меня есть индексы для каждого поля, которое я использую в предыдущем запросе.Я кеширую последние статьи за 1 час и популярные за 4 часа.У меня есть 4 веб-сервера (php5 / apache2) и 1 сервер базы данных (mysql).Ядром таблицы является innoDB.

Проблема, когда мой кэш истекает прямо в середине большой нагрузки, из-за чего мой веб-сайт становится недоступным до тех пор, пока эти модули не будут снова кэшированы.У меня мог бы быть новый сервер MYSQL.

Но есть ли способ сделать кеширование более разумным способом?Как, например, server1 будет пытаться обновить кэш, в то время как серверы 2,3 и 4 будут по-прежнему использовать одно и то же значение из кэша.

Я могу написать некоторый код для этого, но мне было интересно, есть лиэто способ сделать это напрямую с Zend_Cache?Если есть шаблон проектирования, который я мог бы применить к моей проблеме?

[ПРАВИТЬ] Я хочу что-то, что я мог бы масштабировать до 100 серверов

Ответы [ 4 ]

1 голос
/ 06 июля 2011

все возможно:)

распределенный memcache (serv1,2,3,4).

использовать serv4 только для ReCache.

настроить веб-сайт «только для внутреннего использования» (недоступен пользователям).

лишить часть, которая "обновит некоторые категории".

чтобы получить "самые читаемые статьи" -> разобрать логи доступа apache.

и повторно отправьте URL на сервер4.

время доступа есть, поэтому вы можете получить только необходимую часть, то есть от 2 до 6 часов назад.

распределенный memcache автоматически заполнит его значения до serv1,2,3.

1 голос
/ 06 июля 2011

Это фактический запрос, который вы выполняете?

Select * from table where status = 'published' and category = '' order by dateCreated|/popularity\

Возможно, вместо поиска расширенных решений для кэширования, посмотрите, почему этот запрос подвергает нагрузке ваш сервер базы данных.Стол с 1,5-метровыми рядами не является чем-то необычным.

Вы пытались добавить предложение LIMIT или выбрали только те столбцы, которые вам нужны:

Select col1, col2 from table where status = 'published' and category = '' order by dateCreated LIMIT 5

Это значительно сократит трафик между базой данных и веб-серверами.

1 голос
/ 06 июля 2011

Вместо того, чтобы полагаться на истечение срока действия кэша, а затем на повторное заполнение во время HTTP-запроса (или, что более проблемно, во время нескольких одновременных запросов), почему бы никогда не истечь срок действия кэша?

Затем запланируйте некоторый сценарий пока, чтобы выполнить ваши дорогие запросы (только один раз!) И обновить кэш в фоновом режиме.

0 голосов
/ 12 июля 2011

Я наконец-то реализовал класс, унаследованный от Zend_Cache_Backend_Libmemcached Я переопределяю метод load ().

У каждого моего сервера есть имя хоста, заканчивающееся набором номеров, таких как serv01, serv02, serv03, serv04. Основная идея заключается в том, что каждый сервер будет думать, что срок действия кэша истек в разное время. Например, serv01 будет считать, что срок действия кэша истек за 20 минут до истечения срока его действия, а serv02 - 15 минут, serv03 - 10 минут, а serv04 - 5 минут.

Таким образом, мой кэш никогда не будет обновляться одновременно на каждом сервере, и если один сервер не работает, кэш будет обновляться другим сервером.

...