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

11

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

Скажем, в моем приложении кто-то хочет посмотреть последние 20 обсуждений (из 10000). Через базу данных будет отправлен запрос servletна выбор первых 20 записей из таблицы потоков обсуждений в формате XML / JSON. Если они затем хотят увидеть следующие 20, они переходят на следующую страницу результатов, и это запускает другой запрос на получение следующего лота (limit и offset = 20 и т. Д.).

Чтобы уменьшить нагрузку на сервер и ожидания клиентов, я бы хотел кешировать предыдущие страницы результатов. Однако у меня есть два вопроса:

  1. Таблица, в которой отображаются результаты, может быть упорядочена по нескольким атрибутам (т. Е. Дата создания потока, автор темы, дата последней публикации). Это означает, что утверждение типа «первые 20 результатов» не имеет смысла без контекста (то есть, по чему мы упорядочиваем). Как тогда интерфейс взаимодействует с тем, что он уже загрузил? Моей первой мыслью было использовать идентификаторы для каждого результата, но отправка их обратно на сервер при последующих запросах (и фильтрация результатов на их основе) будет так же трудоемкой, как отправка всех обратно вслепую. Как я могу это сделать?
  2. Что если атрибут ранее возвращенного результата (т. Е. Самая последняя дата публикации) изменился? Затем нам нужен способ проверки каждого результата, чтобы увидеть, был ли он изменен на стороне сервера с момента его подкачки. Как я могу это сделать?
goodsquishy
источник
Ваш пример немного грубоват. Если это только 100 потоков, вам лучше всего загрузить все 100 за один раз. Если вы тянете 20 из 10000, это другая история.
Дэн Пичельман,
@DanPichelman Извините, мне было немного неясно. Это было бы больше похоже на 10000.
goodsquishy
Отредактированный номер для наглядности.
goodsquishy
Это http? Если это так, почему бы просто не кешировать на основе URL? Есть все параметры в URL. Если это браузер, попробуйте использовать кеш браузера. Если это приложение, установите срок действия кэша. Android Volley работает довольно хорошо.
морозный

Ответы:

7

Кажется , что вам нужно , это оболочка для всех параметров , которые определяют страницу (скажем, pageNumber, pageSize, sortType, totalCountи т.д.) и использовать этот DataRequestобъект в качестве ключа для вашего механизма кэширования. С этого момента у вас есть несколько вариантов для обработки кэша:

  • Реализуйте некоторый механизм тайм-аута для обновления кэша (в зависимости от того, как часто данные изменяются).
  • Есть прослушиватель, который проверяет изменения базы данных и обновляет кэш на основе вышеуказанных параметров.
  • Если изменения выполняются одним и тем же процессом, вы всегда можете пометить кэш как устаревший при каждом изменении и установить этот флаг при запросе страницы.

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

Наконец, как упоминал @DanPichelman, он может быстро стать слишком сложным алгоритмом, который перевешивает преимущества, поэтому убедитесь, что выигрыш в производительности оправдывает сложность алгоритма.

rae1
источник
3

Я бы, наверное, справился с этим так:

  1. Относитесь к разным порядкам как к разным последовательностям. Не стоит дополнительной бухгалтерии отслеживать, что есть у каждого клиента (или отправлять его снова и снова).
  2. Всякий раз, когда пользовательские страницы отображаются сразу из кэша, одновременно отправляя GET на сервер, который содержит хэш или время последнего доступа. Сервер отправляет обратно полную страницу, только если что-то изменилось.
  3. Получать с сервера более одной страницы пользовательского интерфейса одновременно. Например, если ваш пользовательский интерфейс отображает 20 записей, запрос 60. Мне нужно проверить это, но я ожидаю, что наиболее эффективный размер возврата обычно будет больше, чем средний объем данных, отображаемых на одной странице. Это также делает интерфейс очень отзывчивым для некоторых разворотов страниц.
  4. Prefetch отдыхает, когда вы приближаетесь к границе. Это помогает сохранить это быстрое время загрузки из кэша.
Крис Питман
источник
2

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

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

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

Дэн Пичельман
источник
Спасибо за Ваш ответ. Я думал о хешировании, но не уверен, поможет ли это в сценарии переупорядочения (т. Е. Он недостаточно детализирован и работает только на странице, а не на результате). Я думаю, что ваш последний абзац - хороший момент, и я начинаю думать, что сложность любого возможного решения перевесит выигрыш в производительности.
goodsquishy