#nodejs #кэширование #redis #highload
Планируется highload-проект с использованием NodeJS, MySQL, Redis, NGINX.
За основу взят nodejs фреймворк express, и для работы с сокетами (может это и не
хорошее решение) - socket.io. Проект представляет собой single page application, предполагается,
что сокет-соединение будет открыто повсеместно. Будет большое количество страниц, которые
являются статистично-информативными, и не щадят бд тяжелыми запросами.
Есть несколько вопросов о том, как построить кэширование данных, и где лучше применять
Redis, а где использовать другие способы.
Например, есть запрос к БД, его результат мы можем сохранить в Redis в виде JSON,
при следующих обращениях уже будем брать его из Redis и, когда необходимо - делать
инвалидацию данного кэша. - Насколько правильно это? И стоит ли именно в JSON хранить
данные?
Нам иногда нужна закэшированная страница не только в JSON, а кусок или целиком HTML.
- Правильно ли хранить эти куски в Redis?
Есть идея реализовать session-storage в Redis, как это сделать правильно? например
ключом будет id сессии, а значением - массив данных о клиенте. - Это правильно или
нет? Как будет лучше?
В каких случаях стоит записывать кэш в файлы на диск?
Стоит ли вообще пихать все что выше описано в redis?
Я не имею опыта в highload, поэтому мне интересно все, что вы скажете, очень нужны
грамотные советы в построении проекта на перечисленных компонентах. Может, есть какие-то
рекомендации по работе с сокетами в highload, либо еще что-то, что касается основ такого
проекта.
Признателен за ваши полезные советы, благодарю за внимание!
Ответы
Ответ 1
Например, есть запрос к БД, его результат мы можем сохранить в Redis в виде JSON,
при следующих обращениях уже будем брать его из Redis и, когда необходимо - делать
инвалидацию данного кэша. - Насколько правильно это?
На сто процентов, но своевременная инвалидация кэша - довольно большой челлендж.
И стоит ли именно в JSON хранить данные?
Вообще меня несколько коробит сохранять данные строкой, но особого выбора нет, и
вообще это не должно влиять ни на что.
Нам иногда нужна закэшированная страница не только в JSON, а кусок или целиком
HTML. - Правильно ли хранить эти куски в Redis?
Нет, у вас же SPA, весь рендеринг должен быть на клиенте.
Есть идея реализовать session-storage в Redis, как это сделать правильно? например
ключом будет id сессии, а значением - массив данных о клиенте. - Это правильно или
нет? Как будет лучше?
Если сессия у вас считается за постоянное хранилище, то неправильно, потому что Redis
не предназначен для постоянного хранения данных (хоть и умеет время от времени скидывать
данные на диск). Вместо этого лучше организовать двухуровневое (или даже трехуровневое)
хранилище из связки Redis - БД (In-Memory - Redis - БД в случае трехуровневой связки).
В каких случаях стоит записывать кэш в файлы на диск?
Как правило, ни в каких, есть база данных. Туда можно скидывать результаты тяжелых
запросов, чтобы все ноды их видели, но даже в этом случае я бы организовывал промежуточный
Redis-слой.
Стоит ли вообще пихать все что выше описано в redis?
Чем больше будет висеть в кэше, тем лучше, но время от времени посматривайте на количество
съедаемой оперативной памяти.
Может, есть какие-то рекомендации по работе с сокетами в highload, либо еще что-то,
что касается основ такого проекта.
Помните про две вещи
Проект обязан масштабироваться горизонтально, т.е. простым добавлением новых серверов.
Из этого вытекает, что изменения на одном сервере должны быть видны для всех остальных
(это достигается за счет использования одного Redis и БД)
Существует такая штука, как dogpile effect, который означает кучу пользователей,
одновременно запросивших один и тот же ресурс. В случае с вышеописанным трехуровневым
хранилищем сто синхронно пришедших пользователей не обнаружат запись в кэше и ломанутся
(все сто) к БД. В случае, если в БД 20 одновременных подключений, и каждый запрос занимает
30мс, то последний пользователь получит данные не раньше, чем через 150мс (это в идеальном
случае, на самом деле там будет значительно большее число), что очень нехорошо.