2013-11-12 2 views
2

Я пытаюсь понять, какая из них будет лучшей стратегией кэша в случае слоя REST API, который позволяет запрашивать и обновлять базу данных реестра клиентов. В настоящее время у нас есть 3 фронтовых сервера, которые говорят с центральным сервером базы данных.Согласованность с etags и настройкой нескольких серверов?

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

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

Если второй клиент прибыл и выполнил одно и то же GET для той же самой записи клиента, направляемой на сервер 2, сервер 2 также будет кэшировать запись локально и вернуть тот же заголовок etag.

Предположим, что теперь первый клиент выполнил вызов обновления с той же записью через сервер 1. Кэш сервера 1 обновляется с последней информацией о записи, и первый клиент получает новый etag.

После этого второй клиент выполняет условный вызов get, предоставляющий заголовок «If-None-Match» с принятым этагом. Запрос снова ударит по серверу 2. Мое предположение состоит в том, что сервер 2 все еще будет кэшировать старый etag и вернет 304 Not Notified ответ клиенту. Это правильное предположение?

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

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

Большое спасибо!

ответ

2

Кэш-недействительность - это решение hard problem. Есть, по крайней мере, 3 пути, которые я видел, чтобы решить это. Они различаются по сложности и по тому, как долго срок действия истекшей записи по-прежнему считается действительным.

  1. Самый простой ответ в том, что все внешние серверы должны вызвать базу данных, чтобы проверить ETag до возвращения «304 Not Modified». Это может быть лучше, если есть много обновлений или стоимость загрузки записи из базы данных высока.

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

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

+0

вы можете прокомментировать мой ответ. :)) –

1

+ один более подходит @ список Дэвида:

  1. Используйте централизованный кэш. Он должен решить вашу проблему. Несмотря на то, что он менее эффективен, чем локальное кэширование, он все же быстрее, чем запрос к базе данных в большинстве случаев.

Возможные реализации кластерной кэша являются: couchbase, Redis кластера. Самая популярная некластеризованная реализация - memcached.

0

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

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

Смежные вопросы