Параллельные запросы к СУБД во время отсутствия кэша записи — какой алгоритм?

Не могу найти информацию по этой теме, нашел лишь одну статью:
Если есть запрос, который выполняется 10 секунд, ttl для его кэша 1 час.

Когда проходит это время, данные в кэше удаляются.

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

Чтобы этого избежать, необходимо использовать специальную методику дублирования. Для каждого тяжелого запроса создается не один, а два ключа — ttl и ttl +10 sec.

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

Первое. Кэш может быть удален самим memcached по истечению времени и вышеописанный алгоритм просто "некому" применять.
Второе. Я из клиентского кода не занимаюсь удалением данных кэша, это всё возложено на memcache, на expire значение элемента данных и не знаю, когда данные из кэша будут удалены. Предполагаю, что тут идёт речь о том, что под "удалением данных" инициируется некий CRUD данных, т.е. CRUD должен инициировать вышеописанный процесс.

Но делать этого не хочется на уровне CRUD-а, т.е. не хочется, что бы кэш менялся по данному событию, в идеале - просто по установленному expire значению.

Как сделать правильно?
  • Вопрос задан
  • 327 просмотров
Решения вопроса 1
@rPman
Проблема не в кеше и его экспирации, проблема именно в генерации контента, когда данных в кеше нет либо когда требуется его перегенерация при изменениях данных.

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

Вариант реализации - метод, в котором генерируется контент, используя in memory key-value базу данных (наверное лучше не memcached, так как оно не гарантирует сохранность данных, хотя если администрировать с оглядкой на это, почему нет, можно предложить складывать в memcache определенное значение перед стартом генерации, и проверять именно на него), отмечает начало и конец этого процесса, со ссылкой на идентификатор этих данных (страница сайта например), т.е. запись появляется только на время генерации данных, и при наличии записи тормозит процесс.

Логично было бы не делать случайный sleep для этого, а ждать ивент от соседнего процесса, в идеале средствами этой базы данных
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы