Как управлять повторными запросами на кэшированном сервере во время получения результата - PullRequest
1 голос
/ 01 ноября 2019

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

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

Рассмотрим следующую фигуру, извлеченную из здесь Example caching a book Я использую эту цифру, потому что я думаю, что она помогает мне проиллюстрировать проблему. На рисунке рассматриваются два основных случая: книга находится в кеше или нет в этом. Однако на рисунке не учитывается случайный случай, когда книга извлекается из базы данных и других «get-same-book»запросы приходят. В этом случае я бы хотел временно поставить в очередь повторные запросы, пока книга не будет извлечена. Затем, как только книга уже поступила, на поставленные в очередь запросы отвечают с результатом, который останется в кэше для быстрого получения будущих запросов.

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

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

1 Ответ

0 голосов
/ 01 ноября 2019

Вы можете создать его так, как вы описали. Но есть некоторые важные вещи.

Используйте уникальный ключ

Используйте уникальный ключ для каждой книги и если книга когда-либо изменяется, этот ключ также должен измениться. Этот дизайн заставляет ваш шаг (6) сохранить книгу в Redis и идемпотентную операцию (вы можете делать это много раз с одним и тем же результатом). Таким образом, вы избежите любого состояния гонки с "get-same-book".

Идемпотентные запросы ИЛИ асинхронные сообщения

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

Я бы не рекомендовал запросов очереди , как вы ее описали. Если запрос является пропуском кеша, позвольте ему извлечь его из базы данных - но спроектируйте его идемпотент . В качестве альтернативы вы должны обработать все запросы как асинхронные и использовать очередь сообщений, например, nats , RabbitMQ или что-то еще, но сложность возрастает с этим решением.

Сериализация запросов

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

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

Redis поддерживает PubSub , но это зависит от того, какие требования у вас есть к клиентам. Я бы порекомендовал решение без блокировок, для масштабируемости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...