Пакет sync/singleflight в Go: устранение дублирования идентичных запросов

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

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

К счастью удалось найти решение в виде пакета singleflight (ссылка на оф документацию), предоставляющего механизм подавления повторяющихся вызовов.

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

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

Дабы не повторяться, тут оставлю ссылку на свой перевод: habr.com/ru/post/677444/

Рейтинг

Возврат к списку

Раздел Go
(Codeblog)