Примерно так:
Проходит время, нагрузка растёт и узким местом становится база данных. Разработчики, стараясь снять с неё нагрузку, переходят к асинхронной схеме. Тут база данных не используется в каждом запросе. В основном используется только быстрое noSQL-хранилище или специализированный сервер очередей, для передачи заданий пулу обработчиков. Основную работу эти обработчики выполнят уже позже, когда довольный клиент получит быстрый ответ и пойдёт заниматься своими делами:
Но нагрузка может расти и дальше. Оставим в стороне "горизонтальное" масштабирование при котором мы строим кластера и плодим инстансы приложений - речь сейчас не об этом. Что в последней схеме становится узким местом? База данных уже не в счёт: спрятанная за слоем очередей и обработчиков, кэшей и буферов, она может чувствовать себя спокойно. Обработчики великолепно масштабируются, ведь они "висят" на безразмерной шине очереди. Nginx - один из самых высопроизводительных серверов, за него не беспокоимся. noSQL-хранилища тоже как правило замечтально держат нагрузку и масштабируются.
Что остаётся? К сожалению "крайним" остаётся наше web-приложение. Это оно разбирает запрос, авторизует его, создаёт обьекты, манипулирует с ними, сериализует в базу или в очередь. А потом ещё вычитать данные, сериализовать для ответа... Приложение может содержать неэффективный код, плохо масштабироваться... Кстати, а зачем нам оно вообще нужно? Давайте уберём его из схемы:
Как же так? Очень просто. Задача получить данные из запроса и уложить в очередь вообще-то тривиальная. И обратная задача тоже. Зачем программировать тривиальные вещи? Всё уж сделано за нас :)
Nginx при помощи HttpRedis2Module может уложить в noSQL-хранилище Redis любые параметры из запроса в виде такого набора ключ-значение, который нам нужен. И вычитать нужный нам набор ключей для возврата клиенту. Вы не используете параметры запросов? У вас обмен с клиентской частью в формате JSON? Нет проблем! Используя set-misc-nginx-module мы можем прямо в конфиге nginx-а описать правила получения данных из запроса: UrlDecode, JSONDecode, Base64Decode и т.п.
Теперь посмотрим, как настроить такое "сверхтонкое" web-приложение:
Первым делом установим Redis:
$ wget http://redis.googlecode.com/files/redis-2.4.2.tar.gz
$ tar xzf redis-2.4.2.tar.gz
$ cd redis-2.4.2
$ make
Из директории src можем запустить redis сервер (redis-server) и клиент (redis-cli).
О конфигурировании redis можно подробнее прочитать в документации. Нам пока нужно знать только порт на котором слушает redis. По умолчанию это 6379.
Теперь нужно собрать Nginx. Именно собрать из исходников, ведь нам нужно включить в него сторонние модули.
$ wget 'http://nginx.org/download/nginx-1.1.7.tar.gz' $ tar -xzvf nginx-1.1.7.tar.gz $ cd nginx-1.1.7/ $ ./configure --prefix=/opt/nginx \ --add-module=/path/to/redis2-nginx-module \
--add-module=/path/to/ngx-devel-kit-module \
--add-module=/path/to/set-misc-nginx-module $ make -j2 $ make install
Тут при конфигуривании nginx мы включаем 3 модуля: первый для работы с Redis (redis2-nginx-module), третий для парсинга и преобразования данных запроса (set-misc-nginx-module), второй - ngx_devel_kit нужен для работы третьего.
Как видно из первого параметра команды configure, nginx установится в /opt/nginx. В /opt/nginx/conf/nginx.conf в блок конфигурации http-сервера по умолчанию добавим несколько директив, так чтобы он выглядел следующим образом:
- server {
- listen 80;
- server_name localhost;
- location / {
- root html;
- index index.html index.htm;
- }
- location /get {
- set_unescape_uri $key $arg_key;
- redis2_query get $key;
- redis2_pass 127.0.0.1:6379;
- }
- location /set {
- set_unescape_uri $key $arg_key;
- set_unescape_uri $val $arg_val;
- redis2_query set $key $val;
- redis2_pass 127.0.0.1:6379;
- }
- location /addhello {
- redis2_query set hello world;
- redis2_query get hello;
- redis2_pass 127.0.0.1:6379;
- }
- }
В строках 13-18 описана обратная операция: запись в Redis значения определённого GET-параметром "val" с ключом, имя которого определено GET-параметром "key".
Можем реализовать и цепочку запросов: например в ресурсе /addhello (строки 19-23) мы укладываем в Redis значение и вычитываем его для ответа.
Сохраняем изменённый конфиг, шлём запросы c параметрами на http://localhost и выбираем из Redis-а данные запросов.
Вообще, Nginx весьма гибкий инструмент. Расширяя его модулями и конфигурируя, мы можем реализовать функционал достаточно сложного web-приложения без программирования. Программировать же нам остаётся только слой "обработчиков", которые общаются с клиентами (и друг с другом, если нужно) через Redis. Именно там мы реализуем бизнес-логику не беспокоясь больше о нагрузке.
Интересно, но на сколько гибким могут быть сторонние модули?
ОтветитьУдалитьМне недавно пришла идея реализовать бизнес логику как модуль для nginx в качестве базы всё тот же redis, посмотрим на сколько получится производительное решение.
Глупая идея, если тяжелая бизнесс логика - может упасть nginx. Не забывай, что nginx асинхронный однопоточный процесс (их можно запустить несколько). По этому, если один из HTTP запросов зависнит внутри nginx, то будут висеть и другие процессы.
УдалитьСуть nginx в том, чтоб быстро принять HTTP запрос и перебросить его на backend, потом обработать следующий запрос, еще, и еще..., пока baсkend думает над ответом, о потом отдать ответ.
Принципиально это возможно, если разбить проект на части (микросервисы) и часть легкой Логики реальизовать через lua модуль.
Видимо, вы невнимательно читали пост, раз не поняли основоной мысли. Цель связки nginx + redis как раз в том, чтобы исключить ситуацию, когда nginx-у приходится "ждать" пока исполняется бизнес-логика. Его задача - уложить или достать значения из redis. Бизнес-логика начинается потом, когда ответ клиенту уже отправлен.
УдалитьЭто требует модификации логики фронтенда, он должен уметь реагировать на сигнал бекэнда "зайти позже", но получаемые взамен преимущества того стоят.
Появилась неплохая альтернатива - webdis
ОтветитьУдалитькак передать пароль в redis? redis запароленый
ОтветитьУдалитьДобрый день. Мы занимаемся разработкой программы FastoRedis. FastoRedis - это кроссплатформенный GUI-менеджер для баз данных Redis, Memcached, SSDB. Возможно, наша программа будет полезна для ваших разработчиков. Если Вы используете FastoRedis или планируете использовать, мы будем очень благодарны если в ответном письме Вы напишите нам Ваше мнение, замечания, предложения.
ОтветитьУдалитьТак же будем благодарны за помощь в разрешении спорного вопроса. А именно ->
В первых версиях FastoRedis была возможность работать в консоле lua и python
http://fastoredis.com/whats-new_060.html
http://fastoredis.com/whats-new_045.html
Счас это функционал убрали - есть мнение что это лишнее и совсем не нужно для работы с Redis, Memcached, SSDB.
Если не трудно, сообщите пожалуйста мнение Ваших разработчиков по этому вопросу(возможно был бы полезен еще какой нибудь функционал).
В дальнейшем планируем развивать функционал программы основываясь на замечаниях и предложениях пользователей.
С уважением, разработчики FastoRedis.
Сайт - http://fastoredis.com
E-mail - atopilski@fastoredis.com