Стратегия кэширования, извлекающая как отдельную, так и коллекцию записей из базы данных - PullRequest
0 голосов
/ 25 октября 2018

Для проекта, над которым я сейчас работаю, я бы хотел кэшировать большинство данных, поступающих из базы данных.Для краткости я воспользуюсь примером простого блога здесь и оставлю такие вещи, как нумерация страниц.

Пример: у меня есть блог с постами и категориями.Сообщение может быть назначено одной или нескольким категориям.Категории, разумеется, будут существовать из набора сообщений.


Я разработал следующие две стратегии кэширования:

Стратегия 1

Используя эту стратегию, я буду кэшировать все выходные данные, которые возвращает мой репозиторий.Это означает, что метод find($id) для сообщений вернет один пост (из кэша, если он доступен, если не создан в кэше) Метод getByCategory($category) вернет все сообщения для определенной категории.Список будет поступать из кэша, если он доступен, и если нет, извлеченный список будет помещен в кэш для последующих запросов.

Стратегия 2

Эта стратегия немного отличается,Он также будет кэшировать весь вывод, возвращаемый моим репозиторием, но фактическое сообщение only , возвращенное методом find($id).Все остальные методы репозитория (представляющие списки / коллекции сообщений) будут только возвращать идентификаторы сообщений.Затем эти методы будут зацикливать все идентификаторы и использовать метод find($id) для извлечения фактического сообщения и возврата массива всех сообщений для этих идентификаторов.


Я бы сказал, что стратегия 2 имеет много преимуществ по сравнению со стратегией 1.Прежде всего, пост хранится в кеше только один раз, потому что кеши, представляющие списки, сами не содержат пост (только неизменяемый идентификатор поста). Это экономит место (особенно полезно с кэш-памятью в памяти).механизмы, такие как Redis) Кроме того, когда сообщение обновляется, мне нужно только обновить (аннулировать / повторно заполнить) кэш для этого отдельного сообщения.Все списки будут автоматически содержать обновленную запись, поскольку они имеют только идентификатор, и на основании этого идентификатора запись запрашивается отдельно.Наконец, я смогу разбивать на страницы результаты, просто разрезая массив идентификаторов вместо построения запросов (с OFFSET / `` LIMIT```` и т. Д.), Которые позволяют разбивать результаты на страницы.

Единственноереальный недостаток я вижу это первый запрос.При запуске с пустым кешем и запросе списка, скажем, для 10 самых последних сообщений, первый 1 запрос необходим для определения того, какие 10 идентификаторов представляют записи в этом списке.Затем для всех 10 идентификаторов фактическое сообщение запрашивается из базы данных, в результате чего в общей сложности 11 запросов.При стратегии 1 мне понадобится только 1 запрос (выберите 10 записей, упорядоченных по дате). Конечно, для последующих запросов все данные поступают из кэша, что означает 0 запросов в обоих случаях, поэтому я не рассматриваю это какдело-прерыватель.Другим (небольшим) недостатком может быть то, что стратегии 2 требуется больше запросов в кэш (11 по сравнению с 1 для стратегии 1), но я понятия не имею, смогу ли я вообще заметить такую ​​вещь с механизмами кэширования в памяти, такими как Redis (или даже с файловым кешированием на быстрых SSD-дисках)

Мне интересно ваше мнение и возможные альтернативы, о которых я не думал.

Приветствия!

...