Стратегия разбиения на страницы Redis для бесконечной прокрутки страницы

TL; DR: какой из трех вариантов ниже наиболее эффективен для разбивки на страницы с помощью Redis?

Я реализую веб-сайт с несколькими сгенерированными пользователями публикациями, которые сохраняются в реляционной БД, а затем копируются в Redis в виде хэшей с ключами, такими как site:{site_id}:post:{post_id}.

Я хочу выполнить простые запросы разбиения на страницы к Redis, чтобы реализовать разбиение на страницы с отложенной загрузкой (то есть, когда пользователь прокручивает страницу вниз, мы отправляем Ajax-запрос на сервер с запросом следующей группы сообщений) в интерфейсе в стиле Pinterest.

Затем я создал набор для отслеживания идентификаторов опубликованных постов с такими ключами, как site:{site_id}:posts. Я выбрал наборы, потому что я не хочу иметь дублированные идентификаторы в коллекции, и я могу быстро это сделать с помощью простого SADD (не нужно проверять, существует ли идентификатор) при каждом обновлении БД.

Ну, так как наборы не упорядочены, я обдумываю плюсы и минусы вариантов, которые мне нужно разбить на страницы:

1) Использование команды SSCAN для разбивки моих уже реализованных наборов

В этом случае я мог бы сохранить возвращенный курсор сканирования в сеансе пользователя, а затем отправить его обратно на сервер при следующем запросе (это не кажется надежным, когда несколько пользователей получают доступ к базе данных и обновляют ее: в какой-то момент курсор будет недействительным и возвращать странные результаты - если только нет некоторого предостережения, которое я пропускаю).

2) Рефакторинг моих наборов, чтобы использовать вместо них списки или отсортированные наборы

Тогда я мог бы разбить на страницы, используя LRANGE или ZRANGE. Список, кажется, самый производительный и естественный вариант для моего случая использования. Он идеально подходит для разбивки на страницы и упорядочения по дате, но я просто не могу проверить существование одного элемента, не зациклив весь список. Сортированные наборы, кажется, объединяют преимущества как наборов, так и списков, но потребляют больше ресурсов сервера.

3) Продолжайте использовать обычные наборы и сохраняйте номер страницы как часть ключа

Это будет что-то вроде site:{site_id}:{page_number}:posts. Это был рекомендуемый способ до того, как команды сканирования были реализованы.

Итак, вопрос в том, какой подход наиболее эффективен/прост? Есть ли другой рекомендуемый вариант, не указанный здесь?

Ответ 1

"Бест" лучше обслуживать субъективно :)

Я рекомендую вам использовать второй подход, но обязательно используйте Sorted Sets over Lists. Мало того, что имеет смысл для этого типа работы (см. ZRANGE), они также более эффективны с точки зрения сложности по сравнению с LRANGE -ing a List.