Глава 1. Приступая к Redis
Содержание
В данной главе мы рассмотрим следующие рецепты:
-
Выгрузку и установку Redis
-
Запуск и останов Redis
-
Подключение к Redis при помощи redis-cli
-
Получение информации сервера
-
Общее понимание Модели событий Redis
-
Общее понимание протокола Redis
Redis является очень популярной, основанной на работе в оперативной памяти, базы данных ключ- значение с малым весом. Строго говоря,
Redis является неким сервером структуры данных, в соответствии с Matt Stancliff
(@mattsta
), одним из наиболее важных основателей Redis (https://matt.sh/thinking-in-redis-part-one). Сам автор Redis, Salvatore
Sanfilippo (@Antirez
) вначале назвал её Redis, что является сокращением от
REmote DIctionary
Server, поскольку Redis естественным образом реализует различные виды
структур данных в оперативной памяти и предоставляет различные API для манипуляции этими структуруми данных. Более важно, что Redis
поддерживает обработку высокопроизводительных команд, архитектуры Высокой доступности/ масштабирования, а также свойства постоянства данных пока
запущена служба хранения данных.
При разработке систем с высокой согласованностью и низкой латентностью, использование Redis становится всё более и более широко распространённым. В 2017 Redis попала в полный рейтинг первых десяти механизмов DB (https://db-engines.com/en/ranking). До этого она доавольно продолжительное время пребывал в топ- рейтинге хранилищ ключ- значение (https://db-engines.com/en/ranking/key-value+store).
Основное назначение данной главы состоит в руководстве читателем в быстрой установке простого экземпляра Redis и изучения некоторых общих операций, таких как запуск, подключение и останов Сервера Redis. Также затрагиваются вопросы выборки основной информации из Сервера Redis. Более того, существенно получение лучшего понимания основ имеющейся модели событий и протокола взаимодействия Redis перед изучением Redis. Последние два раздела данной главы содержат подробное обсуждение имеющихся модели событий и протокола Redis.
Redis имеет активное сообщество в GitHub. Было выполнено большое число запросов и переработано с годами, а её автор, Antirez, всегда давал своевременный ответ в общем разделе проблем GitHub. Таким образом, получаемые циклы выпуска Redis очень быстрые. Начиная с самых первых версий, 2.6/ 2.8 до 3.0/ 3.2, которые очень широко применялись, а затем к самой последней версии 4.x, каждый из выпусков Redis предлагал некие существенные улучшения и исправления ошибок. Поэтому наилучшей практикой является использование самой последней версии Redis, если это возможно. В данной книге мы принимаем самую последнюю версию Redit 4.0.1 {Прим. пер.: На момент перевода, конец августа 2018, последней является версия 4.0.11.}
Redis является программным обеспечением с открытым исходным кодом, написанном на чистом языке C, поэтому мы можем устанавливать его посредством компиляции. Основные операционные системы также содержат двоичные пакеты Redis в своих репозиториях программного обеспечения, хотя их версия Redis часто ниже имеющейся на рассматриваемую дату.
Вы можете отыскать необходимую ссылку загрузки и основные шаги по установке на https://redis.io/download. Если у вас есть желание построить Redis скомпилировав исходный код в Linux/Unix/macOS, в вашей среде понадобятся и сам компилятор gcc, и C Standard Library libc. Если речь заходит обустановке из репозитория ОС, всё что вам понадобится, это подключение к интернету и правильная настройка репозитория.
{Прим. пер.: для желающих ознакомиться с установкой Redis в контейнерах отсылаем к своему переводу Docker для разработчиков Rails Роба Айзенберга, The Pragmatic Programmers, LLC., февраль 2019.}
Мы продемонстрируем весь процесс установки с компиляцией Redis в Ubuntu 16.04.2 LTS (Xenial Xerus). Шаги по выгрузке и построению таковы:
-
Настроим инструменты построения:
$ sudo apt-get install build-essential
-
Создадим некий каталог и войдём в него для Redis:
$ mkdir /redis $ cd /redis
-
После этого выгрузим Redis:
$ wget http://download.redis.io/releases/redis-4.0.1.tar.gz
-
Раскроем его и войдем в его каталог:
$ tar zxvf redis-4.0.1.tar.gz $ cd redis-4.0.1
-
Создадим некий каталог для файла настройки Redis и скопируем в него файл настроек по умолчанию:
$ mkdir /redis/conf $ cp redis.conf /redis/conf/
-
Выстроим зависимости:
$ cd deps $ make hiredis lua jemalloc linenoise $ cd ..
Совет Из- за различий между разнообразными операционными системами и установленными в них библиотеками, определённые перечисленные выше шаги потребуются если возникающие ошибки указывающие на неудовлетворительность неких зависимостей. К примеру, вы можете столкнуться со следующим сообщением об ошибке:
zmalloc.h:50:31: fatal error: jemalloc/jemalloc.h: No such file or directory.
Этот шаг не является обязательным для большинства сред, если в зависимостях не происходит ничего предосудительного.
-
Выполните компиляцию:
$ make
Если всё пройдёт успешно, будет отображено приводимое ниже сообщение. Оно означает, что процесс компиляции был успешно завершён:
It's a good idea to run 'make test' ;) make[1]: Leaving directory '/redis/redis-4.0.1/src'
-
Установите Redis:
$ make PREFIX=/redis install
Приводимые далее сообщения представляют полный успех установки:
-
Войдите в каталог
/redis
и убедитесь что необходимые двоичные файды Redis были сгенерированы:$ ls /redis/bin redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-sentinel redis-server
Наши поздравления! Вы выполнили установку Redis путём компиляции.
В сопоставлении с пройденной установкой компиляцией, применение apt-get
в Ubuntu для
установки Redis намного проще. Давайте посмотрим:
-
Для начала обновим индекс репозитория программного обеспечения:
$ sudo apt-get update
-
А затем запустим установку:
$ sudo apt-get install redis-server
-
Когда она завершится, проверим что Redis был установлен в вашей среде:
$ which redis-server
Когда дело доходит до выбора необходимой версии Redis, держите в уме, что Redis следует установленной стандартной практике ведения версий, которой является главная.вспомогательная.исправление. Некое чётное значение вспомогательного значения версии устанавливается для стабильной версии, в то время как нечётные вспомогательные значения относятся к нестабильным версиям, хотя и существует несколько версий для Redis с нечётными вспомогательными значениями.
Основное отличие между построением Redis путём компиляции и построением через некий репозиторий программного обеспечения сотоит в том, что разработчик может добавлять варианты оптимизации или отладки при компиляции, а также собственные функции гибкости определения процесса локализации установки в процессе инсталляции.
После установки получается ряд исполняемых файлов в каталоге bin
. В приводимой ниже таблице
отображены их описания и замечания:
Название файла | Описание | Замечания |
---|---|---|
|
Сервер Redis |
|
|
Redis Sentinel |
Мягкая (soft) ссылка для |
|
Инструментарий консоли Redis |
|
|
Инструмент проверки RDB Redis |
|
|
Инструмент проверки AOF (Append Only Files) Redis |
|
|
Инструментарий эталонного тестирования Redis |
|
Для Windows вы можете получить редакцию Windows Redis, которую группа Microsoft Open Technologies применяла для сопровождения в https://github.com/MicrosoftArchive/redis/releases.
Просто выгрузите имеющийся исполняемый файл .msi
и кликните по нему дважды для установки, оставив
настройки по умолчанию.
Для macOS нет большой разницы в сравнении с приведённой процедурой для Linux. Вы можете установить Redis, запустив в macOS команду
brew install redis
.
-
Для ознакомления с воздействием различных вариантов компиляции на производительности отсылаем вас к оценкам производительности для различных версий Matt Stancliff при применении различных опций компиляции.
-
Исходя из причин безопасности, для Redis следует применять пользователя, не являющегося root, подробнее мы рассматриваем это в рецепте безопасности в Главе 8, Развёртывание промышленной среды
-
Для получения дополнительной информации вы может обратиться к https://github.com/antirez/redis
Прежде чем выполнять доступ к Redis, его Сервер Redis должен быть запущен надлежащим образом. Аналогично, при определённых обстоятельствах, вам придётся останавливать свою службу Redis. Данный рецепт покажет вам как запускать и останавливать Сервере Redis.
Вам требуется завершить установку своего Сервера Redis, как это было описано в рецепте Загрузка и установка Redis данной главы.
Необходимые этапы для запуска и останова Сервера Redis таковы:
-
Вы можете запустить некий Сервер Redis с настройками по умолчанию:
$ bin/redis-server
Ваш сервер теперь должен запуститься как это показано на следующем снимке экрана:
-
Чтобы запустить некий Сервер Redeis при помощи какого- то файла настроек, такого как тот, что мы скопировали из своего исходного пакета кода в своём рецепте установки, наберите следующее:
$ bin/redis-server conf/redis.conf
-
Если вы установили Redis из определённого репозитория некоторой операционной системы, вы можете запустить Redis при помощи сценария
init.d
:$ /etc/init.d/redis-server start
-
Для запуска
redis-server
в качестве демона в фоновом режиме при запуске, вы можете изменить свой файл настроек и кстановить значение параметраdaemonize
вyes
и запустить с данной конфигурацией:$ vim conf/redis.conf daemonize yes $ bin/redis-server conf/redis.conf
Получаемое сообщение
Configuration loaded
, отображаемое на приводимом ниже снимке экрана указывает, что данная настройка уже применена:
-
Соответственно, вы можете воспользоваться
Ctrl + C
(если Redis запущен в приоритетном режиме), или применитеKill + PID
(если Redis запущен в фоновом режиме) чтобы остановить определённую службу Redis:$ kill `pidof redis-server`
-
Более аккуратный и рекомендуемый способ для остановки Redis состоит в вызове конкретной команды останова в
redis-cli
:$ cd /redis $ bin/redis-cli shutdown
-
Redis может также быть остановлен самим сценарием
init.d
, в случае когда вы установили его из определённого репозитория вашей операционной системы:$ /etc/init.d/redis-server stop
Применяемый термин экземпляр (instance) в Redis
представлен неким процессом redis-server
. В одном и том же хосте может запускаться множество
экземпляров Redis, пока они применяют различные настройки, например, различные порты связывания, пути постоянных данных, пути
журналов и тому подобное.
Запуск и останов экземпляра Redis являются базовыми операциями. Не так много чего можно заметить при запуске Redis, однако для некоторой службы данных останов службы Redis заслуживает большего внимания, так как, выступая в роли службы хранения данных, именно в этом основной важный момент для вас при изучении того как аккуратно останавливать ваш Сервер Redis для сопровождения целостности данных.
Основная причина зачем настоятельно рекомендуется применять команду shutdown
для остановки
Redis состоит в том, что если вы заботитесь в целостности данных и уже имеете постоянный набор для сохранения Redis ваших данных в оперативной
памяти на диск (механизм постоянности Redis будет обсуждаться в Главе 6,
Постоянство), выполняя соответствующую команду shutdown
не только для завершения
определённого процесса, но также предпринимать некую последовательность прочих действий.
Во- первых, сам redis-server
остановит всех своих клиентов, а затем будет выполнено одно
постоянное действие если было включено Постоянство. После этого он очистит имеющиися файл .pid
и файл socket
, если они имеются и, наконец, выйти из этого процесса. Адаптируя данную стратегию,
Redis предпринимает всё возможное для предотвращения утраты любых данных. И наоборот, если г рубо применяется команда
kill
для прекращения запущенного процесса redis-server
,
данные могут теряться, поскольку они не становятся постоянными до того как этот сервер остановлен.
Следует заметить что применение kill
или иных инструментов управления процессами для
отправки некоторого сигнала SIGTERM
(сигнала 15) в запущенный процесс Redis в своей основе
эквивалентен рассматриваемой команде shutdown
для аккуратного останова запущенного
redis-server
.
При запуске самой команды redis-server
можно добавлять параметры настройки, что достаточно
удобно при развёртывании множества экземпляров в некотором отдельном хосте. Мы можем иметь некий отдельный файл настроек, используемый
множеством экземпляров в одном и том же хосте. Тем временем, необходимые уникальные параметры настройки каждого экземпляра могут
передаваться в командной строке при запуске. Таким образом, мы избавляемся от стоимости сопровождения множества файлов настройки, а
экземпляры могут легко различаться через ps
или иные системные команды.
Кроме того, вы можете управлять своим экземпляром Redis используя инструменты управления процессами, такими как systemd, supervisord или Monit, которые могут также могут избавлять вас от беспорядка при развёртывании ножества экземпляров некотором отдельном хосте. Всё что нам требуется, это уделять внимание своим упомянутым ранее параметрам настройки запуска и механизмам обработки сигналов выхода.
-
Для получения дополнительных сведений о том как Redis обрабатывает различные виды сигналов обратитесь к https://redis.io/topics/signals, в особенности в обнаружении небольших, но существенных отличий между этими механизмами обработки сигналов. Кроме того, для более глубокого знакомства с аккуратным остановом экземпляра Redis обратитесь к https://redis.io/commands/shutdown
-
https://git.io/v5chR выступает неким примером настройки Сервера Redis systemd в качестве инструмента управления процессом при управлении запуском/ остановом Redis.
-
Более того, вы можете обратиться к Главе 6, Постоянство относительно неизменности Redis.
При разработке и сопровождении Redis redis-cli
в каталоге
bin
является наиболее часто применяемым инструментом. Данный раздел предоставляет его краткое
описание с тем,чтобы читатель смог получить лаконичное представление того как подключаться к Redis и применять его с помощью
redis-cli
.
Вам требуется поднятый и исполняющийся Сервер Redis, согласно нашему описанию в рецепте Запуск и останов Redis этой главы.
Для подключения к Redis при помощи redis-cli
применяется следующая последовательность
шагов:
-
Откройте Терминал и подключитесь к редис с помощью
redis-cli
:$ bin/redis-cli 127.0.0.1:6379>
Шаблоном предыдущего приглашения является
IP:port
, что указывает на то, чтоredis-cli
успешно подключился к данному экземпляру Redis. -
Для проверки отправим несколько простых команд. В последующих главах мы обсудим дополнительные типы данных и функции.
-
Для начала установим две строковые пары ключ- значение,
foo value1
иbar value2
:127.0.0.1:6379> set foo value1 OK 127.0.0.1:6379> set bar value2 OK
-
После этого выполним выборку только что установленных нами значений:
127.0.0.1:6379> get foo "value1" 127.0.0.1:6379> get bar "value2"
-
Наконец, мы прекратим выполнение Redis, отправив соответствующую команду
shutdown
:$ bin/redis-cli 127.0.0.1:6379> shutdown not connected>
-
После останова наше приглашение Командной строки изменилось на
not connected
. Затем мы покидаемredis-cli
и выполняем подключение кredis-cli
вновь. Будет отображено следующее сообщение:not connected>quit $ bin/redis-cli Could not connect to Redis at 127.0.0.1:6379: Connection refused Could not connect to Redis at 127.0.0.1:6379: Connection refused not connected>
По умолчанию redis-cli
подключается к некоторому экземпляру Redis запущенному на
локальном хосте с портом по умолчанию 6379
. Вы также можете определить значение имени
хоста/ IP адреса соответствующего Сервера Redis, запуская команду с параметром -h
.
Просто убедитесь что имеется подключение между вашей стороной redis-cli
и стороной
самого Сервера Redis и в нём нет проблем.
redis-cli
позволяет определять вам порт при помощи параметра
-p
в случае, когда ваш Сервер Redis не запущен с портом по умолчанию
6379
. Этот параметр таже полезен когда вы желаете выполнять подключение с множеством
экземпляров Redis с различными портами привязки в одном и том же хосте.
Кроме того, некий экземпляр Redis защищается при помощи пароля, для установки пароля при подключении к Redis моежет применяться
соответствующий параметр -a
.
Кроме того, если в Redis доступен некий файл socket
, вы можете просто подключаться к Серверу
Redis с применением параметра -a
.
Зачастую имеется некая потребность выполнения проверки какого- то прототипирования прежде чем прицеплять ваше приложение к Redis.
Для этого очень полезным инструментом является redis-cli
. Он предоставляет некий интерфейс
командной строки с тем, чтобы вы могли быстро проверить архитектуру своих данных. Для повседневного сопровождения Сервера Redis
redis-cli
также предоставляет некое множество команд, в том числе получение соответствующих
замеров, манипулирование состояниями системы и установкой настроек производительности.
-
Для обсуждения подробностей того, как управлять неким экземпляром Redis, обратитесь к Главе 9, Администрирование Redis.
При помощи команды INFO
redis-cli
может быть получена
наиболее всеобъемлющая и важная информация об экземпляре Redis. В данном разделе мы рассмотрим как применять команду
INFO
для выборки таких существенных статистических данных.
Вам требуется поднятый и исполняющийся Сервер Redis, согласно нашему описанию в рецепте Запуск и останов Redis этой главы.
Для получения информации о Redis придерживайтесь следующих шагов:
-
Подключитесь к некому экземпляру Redis и затем воспользуйтесь командой
INFO
:$ bin/redis-cli 127.0.0.1:6379> INFO
Получаемые результаты выглядят следующим образом:
# Server redis_version:4.0.1 ... # Clients connected_clients:1 ... # Memory used_memory:828352 used_memory_human:808.94K used_memory_rss:9420800 used_memory_rss_human:8.98M ... # Persistence loading:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:0 rdb_last_save_time:1504223311 ... # Stats total_connections_received:1 total_commands_processed:1 instantaneous_ops_per_sec:0 ... # Replication role:master connected_slaves:0 ... # CPU used_cpu_sys:0.01 used_cpu_user:0.00 ... # Cluster cluster_enabled:0
-
Вы можете выбирать определённый раздел, добавляя некий необязательный параметр
<section>
. Например, мы получаем измерения памяти отправляя вredis-cli
командуINFO memory
:
-
Другим способом получения информации от экземпляра Redis является применение
redis-cli INFO
непосредственно в командной строке. Таким образом достаточно удобно организовывать конвейер вывода в некий сценарий для анализа измерений или мониторинга производительности.
Команда INFO
предоставляет вам все текущие измерения Redis и определённый шаблон
каждого измерения в виде metric-name: metric-value
, с которым в последующем может быть
запросто можно выполнить синтаксический разбор.
Приводимая ниже таблица суммирует общие описания каждого раздела, возвращаемого INFO
:
Название раздела | Описание |
---|---|
|
Основная информация о Сервере Redis |
|
Состояние и измерения соединений клиента |
|
Измерения общего потребления памяти |
|
Состояния и измерения, относящиеся к постоянным данным |
|
Общие статистические данные |
|
Состояние и измерения репликации хозяин- подчинённый |
|
Потребление ЦПУ |
|
Состояние Кластера Redis |
|
Статистические данные, относящиеся к базе данных |
Построение некоего приложения мониторинга путём получения информации из периодически выполняемой команды
INFO
является распространённой практикой.
-
Для получения дополнительной информации относительно применения
INFO
для операций сопровождения и поиска неисправностей Redis отсылаем вас к разделам Проверка состояния Redis, Проблемы выявления неисправностей латентности и Проблемы выявления неисправностей памяти в Главе 10, Поиск неисправностей Redis. -
Вы также можете обратиться к https://redis.io/commands/INFO, где перечисляются значения всех измерений, возвращаемых
INFO
.
Redis, знаменитый своей высокой производительностью, для быстрой обработки запросов заставляет большинство отдельных потоков
придерживаться модели неблокируемого ввода/ вывода. Следовательно, существенным является понимание общей модели событий Redis.
В качестве пробного образца для понимания читающим такой модели, данный рецепт вначале показывает некую демо программу
echo server
, которая строится на библиотеке асинхронных событий Redis
(библиотека ae
). Затем мы предоставляем важные сущностные моменты имеющейся модели обработки
событий Redis анализируя определённый фрагмент исходного кода Redis.
Данный рецепт содержит множество практических программных приёмов C. Поэтому, если вы недостаточно подкованы в языке C, вы можете пропустить этот рецепт,если пожелаете и вас не должно сильно беспокоить когда вы продолжите чтение.
Данный рецепт затрагивает построение и отладку исходного кода. Поэтому вам вначале требуется завершить рецепт Загрузка и установка Redis из этой главы. Для лучшей иллюстрации необходим некие IDE, который поддерживает язык программирования C. Применяемым нами IDE является CLion в Ubuntu Desktop 16.04.3 LTS. Хотя CLion IDE и не является свободно распространяемым, нам будет достаточно 30- дневного пробного срока.
Вам также следует подготовить соответствующий компилятор C и среду разработки. В Ubuntu мы можем воспользоваться следующей командой для установки относящихся к этому пакетов:
$ sudo get update && apt-get install build-essential
После установки вам следует убедиться, что CMake имеет версию 3.5 или выше:
$ cmake --version
cmake version 3.5.1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
Для получения представления о Модели событий Redis выполните следующую последовательность:
-
Раскройте необходимый пакет исходного кода Redis и постройте некие необходимые зависимости вручную вместо того, чтобы применять CMake:
~$ mkdir coding; cd coding ~/coding$ tar xzvf redis-4.0.1.tar.gz ~/coding$ cd redis-4.0.1/deps/ ~/coding/redis-4.0.1/deps$ make lua linenoise hiredis
Приводимый ниже снимок экрана указывает, что все зависимости были построены успешно:
-
Выгрузите пакет CLion IDE и раскройте его в каталоге
/redis/coding/
:~/coding$ wget https://download.jetbrains.8686c.com/cpp/CLion-2017.2.2.tar.gz ~/coding$ tar zxvf CLion-2017.2.2.tar.gz
-
Загрузите наш демонстрационный пакет пакет для построения и отладки
redis-server
. -
Раскройте его в каталоге
redis-4.0.1
:~/coding$ tar xzvf echodemo.tar.gz -C redis-4.0.1/
Убедитесь что следующие файлы,
CMakeLists.txt
иechodemo
присутствуют в каталогеredis-4.0.1
:
-
Зарегистрируйтесь на своём рабочем столе Ubuntu и откройте Терминал для запуска CLion:
~/coding/clion-2017.2.2$ bin/clion.sh
-
После подтверждения лицензионного соглашения вам следует проверить, что и CMake и отладчик готовы, как это показано ниже:
-
Продолжайте с установленными по умолчанию значениями, пока вы не достигните следующего снимка экрана:
Кликните по Import Project from Sources и выберите в каталоге
coding
подкаталогredis-4.0.1
.Кликните по кнопке OK button, а затем выберите Open Project чтобы открыть проект Redis.
-
Выберите соотвествующую конфигурацию Build All из своего верхнего правого угла и кликните по кнопке Run:
Проигнорируйте появившуюся ошибку того, что не определена некая исполняемая цель, и кликните Run.
Следующие регистрационные записи отобразят что вы управляли построением и демонстрационной программы
echo-server/client
, иredis-server
(в данном примереmy-redis-server
):/redis/coding/clion-2017.2.2/bin/cmake/bin/cmake --build /redis/coding/redis-4.0.1/cmake-build-debug --target all -- -j 6 Scanning dependencies of target ae Scanning dependencies of target my-redis-server [ 1%] Building C object CMakeFiles/ae.dir/src/zmalloc.c.o ... [ 17%] Building C object CMakeFiles/my-redis-server.dir/src/blocked.c.o Scanning dependencies of target echo-server ... [ 25%] Built target echo-server [ 26%] Building C object CMakeFiles/my-redis-server.dir/src/config.c.o ... [ 31%] Building C object CMakeFiles/my-redis-server.dir/src/defrag.c.o [ 32%] Linking C executable echo-client [ 32%] Built target echo-client [ 98%] Building C object CMakeFiles/my-redis-server.dir/src/zmalloc.c.o [100%] Linking C executable my-redis-server [100%] Built target my-redis-server
-
В том случае,если вы в первую очередь желаете использовать командную строку для компиляции демонстраций, вы можете выполнить следующие шаги:
/redis/coding/redis-4.0.1$ cmake -- The C compiler identification is GNU 5.4.0 ... -- Configuring done -- Generating done -- Build files have been written to: /redis/coding/redis-4.0.1 /redis/coding/redis-4.0.1$ make Scanning dependencies of target my-redis-server [ 1%] Building C object CMakeFiles/my-redis-server.dir/src/adlist.c.o [ 2%] Building C object CMakeFiles/my-redis-server.dir/src/ae.c.o ... [ 85%] Building C object CMakeFiles/my-redis-server.dir/src/zmalloc.c.o [ 86%] Linking C executable my-redis-server [ 86%] Built target my-redis-server Scanning dependencies of target ae ... [ 92%] Built target ae Scanning dependencies of target echo-server ... [ 96%] Built target echo-server Scanning dependencies of target echo-client ... [100%] Built target echo-client
-
В каталоге
cmake-build-debug
подredis-4.0.1
вы можете обнаружитьecho-server
,echo-client
иmy-redis-server
:
В правом верхнем углу выберите конфигурацию
echo-server
и кликните по кнопке правой стрелки для её исполнения:
-
Откройте некий Терминал и затем подключитесь к
echo-server
при помощиnc
(Netcat):~/coding/redis-4.0.1/cmake-build-debug$ nc 127.0.0.1 8000
-
В случае, когда ваш сервер стартовал успешно, будет отображено сообщение
Hello Client!
:
Вот регистрационные записи данного подключения:
-
В
nc
наберитеHello, please echo!
и нажмите наEnter
для отправки текста. То же самое сообщение должно вернуться к вам эхом:
На стороне сервера будут зарегистрированы те данные, которые были отосланы обратно к клиенту позднее:
-
Откройте другой Терминал и осуществите другое подключение к своему
echo-server
. Аналогичный результат будет получен и на сторонеnc
, и на стороне сервера, что отображено на приводимом ниже снимке экрана:
-
Вы можете выполнять отладку этого сервера по своему желанию:
-
Для более глубокого погружения в исходный код вы можете построить и отладить сервер
redis-server
(именуемый в данном примереmy-redis-server
) почти тем же самым способом, что и в нашем примереecho-server
. Единственный момент,который вам следует изменить, это выбратьmy-redis-server
в профиле конфигурации run/debug:
Как уже упоминалось ранее, Redis получает громадные преимущества от своей модели неблокируемого, мультиплексированного ввода/ вывода при своей основной обработке отдельного потока, хотя имеются определённые обстоятельства, при которых Redis для определённых задач и порождает отдельные потоки или процессы потомков.
Redis содержит в себе простую, но мощную библиотеку асинхронных событий, именуемую ae
для
обёртывания функций опроса различных операционых систем, таких как epoll
,
kqueue
, select
и тому подобных.
{Прим. пер.: подробнее, например, в нашем переводе главы API Epoll из руководства Микаэля Керниска "Интерфейс программирования Linux".}
Итак, что такое функциональность опроса в некоторой операционной системе? Для иллюстрации этого давайте воспользуемся примером из реальной жизни. Представим себе,что вы заказали пять блюд в некотором ресторане. Вам придётся получать свои блюда самостоятельно в каком- то окне ожидания, причём вы желаете получать их настолько быстро, насколько это возможно, как только эти блюда будут готовы, так как вы очень голодны. При таком развитии событию у вас имеются три стратегии:
-
Вы подходите к окну выдачи каждый раз самостоятельно время от времени через короткие промежутки времени для проверки того, что готово каждое блюдо из списка заказа.
-
Вы нанимаете пятерых людей. каждый из них подходит к окну выдачи для проверки того, что одно из блюд по вашему списку приготовлено.
-
Вы просто сидите за столом, ожидая соответствующего уведомления. Специально обученный уведомлению о готовности член службы ресторана сделает вам уведомление, что означает, что официант сообщит вам какое из блюд готово, как только оно будет приготовлено. Как только вы получаете такое уведомление, вы получаете блюдо самостоятельно.
Принимая во внимание те время и усилия, которые они потребуют, очевидно, что третий вариант является наилучшим.
Функциональность опроса (polling) аналогично тому, как это делается в третьем варианте. Для упрощения данного раздела в качестве
примера мы рассмотрим только метод epoll
API Linux. Вначале вы можете вызвать
epoll_create
чтобы сообщить своему ядру, что вы желаете применять
epoll
. Затем вы вызываете epoll_ctl
для
информирования своего ядра о необходимых файловых дескрипторах (FD) и о
том, какой тип события вас интересует, когда произойдёт некое обновление. После этого epoll_wait
выполняет вызов ожидания определённого события с тем FD, который вы назначили в epoll_ctl
.
Само ядро отправит вам некое уведомление при обновлении вашего FD. Единстенный момент, который вам следует осуществить, это создать
обработчики для определённых событий.
Весь процесс мультиплексирования целиком выглядит следующим образом:
В целом, имеющаяся в Redis библиотека ae
при обработке всех запросов следует приведённой выше
процедуре. В своём примере echo-server
мы создаём некий цикл событий вызывая вначале
aeCreateEventLoop
. Затем посредством anetTcpServer
строится какой- то сервер TCP для привязки к сетевой среде и организации процесса ожидания. Для настройки некоторого неблокируемого
действия в данном FD сокета мы делаем вызов anetNonBlock
. После этого мы определяем соответствующий
обработчик события acceptProc
для данного FD сокета при помощи того цикла событий, который создан в
aeCreateEventLoop
. Когда соединение TCP установлено, наш сервер переключит своё действие в
acceptProc
. В acceptProc
мы применяем
anetTcpAccept
для приёма соответствующего запроса на подключение и регистрации событий считывания
с данного FD сокета для readProc
. Затем readProc
получает вызов, в котором мы считываем те данные, которые отправлены в наш сервер и регистрируем соответствующее событие для записи в
свой FD сокета. Наш цикл событий затем получает соответствующее событие записи чтобы зажечь необходимый
writeProc
для отправки полученных данных обратно в сокет клиента.
Redis работает во многом аналогично тому, как это делает echo-server
.
В функции main server.c
в соответствующем методе initServer
для инициализации нашего сервера вызываются aeCreateEventLoop
,
anetTcpServer
и anetNonBlock
:
Соответствующий обработчик приёма также устанавливается в этом методе initServer
, как это
показано в следующем снимке экрана:
После того как наш сервер установлен, получает вызов соответствующий метод aeMain
:
Для непрерывной обработки возникающих событий в нашем методе aeMain
вызывается
asProcessEvents
:
Ясно, что в данном процессе опроса не порождается ни какой поток или подчинённый процесс и не выполняется никакое взаимодействие. Таким образом, основным ключевым преимуществом данной модели является то, что она выступает яркой моделью контекстного переключения ввода/ вывода, поэтому переключение контекста не является затратным. Для данной модели следует рассматривать ряд ограничений. Наиболее распространённой проблемой, с которой вы можете сталкиваться является проблема задержек. В данной модели опроса Redis не будет обрабатывать никакие иные команды, пока не завершится обрабатываемая. Поэтому, начиная с данного момента держите на уме, что некая неожиданная латентность будет самой первой головной болью для вас при использовании Redis.
Прочие методы опроса, такие как poll, select и тому подобные, не обсуждаются здесь в силу их ограниченной применимости. Если вы работаете с иными нежели Linux платформами, вы можете пройти отладку соответствующего исходного кода с тем, чтобы дополнительно изучить возможности опроса в этой платформе.
-
Для более подробного ознакомления с обнаружением проблем с латентностью Redis ознакомьтесь с разделами Выявление медленных запросов при помощи SLOWLOG Проблемы выявления неисправностей латентности в Главе 10, Поиск неисправностей Redis.
-
Если вы желаете строить и отлаживать свой исходный код в Windows, отсылаем вас к Приложению A, Установка среды Windows.
-
В дальнейшем вы также можете воспользоваться следующими ссылками:
https://redis.io/topics/internals-eventlib предлагает вам боле глубокие внутренние концепции рассматриваемой библиотеки событий.
https://redis.io/topics/internals-rediseventlib описывает подробности самой библиотеки событий Redis.
-
Если вы работаете с операционной системой, отличной от Ubuntu, для установки CMake вы можете обратиться к https://cmake.org/install/.
Как мы уже обсуждали в нашем предыдущем рецепте, Radis всего навсего некий TCP сервер неблокируемого ввода/ вывода с мулитиплексированием, которые принимает от клиентов запросы и обрабатывает их. Другими словами, несмотря на сложность организации самого Сервера Redis, вы можете общаться с Rdeis поверх подключения TCP на различных языках программирования. Термин протокол применяется для того языка, который применяется между некими сервером и клиентом при сетевом взаимодействии. Что касается Redis, таким протоколом является RESP (REdis Serialization Protocol). В данном рецепте мы рассмотрим как RESP работает в Redis.
Стоит отметить один момент: Даже на первый взгляд слегка самонадеянно для новичков ознакомиться с данным рецептом. Однако мы на самом деле полагаем, что изучение основ RESP, на базовом уровне, не настолько сложно и сулит для вас преимущества в таком понимании в таком понимании различных видов клиентов и посредников (прокси), реализуемых в разнообразных языках программирования, которое больше не будет представлять для вас мистики.
Безусловно, вы можете пропустить данный рецепт и это не должно вызвать вашей обеспокоенности при чтении в последующих главах.
{Прим. пер.: на самом деле, Redis не обязан ограничиваться исключительно протоколом TCP/IP, он прекрасно может быть реализован, например, поверх RDMA, см. например Using RDMA Efficiently for Key-Value Services Anuj Kalia, Michael Kaminsky, David G. Andersen, CMU, 2014; Accelerating Redis with RDMA Over InfiniBand Wenhui Tang, Yutong Lu, Nong Xiao, Fang Liu, Zhiguang Chen, DMBD 2017. или обратитесь к нам относительно применения RDMA over Ангара.}
Вам требуется поднятый и исполняющийся Сервер Redis, согласно нашему описанию в рецепте Запуск и останов Redis этой главы.
Должен быть установлен необходимый инструмент, netcat (nc
). В этом рецепте у нас есть
команды для nc
в Ubuntu 16.04.3 LTS для netcat. Если вы работаете под Windows, вы можете
воспользоваться Cygwin для установки netcat.
Для знакомства с протоколом Redis сделайте следующие шаги:
-
При помощи netcat отправьте в свой Сервер Redis команду
PING
.Вместо отправки команды
PING
вredis-cli
, давайте построим соответствующую команду при помощи RESP:$ echo -e "*1\r\n\$4\r\nPING\r\n" | nc 127.0.0.1 6379 +PONG
-
Для установки целого значения и уго приращения на единицу воспользуйтесь командами
SET
иINCR
:$ echo -e "*3\r\n\$3\r\nset\r\n\$5\r\nmykey\r\n\$1\r\n1\r\n" | nc 127.0.0.1 6379 +OK $ echo -e "*2\r\n\$4\r\nINCR\r\n\$5\r\nmykey\r\n" | nc 127.0.0.1 6379:2
При отправке не существующей команды вы можете столкнуться со следующей ошибкой:
$ echo -e "*2\r\n\$3\r\ngot\r\n\$3\r\nfoo\r\n" | nc 127.0.0.1 6379 -ERR unknown command 'got'
Можно комбинировать несколько команд и отправлять их в свой Сервер Redis в единой сетевой передаче:
$ echo -e "*3\r\n\$3\r\nset\r\n\$3\r\nfoo\r\n\$3\r\nbar\r\n*2\r\n\$3\r\nget\r\n\$3\r\nfoo\r\n" | nc 127.0.0.1 6379 +OK $3 bar
Имеется большая вероятность, что ознакомившись с этими командами , вы испытаете большое смятение. Как мы уже постулировали в разделе предисловии этого рецепта, эти команды являются тем языком, на котором Сервер Redis и клиент общаются друг с другом. Вам будет просто изучить его, так как в RESP имеется всего пять типов.
Давайте рассмотрим все команды.
Вначале мы отправляем в свой Сервер Redis *1\r\n\$4\r\nPING\r\n
. Данная команда начинается со
звёздочки, которая означает, что она представляет тип массива.
Рассмотрим по очереди:
-
1
устанавливает размер данного массива. -
\r\n
(CRLF) является необходимым терминатором для каждой части в RESP. -
Знак косой черты перед
$4
является экранирующим символом для идущего следом символа$
.$4
сообщает, что вслед за ним следует пакет строкового типа длиной в четыре символа. -
PING
является собственно этой строкой. -
+PONG
является той строкой, которую возвращает командаPING
.
Следующий тип, о котором мы поговорим, это соответствующий тип целых. Взгляните на :2
,
что является результатом, возвращаемым командой INCR
. Установленное перед самим
численным значением двоеточие указывает на то, что это некое целое значение.
Порой ваш сервер может возвращать некий тип сообщения об ошибке, начинающийся с минуса, когда была обработана несуществующая
команда, такая как показанная ранее команда got
.
Кроме того, из соображений производительности вы можете отправлять при помощи RESP множество команд в отдельном вызове в Сервер Redis.
Суммируя, ваш клиент отправляет в некий Сервер Redis команды как массив кипы строк. Затем сервер отвечает соответствующим образом одним из пяти упомянутых выше типов RESP.
-
Для получения дополнительных подробностей о протоколе RESP обратитесь к https://redis.io/topics/protocol .
-
Различные виды клиентов и посредников можно получить в GitHub. Например, для Java Netty реализации RESP вы можете обратиться к https://github.com/tonivade/resp-server.