Когда запускается Редис

Redis задняя часть
Когда запускается Редис

"Это седьмой день моего участия в ноябрьском испытании обновлений, ознакомьтесь с подробностями события:Вызов последнего обновления 2021 г."

Как самая популярная база данных пар «ключ-значение», Redis играет очень важную роль в разработке системы нашими бэкэнд-инженерами. Его сверхвысокая производительность чтения и записи, богатая структура хранения, дизайн кластера с высокой доступностью и активное сообщество, несомненно, являются лучшим выбором для баз данных с открытым исходным кодом в памяти. Давайте узнаем сегодняКак Redis обрабатывает команду? Какую маленькую мысль он использует в коде для повышения производительности?

Источники данныхdb-engines.com

до начала

Прежде чем начать, убедитесь, что у нас есть определенное понимание установки, работы и общих команд Redis, чтобы у нас было понимание восприятия при попытке понять принцип внутренней реализации. Давайте рассмотрим:

  1. Запустите контейнер Redis через Docker и введите
$ docker pull redis:4
$ docker exec -p 6379:6379 -itd --name redis redis:4
# 进入容器
$ docker exec -it redis sh
  1. пройти черезredis-cliподключиться, выполнить некоторые команды
$ redis-cli
redis-cli(6379)> set name foo
OK
redis-cli(6379)> get name
"foo"

Давайте посмотрим, что произошло с Redis в описанном выше процессе?imageС внешней точки зрения, то есть с точки зрения клиента, его можно разбить на следующие этапы.

  1. Служба Redis запускается
  2. Клиент устанавливает соединение с Redis
  3. Клиент отправляетset name fooкоманда, возврат ответаOK
  4. Клиент отправляетget nameкоманда, возврат ответаfoo

Итак, далее мы начнем с внутренней точки зрения Redis (Анализ на основе исходного кода Redis 5.0), заходи и смотри, когда командаset name fooКогда его получает Redis, насколько он «сопротивляется одному человеку»?image

Когда запускается Редис

Когда Redis запускается, он сначала инициализирует сервер, включая следующие шаги:

  1. Исходная конфигурация (конфигурация системы по умолчанию)
  2. Загружать и анализировать файлы конфигурации (конфигурация пользователя)
  3. Инициализировать внутренние переменные службы
  4. Создать цикл событий eventLoop
  5. Создайте сокет и начните слушать
  6. Создать событие файла и событие времени
  7. запустить цикл событий

Начальная конфигурация

Основная функция первой операцииinitServerConfig(void), имеется более 200 строк, в основном для установки конфигурации системы по умолчанию для некоторых основных параметров сервера, таких как:

основные параметры По умолчанию
Частота выполнения запланированной задачи по умолчанию 10
номер порта прослушивания 6379
Максимальное количество клиентов 10000
тайм-аут клиента 0 (никогда не истекает)
Количество баз данных 16
Кроме того, инициализируется список часто используемых команд.

Загрузка и разбор файлов конфигурации

Основная функция операции второго шага состоит в том,void loadServerConfig(char *filename, char *options), в параметреfilenameэто путь к конфигурационному файлу,optionsИнформация о конфигурации, указанная параметрами для командной строки, например:

$ redis-server /config/redis/redis.conf -p 400

но/config/redis/redis.confбудет действовать какfilename,-p 400в видеoptions. При анализе файла конфигурации все содержимое файла конфигурации загружается в память через\nразделить, а затем#Строка в начале пропускается, что представляет собой комментарий.

Инициализировать внутренние переменные службы

Основная функция операции третьего шага состоит в том,initServer(void), в основном для инициализации некоторых клиентских связанных списков, баз данных, глобальных и общих переменных. Redis уменьшает частое выделение памяти за счет повторного использования общих переменных через функцииcreateSharedObjects(void)Для этого общие переменные хранятся в глобальной структуре.shared, в основном включают:

  • Строка для ответа, например:shared.ok,shared.err
  • Целое число от 0 до 10000, например:shared.integers[1]

Создать цикл событий eventLoop

Основная функция операции четвертого шага состоит в том,aeCreateEventLoop(int setsiee), создать цикл обработки событий eventLoop, то есть выделить необходимую для структуры память, инициализировать поля структуры и вызватьaeApiCreateФункция инициализирует структуру, соответствующую epoll.

Создайте сокет и начните слушать

Основная функция операции пятого шага состоит в том,listenToPort(int port, int *fds, int *count)используется в этой функцииserverпеременная, которая является глобальной переменной

// server.c
/* Global vars */
struct redisServer server; /* Server global state */

Инициализация этой переменной выполняется на третьем шаге, упомянутом выше.server.bindaddrВсе IP-адреса, записанные пользователем в конфигурационном файле, сохраняются. Пятый шаг — пройти по IP-адресу, настроенному пользователем, установить非阻塞розетка для мониторинга.

Создать событие файла и событие времени

Следующим шагом является создание файловых событий и временных событий.Redis абстрагирует события чтения и записи сокета в файловые события, то естьaeFileEvent, Выполнить по циклу события. Поэтому вам нужно создать соответствующее файловое событие для только что прослушанного сокета. Основной функцией обработки для создания файловых событий является

int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
        aeFileProc *proc, void *clientData)

Я понимаю, что использование неблокирующих свойств EPOLL, соответствующее связыванию обработчика для каждого события, когда происходит событие, вызов соответствующих функций обработки обрабатывается может быть. Например: обработчик событий для прослушиванияacceptTcpHandler, который реализует прием запроса на подключение к сокету и создание объекта клиента.

Событие времени инициируется функцией задачи по времени, а основная функция обработкиaeCreateTimeEvent, на самом деле есть только одно временное событие, и он соединяет несколько задач синхронизации через связанный список.

запустить цикл событий

Последний шаг — запустить цикл обработки событий, код основной функции обработки очень мал, давайте посмотрим

void aeMain(aeEventLoop *eventLoop) {
    eventLoop->stop = 0;
    while (!eventLoop->stop) {
        if (eventLoop->beforesleep != NULL)
            eventLoop->beforesleep(eventLoop);
        aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP);
    }
}

уведомлениеeventLoop->beforesleepФункция, которая выполняется перед каждым циклом событий, выполняет некоторые операции, не требующие больших затрат времени, такие как: операции, связанные с кластером, операции удаления просроченного ключа (здесь можно назвать быстрое удаление просроченного ключа), возврат ответов на команды на клиент и т.д. после этогоaeProcessEventsвыполнение функции, которая блокирует ожиданиеНекоторое времяОтвет на событие файла, если есть результат, выполнить соответствующую функцию обработки, а затем выполнить событие времени.

Суммировать

В этой статье объясняется, какие действия выполняет программа при запуске Redis: инициализация конфигураций и переменных, создание циклов событий, прослушивание сокетов, создание файловых событий и временных событий и многое другое. Я также узнал о роли глобальных переменных и общих переменных в Redis.Операция инициализации целых чисел от 0 до 10000 в общих переменных — это идея из небольшого пула целых чисел при изучении управления памятью Python ранее (пространство — это время).