Рубрики
Uncategorized

Прочитайте исходный код с помощью Dabin – Redis 2 – Как сервер отвечает на запросы клиентов? (I)

Автор оригинала: David Wong.

В прошлый раз мы спросили: “Что сделала программа для запуска сервера?” Следуя исходному коду, мы досконально понимаем процесс запуска сервера Redis.

Теперь, когда сервер Redis запущен, нам нужно подключиться к службе Redis, чтобы что-то сделать. Здесь мы можем пройти тест redis-cli.

Теперь клиент и сервер готовы, поэтому Как клиенты и серверы Redis устанавливают соединения? Как сервер отвечает на запросы клиентов?

1 Подключите Сервер

Для связи между клиентом и сервером первым шагом является установление соединения. Далее давайте рассмотрим процесс подключения между redis-cli и сервером.

Помните, когда мы в последний раз использовали его gdb Это процедура отладки программы? Давайте еще раз рассмотрим redis-cli и посмотрим, как работает исходный код. Прежде чем начать, не забудьте открыть его в редакторе redis-cli.c Найдите основное Расположение функций, в конце концов, GDB выглядит комфортно без редактора.

Шаги по отладке следующие:

# bash
cd /opt/redis-3.2.13
// Start the Redis service. Ctrl + C can push out the server startup page while keeping the server running
./src/redis-server --port 8379 &
// Debugging redis-clli
gdb ./src/redis-cli
# gdb 
(gdb) b main
(gdb) r -p 8379
(gdb) layout src
(gdb) focus cmd

После выполнения описанных выше действий мы войдем в следующий интерфейс:

Затем мы можем вернуться на страницу редактора и посмотреть, правильно ли это. главная Какая строка в функции интереснее, остановитесь для изучения. По строке 2618 мы увидим исполнение. parseOptions Эта функция, судя по имени, инициализирует некоторые дополнительные параметры. Давайте зайдем и посмотрим.

1.1 Инициализация конфигурации клиента

Этапы выполнения функции: главная -> Параметры синтаксического анализа -> главная

Посмотрим, в исполнении. redis-cli Параметры, которые мы переносим, разрешаются в этой функции, например, то, что мы переносим при запуске. -p Параметры анализируются в строке 996 и назначаются элементу конфигурации хост-порта клиента. Следующим образом:

1.2 Режим запуска Клиента

Этапы выполнения функции: главная

Вернитесь к main Функции, и вы увидите много кода, который появится позже cliConnect Функция. Обратите внимание, что это не означает, что redis-cli выполняет функцию cliConnect много раз. Фактически, каждый блок операторов if представляет режим подключения для клиентов. Версия 3.2.13 поддерживает следующие режимы:

  1. Режим задержки: Режим задержки. redis-cli --задержка-p 8379 Используется для проверки задержки соединения клиент-сервер. Также --история и --dist Опции для отображения различных форм.
  2. Подчиненный режим: Имитирует подчиненный режим.
  3. Получить режим RDB: Создавайте и отправляйте постоянные файлы RDB и сохраняйте их локально.
  4. Режим трубы: Режим трубы. Команда инкапсулируется в указанный формат данных и пакетами отправляется на сервер redis для выполнения.
  5. Найти большие ключи: Статистическое распределение больших ключей.
  6. Режим статистики: Статистический режим. Отображение статистики сервера в режиме реального времени.
  7. Режим сканирования: Сканируйте ключи указанного режима, который эквивалентен режиму сканирования.
  8. Режим тестирования LRU: Тестирование попаданий алгоритма LRU в режиме реального времени.

1.3 Подключение Сервера

Этапы выполнения функции: main – > |/cliConnect - > |/redisConnect – > |/redisContextInit - > |/redisContextConnectTcp – > |/_redisContextConnectTcp - > |/cliConnect

Мы не использовали специальный режим для запуска выше, поэтому мы увидим реальный вызов на линии 2687. cliConnect Функция. Следуйте за ним и давайте посмотрим, как он подключается к серверу.

оставайтесь cliConnect В функции, мы видим, что в соответствии с хост-сокетом Элементами конфигурации используются разные режимы подключения. Судя по названию, мы, вероятно, можем догадаться, что одно из них является соединением сокета TCP, а другое-собственным соединением сокета Unix.

Если вы хотите использовать сокетные соединения Unix, просто настройте их в формате hostscoket Can: ./src/redis-cli-s/tmp/redis.носок

Здесь мы используем соединение через сокет TCP, используя повторное отключение Функция устанавливает соединение.

Продолжайте отслеживать, и мы увидим шаги выполнения функции, показанные выше. _redisContextConnectTcp Как вы можете видеть в функции getaddrinfo и connect Именно здесь устанавливается TCP-соединение.

1.4 Проверьте разрешения и выберите базы данных

Этапы выполнения функции: cliConnect -> сеть поддерживает работу – > |/Аутентификация cli -> Выбор cli - > |/главная

Вернитесь к функции cliConnect , если мы подключимся к серверу нормально, мы также установим TCP-соединение, созданное выше, на длительное соединение, затем проверим разрешения и выберем подключение к базе данных.

...
/* Set aggressive KEEP_ALIVE socket option in the Redis context socket
 * in order to prevent timeouts caused by the execution of long
 * commands. At the same time this improves the detection of real
 * errors. */
anetKeepAlive(NULL, context->fd, REDIS_CLI_KEEPALIVE_INTERVAL);
/* Do AUTH and select the right DB. */
if (cliAuth() != REDIS_OK)
    return REDIS_ERR;
if (cliSelect() != REDIS_OK)
    return REDIS_ERR;
...

На данный момент мы завершили весь процесс установления соединения между клиентом и сервером. Заинтересованные партнеры могут попытаться подключиться к несуществующим IP-адресам или портам, наблюдать за временем, когда программа выдает исключение, и быть знакомыми со всем процессом подключения.

После того, как клиент установит соединение с сервером, ключом в базе данных можно управлять с помощью соответствующих команд. Теперь давайте взглянем на УСТАНОВИТЬ ЗНАЧЕНИЕ КЛЮЧА Возьмите команды в качестве примера, чтобы увидеть, как они выполняются.

2 Отправьте запрос на команду

Когда пользователь вводит запрос команды в клиенте, клиент преобразует запрос команды в формат протокола, а затем отправляет преобразованный запрос команды на сервер через сокет, подключенный к серверу, как показано на рисунке 3:

Поэтому для нашего приведенного выше запроса команды клиент обратится к:

"*3\r\n$3\r\nSET\r\n$3\r\nKEY\r\n$5\r\nVALUE\r\n"

Затем отправьте его на сервер.

Это процесс отправки команд от клиента на сервер. В следующем разделе мы увидим, как сервер отвечает на запрос клиента.