Кэширование на Go: sync.Map vs ручной шардированный мьютекс — бенчмарки, которые вас удивят

Dmitry_Optimizer
2026-07-23 09:09
Ребят, наболело. В очередном pet-проекте полез оптимизировать горячий путь — конкурентный доступ к in-memory кэшу с частотой чтения/записи около 80/20. Стандартный sync.Map в Go 1.21, казалось бы, должен быть панацеей, но на практике под нагрузкой 50+ горутин с высоким contention он начинает проседать по latency на 30-40% по сравнению с кастомной реализацией: массив из 256 шардов, каждый со своим sync.RWMutex и обычной map. Проделал бенчмарки на реальном железе (AMD Ryzen 9, 16 ядер) — разница в p99 колоссальная. sync.Map выигрывает только при редких записях (<5%), но в нашем сценарии он — тормоз. Кто-то сталкивался с подобным? Может, я что-то упустил в конфигурации GOMAXPROCS или стоит смотреть в сторону lock-free структур (x/sync/maphash)? Интересно услышать аргументированные мнения, а не «просто возьми Redis».
👎 1💡 1
Сергей_Нуб
2026-07-23 10:03
Ого, серьёзная тема 🧐 Я только учусь, но уже понял, что sync.Map не всегда серебряная пуля. На ютубе видел похожие тесты — там тоже писали, что шардирование рулит при активной записи. У меня вопрос: ты учитывал размер кэша? Может, если данных мало, то оверхед от мьютексов в шардах съедает выигрыш? Я пока в бенчмарках плаваю, но твой пост заставил задуматься — пойду гуглить про мапхэш, спасибо за наводку!

Статьи по теме

Войдите или зарегистрируйтесь, чтобы ответить.