Redis Plus уже здесь, взрыв производительности!

Источник: https://developer.aliyun.com/article/705239

1 Что такое KeyDB?

KeyDB — это высокопроизводительный форк Redis, ориентированный на многопоточность, эффективность использования памяти и высокую пропускную способность. В дополнение к многопоточности KeyDB также имеет функции, доступные только в Redis Enterprise, такие как Active Replication, поддержка FLASH-хранилища, а также некоторые функции, которые вообще недоступны, например прямое резервное копирование в AWS S3.

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

На том же оборудовании KeyDB может выполнять в два раза больше запросов в секунду, чем Redis, с задержкой на 60% ниже. Active-Replication упрощает отказоустойчивость горячего резерва, позволяя легко распределять записи между репликами и использовать простую балансировку нагрузки/отказоустойчивость на основе TCP. Высокая производительность KeyDB позволяет вам делать больше с меньшим количеством оборудования, снижая эксплуатационные расходы и сложность.

Ознакомьтесь с полными результатами тестов и информацией о настройке здесь:

https://docs.keydb.dev/blog/2019/10/07/blog-post/

2 Введите ключевую базу данных

Проект KeyDB является ответвлением форка redis. Как мы все знаем, Redis — это однопоточная система хранения kv-памяти, а KeyDB превращает Redis в многопоточность, когда он на 100% совместим с Redis API.

Git-адрес проекта:

https://github.com/JohnSully/KeyDB

В Интернете опубликовано относительно немного технических подробностей.Эта статья в основном резюмируется чтением исходного кода.Пожалуйста, поправьте меня, если есть какие-либо ошибки или упущения.

Порекомендуйте наиболее полное бесплатное руководство по Spring Boot с открытым исходным кодом:

https://github.com/javastacks/spring-boot-best-practice

многопоточная архитектура

резьбовая модель

KeyDB разбивает исходный основной поток Redis на основной поток и рабочий поток. Каждый рабочий поток — это поток ввода-вывода, отвечающий за прослушивание портов, прием запросов, чтение данных и анализ протоколов. как показано на рисунке:

KeyDB использует SO_REUSEPORTфункцию, позволяющую нескольким потокам связываться и прослушивать один и тот же порт.

Каждый рабочий поток связывает ядро ​​с процессором, считывает данные и использует SO_INCOMING_CPUфункцию, а также указывает процессор для получения данных.

После синтаксического анализа протокола каждый поток будет оперировать данными в памяти, а глобальная блокировка используется для управления многопоточным доступом к данным в памяти.

Основной поток на самом деле является рабочим потоком, включая рабочий контент рабочего потока, а также рабочий контент, который может выполнять только основной поток. Нижний индекс 0 в массиве рабочих потоков — это основной поток.

Основная работа основного потока заключается в реализации serverCron, в том числе:

  • Статистика обработки
  • Управление клиентскими ссылками
  • Изменение размера и перераспределение данных БД
  • иметь дело с aof
  • мастер репликации и резервная синхронизация
  • Задачи в кластерном режиме

управление ссылками

Все управление соединениями в Redis выполняется в одном потоке. В дизайне KeyDB каждый рабочий поток отвечает за набор ссылок, и все ссылки вставляются в список ссылок этого потока для обслуживания. Генерация, работа и уничтожение ссылок должны быть в одном потоке. Добавьте новое поле для каждой ссылки

int iel; /* the event loop index we're registered with */

Используется для указания того, к какому потоку принадлежит ссылка.

KeyDB поддерживает три ключевые структуры данных для управления ссылками:

  • clients_pending_write: связанный список для конкретного потока, поддерживающий очередь для синхронной отправки данных по клиентским ссылкам.
  • clients_pending_asyncwrite: связанный список для конкретного потока, который поддерживает очередь, которая асинхронно отправляет данные по клиентским ссылкам.
  • clients_to_close: глобальный связанный список, поддерживающий клиентские ссылки, которые необходимо закрыть асинхронно.

Он разделен на две очереди, синхронную и асинхронную, потому что у Redis есть некоторые API-интерфейсы связи.Например, pub/subпосле того, как pub должен отправить сообщения клиенту sub, поток, выполняемый pub, и поток клиента sub не совпадают. Чтобы справиться с этой ситуацией, KeyDB поддерживает данные, которые необходимо отправить клиентам, отличным от этого потока, в асинхронной очереди.

Логика синхронной отправки относительно проста, и вся она выполняется в этом потоке.На следующем рисунке показано, как отправлять данные клиенту синхронно.

Как упоминалось выше, создание соединения, получение данных, отправка данных и разрыв соединения должны выполняться в одном потоке. Асинхронная отправка включает взаимодействие между двумя потоками. KeyDB передает сообщения в два потока:

int fdCmdWrite; //写管道
int fdCmdRead; //读管道

AE_ASYNC_OP::CreateFileEventКогда локальному потоку необходимо отправлять данные асинхронно, сначала проверьте, принадлежит ли клиент к локальному потоку, а нелокальный поток получает идентификатор потока, специфичный для клиента, а затем управляет операцией отправки для выделенного потока и запрашивает добавление событие сокета записи. Выделенный поток добавляет соответствующий запрос к событию записи при обработке конвейерного сообщения, как показано на рисунке:

Некоторые запросы Redis на закрытие клиента не полностью закрываются в потоке, в котором находится ссылка, поэтому здесь поддерживается глобальный асинхронный список закрытия.

замок механизм

KeyDB реализует механизм блокировки, аналогичный спин-блокировке, называемый быстрой блокировкой.

Основные структуры данных fastlock:

struct ticket
{
    uint16_t m_active;  //解锁+1
    uint16_t m_avail;  //加锁+1
};
struct fastlock
{
    volatile struct ticket m_ticket;

    volatile int m_pidOwner; //当前解锁的线程id
    volatile int m_depth; //当前线程重复加锁的次数
};

Используйте атомарную операцию __atomic_load_2, __atomic_fetch_add, __atomic_compare_exchangeчтобы определить, можно ли получить блокировку путем сравнения m_active=m_avail. Fastlock предоставляет два способа получения замков:

  • try_lock : неудачное получение, возврат напрямую
  • lock : занятое ожидание, используйте после 1024 * 1024каждого занятого ожидания sched_yield, чтобы активно передать процессор, перейти в конец задачи процессора и дождаться выполнения.

В KeyDB try_lockэто будет объединено с событиями, чтобы избежать ожидания. Каждый клиент имеет монопольную блокировку. Перед чтением клиентских данных он сначала попытается заблокировать их. Если это не удастся, он выйдет. Поскольку данные не были прочитаны, их можно снова обработать в следующем цикле обработки событий epoll_wait.

Активная реплика

KeyDB реализует многоактивный механизм: каждая реплика может быть настроена на запись, но не только на чтение, и реплики могут синхронизировать данные друг с другом. Основные особенности:

  • Каждая реплика имеет флаг uuid для удаления кольцевой репликации.
  • Недавно добавленный API rreplay, инкрементная команда пакета в команду rreplay, добавление локального uuid
  • Ключ и значение, а также номер версии метки времени используются для проверки конфликта.Если такой же ключ существует локально, а номер версии метки времени больше, чем синхронизированные данные, новая запись завершится ошибкой. Текущая временная метка сдвигается на 20 бит влево, а последние 44 бита увеличиваются для получения номера версии временной метки ключа.

Справочная документация: https://docs.keydb.dev/docs/commands

Недавняя горячая рекомендация статьи:

1. Более 1000 вопросов и ответов на собеседовании по Java (последняя версия 2022 г.)

2. Гениально! Будут сопрограммы Java. . .

3. Учебник по Spring Boot 2.x, слишком полный!

4. Не заполняйте экран взрывами и взрывами, попробуйте режим декоратора, это элегантный способ! !

5. Последний выпуск «Руководства по разработке Java (издание Songshan)», загрузите быстро!

Хорошего настроения, не забудь поставить лайк + вперед!

おすすめ

転載: blog.csdn.net/youanyyou/article/details/130344496