Оптимистичный шаблон проектирования параллельного кэширования - PullRequest
10 голосов
/ 21 февраля 2012

У меня есть веб-сервис, работающий на кластере серверов. Этот веб-сервис выполняет некоторую внутреннюю обработку, а затем может вызвать внешний сервис, за который взимается плата.

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

Однако я пытаюсь понять, как управлять этим кэшированием, когда у меня есть следующие ограничения

  • Служба работает на нескольких веб-серверах для обеспечения высокой доступности и масштабируемости
  • Для ответа на запрос может потребоваться до 5 секунд, но в то же время я мог получить 2 или 3 других идентичных запроса.

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

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

Ответы [ 2 ]

6 голосов
/ 21 февраля 2012

Вы могли бы

  1. вычислить криптографический хеш запроса
  2. посмотреть, есть ли результат в базе данных для этого хэша, и если да, вернуть его
  3. сохранить хэш в базе данных со статусом "ожидающий результат"
  4. вызвать веб-сервис и обновить строку в базе данных с результатом.

На шаге 2, если хэш уже находится в базе данных со статусом «ожидающий результат», вы можете опрашивать базу данных каждые X миллисекунд и, наконец, возвращать результат, как только он там будет.

Дьявол кроется в деталях, конечно, потому что вам придется решить, что вы будете делать в случае ошибки:

  • возвращаете ли вы ошибку для всех последующих идентичных запросов?
  • Вы заставляете ожидающие потоки повторять вызов веб-службы?
  • вы возвращаете ошибку, но только в течение некоторого времени, а затем повторите попытку?
2 голосов
/ 21 февраля 2012

1.) Служба работает на нескольких веб-серверах для обеспечения высокой доступности. и масштабируемость

Относитесь к этому просто как к конструктивному ограничению. Это означает, что не включайте имя хоста в ваш метод поиска в кэше. Пока результат не зависит от хоста, у вас не должно быть проблем. Я бы посчитал недостатком дизайна, если hostA возвращает что-то отличное от hostB в среде высокой доступности с той же службой и теми же параметрами.

Если вы хотите сохранить избыточность системы, у вас не должно быть центрального кэша. Потому что в большинстве случаев «центральное» решение является синонимом «единой точки отказа» - решения. Блокировка также более сложна, если вы синхронизируете серверы приложений.

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

2.) Для ответа на запрос может потребоваться до 5 секунд, но в то же время Возможно, я получил 2 или 3 других идентичных запроса.

Это также ограничение дизайна. Вы разделяете кеширование просто на 2 разных шага.

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

Вы также должны обрабатывать обработку исключений.

Механизм locking и connection может быть реализован с разными стратегиями

  • Синхронный - вы просто делаете Mutex / Семафор или что-то еще и блокируете доступ к критическому разделу. Который мог бы в конечном итоге иметь несколько запросов в состоянии ожидания, пока блокировка не исчезнет
  • Асинхронный - вы реализуете некоторый механизм опроса, который приводит к сообщению о том, что данные не готовы, если поток встречает заблокированную критическую секцию (как при синхронной обработке). Это не приведет ко многим открытым соединениям, но усложнит процесс.

Mutex / Семафор или любая другая структура, которую вы используете для блокировки доступа к критическому разделу , может зависеть от уникального ключа (если вы не хотите сериализовать доступ к вашему сервису), который вы рассчитали для идентичный запрос.

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