Я пытаюсь сократить время, которое приложение тратит на вычисления одного и того же снова и снова ... Это звучит как сценарий использования кэширования, но вместо этого может потребоваться изменение архитектуры.
Ситуацияэто так: есть много звонящих, которые независимо друг от друга подают почти идентичные запросы в мой микро-сервис.Это происходит в течение некоторого времени (того же порядка, что и время, необходимое для обслуживания одного из этих запросов), затем все они переходят к новому набору почти идентичных запросов.
Я хотел бы попытатьсявычислять каждый уникальный запрос только один раз, насколько это возможно.
В определенный момент времени я получу несколько запросов для вычисления каждого из
{A, T0}
, {B, T0}
, {C, T0}
, {A, B, T0}
, {B, C, T0}
и т. Д.
Затем мои абоненты переключаются на {A, T1}
, {B, T1}
и т. Д.
Пока я вычисляю результат для {A, T0}
запрос на один узел, кластер получит несколько других запросов на тот же {A, T0}
запрос.Даже после того, как я закончу вычислять результат, но до того, как абоненты перейдут на T1, я все равно получу {A, T0}
запросов.
Кроме того, запрос {A, B, T0}
можно разбить на {A, T0}
и {B, T0}
запрос плюс простое объединение.
После того, как отдельный запрос вычислен, должно быть довольно легко кэшировать этот результат и обслуживать его для последующих запросов.Просто большинство дублирующих запросов поступает во время вычисления первого запроса ...
Существует ли какая-либо форма кэширования на уровне запросов, которая может облегчить эту ситуацию?
Звучит ли этонемного похоже на попытку сделать POSTs идемпотентными, что может быть невыполнимым.
Набор возможных «букв», указанных выше A
, B
и C
, известен, но большой.Подмножество «букв», которые формируют запросы, могут немного измениться (например, в какой-то момент может быть запрос {A, C, D, T2}
).
Есть ли лучший архитектурный подход к этой проблеме?Просто добавив больше оборудования, это будет работать, но, кажется, расточительно.
РЕДАКТИРОВАТЬ:
Один из подходов, который я рассматриваю, заключается в следующем:
- "похожие" запросы получаютнаправляется на тот же узел.Например, все
{A, T0}
запросов отправляются на узел 12 - локально, на каждом узле у меня есть (LRU) кэш от
Request
до Future<Response>
- , любой запрос либо прослушивает существующий
Future
или регистрирует и выполняет новый - , если узел выйдет из строя, все «похожие» запросы будут назначены другому узлу, и запрос будет обработан снова
Гдеэто становится сложным, имея дело с {A, B, T0}
запросами.Они разбиваются на более мелкие запросы, каждый из которых может обрабатываться разными узлами.