Когда ООМ убил memcached
Ситуация: на сайте есть несколько блоков данных, которые подгружаются с других сайтов и затем некоторое время хранятся в memcached. Это позволяет реже обращаться к другим сайтам и тем самым быстро выдавать страницы. Но в понедельник всё пошло не так, как было задумано.
Есть такая техника хранения данных в кэше, которая называется «Ленивый кэш» (Lazy Cache).
Схема такая:
- Когда нужна информация, проверить наличие её в кэше
- Если в кэше этой информации нет, то запросить из источника данных, затем сохранить информацию в кэш
- Далее вернуть данные из кэша
Схема позволяет при наличии данных в кэше работать очень быстро. При этом в кэше хранятся только реально необходимые данные.
В чём минус этой схемы? Если данных в кэше нет, то их надо получить из внешнего источника. И если на сайте используется блок, содержимое которого зависит от этого кэша, страница не будет выдана пользователю, пока источник данных не ответит. Если источник данных медленный, то и сам сайт тоже в этот момент начинает работать медленно. Если в этот момент несколько пользователей одновременно запрашивают страницу, содержащую такой блок, то все они «зависают», при этом он занимает память. При определённом количестве посетителей память сервера закончится.
Вот это и случилось в понедельник. Количество обращений на сайт превысило ожидаемое и память закончилась. OOM Killer решил освободить память и убил один из процессов, которые ему не нравились. Ему не понравился процесс memcached, который был запущен уже 90 дней и почему-то потреблял 8G памяти.
В итоге в цепочке Lazy Cache звено «если в кэше нет данных — запросить источник» стало самым слабым. Для генерации ответа каждому посетителю отправлялся запрос на сайт источника данных и в результате этот сайт тоже не выдержал нагрузки и упал.
Я знаю как минимум четыре способа решения этой проблемы. Сейчас эта проблема решена и я считаю решение очень надёжным. А как бы решил ты? Давай сверим наши решения.
Технические сведения:
- сайт-источник (донор информации) — блог на WordPress
- мой сайт (акцептор информации) — портал Icons8 на фреймворке Yii 1.x.
- у меня на сервере есть PHP 5.6, MySQL 5.5, memcached, MongoDB, Redis