2W слово! Подробное объяснение 20 классических вопросов интервью Redis! (ограниченный выпуск)

Java задняя часть
2W слово! Подробное объяснение 20 классических вопросов интервью Redis! (ограниченный выпуск)

предисловие

Привет всем, я маленький мальчик, который собирает улиток. Золотая девятка и Серебряная десятка скоро появятся. Я собрал 20 классических вопросов для интервью Redis. Надеюсь, они будут полезны всем.

1. Что такое Redis? Для чего он в основном используется?

Redis, полное английское имяRemote Dictionary Server(Remote Dictionary Service) — это база данных типа журнала с открытым исходным кодом, написанная на языке ANSI C, поддерживающая сеть, память и постоянство, а также предоставляющая API-интерфейсы на нескольких языках.

В отличие от баз данных MySQL, данные Redis хранятся в памяти. Его скорость чтения и записи очень высока, и он может обрабатывать более 100 000 операций чтения и записи в секунду. Поэтому редисШироко используется для кэширования, Кроме того, Redis также часто используется для распределенных блокировок. Кроме того, Redis поддерживает транзакции, постоянство, сценарии LUA, события, управляемые LRU, и различные схемы кластеризации.

2. Расскажите об основных типах структур данных Redis.

Большинство друзей знают, что Redis имеет следующие пять основных типов:

  • Строка (строка)
  • Хэш
  • Список
  • Набор
  • zset (отсортированный набор)

Он также имеет три специальных типа структуры данных.

  • Geospatial
  • Hyperloglog
  • Bitmap

2.1 Пять основных типов данных Redis

Строка (строка)

  • Введение: Строка – это самый простой тип структуры данных Redis. Она безопасна для двоичных файлов и может хранить изображения или сериализованные объекты. Максимальное значение – 512 М.
  • Простой пример использования:set key value,get keyЖдать
  • Сценарии применения: общие сессии, распределенные блокировки, счетчики, ограничение тока.
  • Существует 3 вида внутреннего кодирования,int(8字节长整型)/embstr(小于等于39字节字符串)/raw(大于39个字节字符串)

Строки в языке Cchar[]реализовано, в то время как Redis используетSDS (простая динамическая строка)Пакет, исходный код sds выглядит следующим образом:

struct sdshdr{
  unsigned int len; // 标记buf的长度
  unsigned int free; //标记buf中未使用的元素个数
  char buf[]; // 存放元素的坑
}

Структурная схема SDS выглядит следующим образом:

Почему Redis выбралSDSструктура, в то время как родной язык C char[]Разве это не ароматно?

Например, в SDS длина строки может быть получена с временной сложностью O(1), в то время как строка C должна пройти всю строку, а временная сложность составляет O(n).

Хэш

  • Введение. В Redis тип хэша означает, что v (значение) само по себе является структурой пары ключ-значение (k-v).
  • Простой пример использования:hset key field value,hget key field
  • Внутренняя кодировка:ziplist(压缩列表),hashtable(哈希表)
  • Сценарий применения: кеширование информации о пользователе и т. д.
  • будь осторожен: Если вы используете hgetall для разработки и есть много хеш-элементов, это может привести к блокировке Redis.Вы можете использовать hscan. И если вы получаете только часть поля, рекомендуется использовать hmget.

Сравнение строковых и хэш-типов выглядит следующим образом:

Список

  • Введение. Тип списка используется для хранения нескольких упорядоченных строк, а список может хранить до 2^32-1 элементов.
  • Простой практический пример: lpush key value [value ...],lrange key start end
  • Внутренняя кодировка: ziplist (сжатый список), linkedlist (связанный список)
  • Сценарии применения: очередь сообщений, список статей,

Картинка для понимания вставки и всплывающих окон типа списка:

Список сценариев применения относится к следующему:

  • lpush+lpop=Стек (стек)
  • lpush+rpop=Очередь (очередь)
  • lpsh+ltrim=Коллекция с ограничениями
  • lpush+brpop=Message Queue (очередь сообщений)

Набор

  • Введение. Тип set ​​также используется для хранения нескольких строковых элементов, но не допускает дублирования элементов.
  • Простой пример использования:sadd key element [element ...],smembers key
  • Внутренняя кодировка:intset(整数集合),hashtable(哈希表)
  • будь осторожен: smembers, lrange и hgetall — тяжелые команды.Если элементов слишком много, есть вероятность блокировки Redis, для завершения можно использовать sscan.
  • Сценарии применения: Пользовательские теги, генерация лотереи случайных чисел, социальные нужды.

отсортированный набор (zset)

  • Введение: отсортированная коллекция строк и элементы не могут повторяться одновременно.
  • Пример простого формата:zadd key score member [score member ...],zrank key member
  • Низкоуровневое внутреннее кодирование:ziplist(压缩列表),skiplist(跳跃表)
  • Сценарии применения: таблицы лидеров, социальные потребности (например, лайки пользователей).

2.2 Три специальных типа данных Redis

  • Гео: запущен Redis3.2, позиционирование по географическому местоположению, используется для хранения информации о географическом местоположении и работы с сохраненной информацией.
  • HyperLogLog: структура данных, используемая для статистических алгоритмов кардинальности, таких как статистический веб-сайт UV.
  • Растровые изображения: используйте бит для отображения состояния элемента.В Redis его нижний слой реализован на основе типа строки.Растровые изображения можно преобразовать в массив битов.

3. Почему Redis такой быстрый?

Redis为什么这么快

3.1 Реализация на основе памяти

Все мы знаем, что чтение и запись в память намного быстрее, чем чтение и запись на диск.Redis, база данных, реализованная на основе хранилища в памяти, экономит потребление дискового ввода-вывода по сравнению с базой данных MySQL, где данные хранятся на диске.

3.2 Эффективные структуры данных

Мы знаем, что индекс Mysql выбирает структуру данных дерева B+ для повышения эффективности. На самом деле, разумная структура данных может сделать ваше приложение/программу быстрее. Давайте сначала посмотрим на структуру данных и схему внутреннего кодирования Redis:

Простая динамическая строка SDS

  • Обработка длины строки: Redis получает длину строки, а временная сложность — O(1), тогда как в языке C ее нужно пройти с самого начала, а сложность — O(n);
  • Предварительное выделение пространства: чем чаще изменяется строка, тем чаще выделяется память, что снижает производительность, а модификация SDS и расширение пространства дополнительно выделяют неиспользуемое пространство для снижения потерь производительности.
  • Освобождение инертного пространства: когда SDS укорачивается, он не освобождает избыточное пространство памяти, а освобождает запись избыточного пространства.Если есть последующие изменения, пространство, записанное в свободном пространстве, непосредственно используется для уменьшения выделения.
  • Двоичная безопасность: Redis может хранить некоторые двоичные данные.В языке C строка заканчивается, когда она встречает '\0', а в SDS конец строки помечается атрибутом len.

Словарь

Redis — это база данных K-V в памяти, а все значения ключей хранятся в словарях. Словарь — это хеш-таблица, такая как HashMap, и соответствующее значение может быть получено напрямую через ключ. И характеристики хеш-таблицы, соответствующие значения могут быть получены за O(1) временной сложности.

стол для прыжков

  • Таблица переходов — это уникальная для Redis структура данных, основанная на связном списке с добавлением многоуровневых индексов для повышения эффективности поиска.
  • Таблица пропуска поддерживает поиск среднего O(logN), наихудшего O(N) узла, а также может группировать узлы с помощью последовательных операций.

3.3 Разумное кодирование данных

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

  • Строка: Если хранится число, оно кодируется в типе int; если хранится нецифровая строка, меньшая или равная 39 байтам, это embstr; если она больше 39 байт, это исходное кодирование.
  • Список: если количество элементов в списке меньше 512, значение каждого элемента списка меньше 64 байт (по умолчанию), используйте кодировку ziplist, в противном случае используйте кодировку связанного списка.
  • Хэш: количество элементов типа хэш меньше 512. Если все значения меньше 64 байт, используйте кодировку ziplist, в противном случае используйте кодировку хэш-таблицы.
  • Набор: если все элементы в наборе являются целыми числами, а количество элементов меньше 512, используйте кодировку intset, в противном случае используйте кодировку хэш-таблицы.
  • Zset: когда количество элементов в упорядоченном наборе меньше 128, а значение каждого элемента меньше 64 байт, используйте кодировку ziplist, в противном случае используйте кодировку skiplist (таблицу пропуска).

3.4 Разумная многопоточная модель

Мультиплексирование ввода/вывода

I/O 多路复用

Технология множественного мультиплексирования ввода-вывода позволяет одному потоку эффективно обрабатывать несколько запросов на подключение, а Redis использует epoll как реализацию технологии мультиплексирования ввода-вывода. Кроме того, собственная модель обработки событий Redis преобразует подключения, операции чтения и записи и закрытия в epoll в события, не тратя слишком много времени на сетевой ввод-вывод.

Что такое мультиплексирование ввода/вывода?

  • Ввод/вывод: сетевой ввод/вывод
  • Мультиплекс: Несколько сетевых подключений
  • Повторное использование: повторное использование одного и того же потока.
  • Мультиплексирование ввода-вывода на самом деле является синхронной моделью ввода-вывода, которая позволяет потоку отслеживать несколько дескрипторов файлов; как только дескриптор файла готов, он может уведомить приложение о выполнении соответствующих операций чтения и записи; и когда дескриптор файла не готов, он блокируется. приложение и передать процессор.

однопоточная модель

  • Redis — это однопоточная модель, а однопоточная модель позволяет избежать ненужного переключения контекста ЦП и использования конкурирующих блокировок. Поскольку это один поток, если команда выполняется слишком долго (например, команда hgetall), это вызовет блокировку. Redis — это база данных для сценариев быстрого выполнения. , поэтому будьте осторожны при использовании таких команд, как smembers, lrange, hgetall и т. д.
  • В Redis 6.0 реализовано ускорение многопоточности, а выполнение команд и памяти по-прежнему выполняется в одном потоке.

3.5 Механизм виртуальной памяти

Redis напрямую сам строит механизм ВМ, и он не будет вызывать системные функции для обработки, как общая система, и будет тратить определенное количество времени на перемещение и запрос.

Каков механизм виртуальной памяти Redis?

Механизм виртуальной памяти заключается в временном обмене редко используемыми данными (холодные данные) из памяти на диск, тем самым освобождая ценное пространство памяти для других данных, к которым необходимо получить доступ (горячие данные). С помощью функции VM горячие и холодные данные могут быть разделены, так что горячие данные остаются в памяти, а холодные данные сохраняются на диск. Таким образом можно избежать проблемы снижения скорости доступа из-за нехватки памяти.

4. Что такое разбивка кеша, проникновение в кеш и лавина кеша?

4.1 Проблема проникновения в кэш

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

读取缓存

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

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

Проникновение в кэш обычно вызывается следующими ситуациями:

  • бизнес необоснованный дизайн, например, у большинства пользователей нет опекуна, но каждый ваш запрос кэшируется, и для проверки наличия опекуна запрашивается идентификатор пользователя.
  • Ошибки ведения бизнеса/эксплуатации и обслуживания/развития, такие как кэш и данные базы данных, были удалены по ошибке.
  • Хакерская атака с незаконным запросом, например, хакеры намеренно фабрикуют большое количество незаконных запросов на чтение несуществующих бизнес-данных.

Как избежать проникновения в кеш?Обычно есть три метода.

  • 1. Если это недопустимый запрос, мы проверяем параметры на входе в API и фильтруем недопустимые значения.
  • 2. Если база данных запроса пуста, мы можем установить пустое значение для кеша или значение по умолчанию. Однако, если приходит запрос на запись, кеш необходимо обновить, чтобы обеспечить согласованность кеша, в то же время для кеша в конце устанавливается соответствующее время истечения срока действия. (Обычно используется в бизнесе, прост и эффективен)
  • 3. Используйте фильтр Блума, чтобы быстро определить, существуют ли данные. То есть, когда приходит запрос-запрос, он сначала рассудит, существует ли значение через фильтр Блума, а затем продолжит проверку, существует ли оно.

Принцип фильтра Блума: он состоит из массива растровых изображений с начальным значением 0 и N хеш-функций. Один выполняет N хеш-алгоритмов для ключа, чтобы получить N значений, хэширует N значений в битовом массиве и устанавливает их в 1, а затем проверяет, все ли эти конкретные позиции равны 1, затем фильтрация Блума Устройство определяет, что ключ существует .

4.2 Проблема запуска кеша на снегу

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

  • Кэш Xueben обычно вызывается одновременным истечением срока действия большого объема данных, поэтому его можно решить, установив время истечения равномерно, то есть сделав время истечения относительно дискретным. Например, используется большее фиксированное значение + меньшее случайное значение, 5 часов + от 0 до 1800 секунд.
  • Время простоя Redis из-за сбоя также может привести к запуску кэша. Для этого требуется создание кластера высокой доступности Redis.

4.3 Проблема с поломкой кеша

Разбивка кеша:Это относится ко времени, когда срок действия горячего ключа истекает в определенный момент времени, и в этот момент времени существует большое количество одновременных запросов на этот ключ, поэтому большое количество запросов попадает в базу данных.

Разбивка кеша выглядит немного похоже. На самом деле разница между ними заключается в том, что запуск кеша означает, что нагрузка на базу данных слишком высока или даже выключает машину. Разбивка кеша — это просто большое количество одновременных запросов к уровню базы данных БД. . Можно считать, что разбивка является подмножеством кэша Xueben. В некоторых статьях считается, что разница между ними заключается в том, что разница заключается в поломке кеша горячих клавиш, тогда как Сюэ Бен — это много ключей.

Есть два решения:

  • 1. Используйте схему блокировки мьютекса. В случае сбоя кеша вместо немедленной загрузки данных базы данных используйте некоторые команды атомарных операций с успешным возвратом, например (setnx Redis), для работы, а в случае успеха загрузите данные базы данных базы данных и установите кеш. В противном случае повторите попытку получения кеша.
  • 2. «Никогда не истекает», что означает, что время истечения срока действия не установлено, но когда срок действия данных точки доступа подходит к концу, асинхронный поток обновляет и устанавливает время истечения срока действия.

5. Что такое проблема с горячими клавишами и как решить проблему с горячими клавишами

Что такое горячая клавиша?? В Redis мы называем ключи с высокой частотой доступа ключами хотспотов.

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

А как генерируется горячий ключ? Есть две основные причины:

  • Данные, потребляемые пользователями, намного больше, чем производимые данные, такие как всплески, горячие новости и другие сценарии, в которых больше операций чтения и меньше операций записи.
  • Осколки запросов сконцентрированы, что превышает производительность одного сервера Redi.Например, если фиксированный ключ имени и хеш попадают на один и тот же сервер, мгновенный объем доступа будет чрезвычайно большим, превысив узкое место машины, что приведет к горячему ключу проблема.

Итак, в повседневной разработке, как определить горячие клавиши?

  • Определение горячих клавиш на основе опыта;
  • отчет о статистике клиентов;
  • Отчет уровня сервисного агента

Как решить проблему с горячим ключом?

  • Расширение кластера Redis: увеличьте количество реплик шардов, чтобы сбалансировать трафик чтения;
  • Распределить горячие клавиши по разным серверам;
  • Используйте кеш второго уровня, то есть локальный кеш JVM, чтобы уменьшить количество запросов на чтение Redis.

6. Стратегия истечения срока действия Redis и стратегия ликвидации памяти

6.1 Политика истечения срока действия Redis

мы вset key, вы можете установить для него время истечения срока действия, напримерexpire key 60. Укажите, что срок действия этого ключа истекает через 60 сек. Как Redis обрабатывает его после 60 сек.? Давайте сначала представим несколько стратегий экспирации:

истечение срока действия по времени

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

ленивый выдох

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

Периодически истекает

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

Словарь expires сохранит данные о времени истечения срока действия всех ключей с установленным временем истечения срока действия, где ключ — это указатель на ключ в пространстве ключей, а значение — это время истечения срока действия, представленное отметкой времени UNIX с точностью до миллисекунды ключа. Пространство ключей относится ко всем ключам, хранящимся в этом кластере Redis.

Оба используются в RedisЛенивое истечение и периодическое истечениеДве стратегии экспирации.

  • Предполагая, что Redis в настоящее время хранит 300 000 ключей и установил время истечения срока действия, если вы будете проверять все ключи каждые 100 мс, загрузка ЦП будет особенно высокой, и в конечном итоге он может зависнуть.
  • Поэтому Redis принимает периодическое истечение срока действия и случайным образом выбирает определенное количество ключей каждые 100 мс для проверки и удаления.
  • Однако в итоге может остаться много ключей с истекшим сроком действия, которые не были удалены. В настоящее время Redis использует ленивое удаление. Когда вы получите ключ, Redis проверит его.Если для ключа установлено время истечения срока действия, и он истек, он будет удален в это время.

Но да, если при обычном удалении пропущено много ключей с истекшим сроком действия, то ленивое удаление не выполняется. В памяти будет скапливаться много просроченных ключей, что напрямую приведет к взрыву памяти. Или иногда объем бизнеса увеличился, ключ Redis используется часто, памяти явно недостаточно, а брат по эксплуатации и обслуживанию также забыл увеличить память. Redis так зависает? Не буду! Redis защищает себя с помощью 8 стратегий устранения памяти~

6.2 Стратегия ликвидации памяти Redis

  • volatile-lru: когда памяти недостаточно для размещения вновь записанных данных, используйте алгоритм LRU (наименее недавно использовавшийся) для исключения из ключа с установленным временем истечения;
  • allkeys-lru: используйте алгоритм LRU (наименее недавно использовавшийся) для удаления всех ключей, когда памяти недостаточно для вновь записанных данных.
  • volatile-lfu: Добавлено в версии 4.0, когда памяти не хватает для размещения вновь записанных данных, используется алгоритм LFU для удаления ключей в ключах с истекшим сроком действия.
  • allkeys-lfu: Добавлено в версии 4.0, когда памяти не хватает для размещения вновь записываемых данных, используется алгоритм LFU для исключения всех ключей;
  • volatile-random: когда памяти недостаточно для размещения вновь записанных данных, данные удаляются из ключа случайным образом с установленным временем истечения;
  • allkeys-random: случайным образом удалять данные со всех ключей, когда памяти недостаточно для вновь записанных данных.
  • volatile-ttl: когда памяти недостаточно для размещения вновь записанных данных, в ключе с установленным временем истечения оно будет устранено в соответствии со временем истечения срока действия, а ранее истекшее будет устранено первым;
  • noeviction: политика по умолчанию, когда памяти недостаточно для размещения вновь записанных данных, новая операция записи сообщит об ошибке.

7. Расскажите об общих сценариях применения Redis

  • тайник
  • Таблица лидеров
  • Приложение счетчика
  • Общий сеанс
  • Распределенная блокировка
  • Социальная сеть
  • очередь сообщений
  • битовые манипуляции

7.1 Кэш

Когда мы упоминаем Redis, мы, естественно, подразумеваем кеширование: большие и средние веб-сайты в стране и за границей неотделимы от кеширования. Разумное использование кэша, например кэширование горячих данных, может не только повысить скорость доступа к веб-сайту, но и снизить нагрузку на БД базы данных. Более того, по сравнению с memcached, Redis также предоставляет богатые структуры данных и предоставляет более надежные механизмы сохранения, такие как RDB и AOF.

7.2 Таблица лидеров

В современных интернет-приложениях существуют различные рейтинги, такие как ежемесячные рейтинги продаж веб-сайтов электронной коммерции, рейтинги подарков социальных приложений, рейтинги голосования небольших программ и так далее. предоставлено РедисомzsetТип данных позволяет использовать эти сложные списки лидеров.

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

  • 1. Пользователь Jay загружает видео, получает 6 лайков и может быть фиолетовым:
zadd user:ranking:2021-03-03 Jay 3
    1. Через некоторое время, чтобы получить еще один лайк, можно сделать так:
zincrby user:ranking:2021-03-03 Jay 1
    1. Если пользователь John обманывает, пользователя необходимо удалить:
zrem user:ranking:2021-03-03 John
    1. Показать 3 пользователей с наибольшим количеством лайков
zrevrangebyrank user:ranking:2021-03-03 0 2

7.3 Применение счетчика

Крупные веб-сайты и приложения APP часто нуждаются в функциях счетчика, таких как количество воспроизведений коротких видео и количество просмотров веб-сайтов электронной коммерции. Количество воспроизведений и представлений обычно требует реального времени, и каждое воспроизведение и представление должны увеличиваться на 1. Если объем параллелизма велик, это будет проблемой для производительности традиционных реляционных данных. Redis, естественно, поддерживает функцию подсчета, и производительность подсчета также очень высока.Можно сказать, что это важный выбор для системы счетчиков.

7.4 Общий сеанс

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

7.5 Распределенные блокировки

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

  • Заблокирован синхронизированным или рентрангантом на местном уровне нет.
  • Если объем параллелизма невелик, можно без проблем использовать пессимистическую блокировку и оптимистическую блокировку базы данных.
  • Однако в случае высокого параллелизма использование блокировок базы данных для управления одновременным доступом к ресурсам повлияет на производительность базы данных.
  • На самом деле распределенные блокировки можно реализовать с помощью setnx Redis.

7.6 Социальные сети

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

7.7 Очередь сообщений

Очередь сообщений является обязательным промежуточным программным обеспечением для крупных веб-сайтов, таких как ActiveMQ, RabbitMQ, Kafka и другим популярным промежуточным программным обеспечением очереди сообщений.Оно в основном используется для разделения бизнеса, сокращения пикового трафика и асинхронной обработки служб с низким уровнем реального времени. Redis предоставляет функции публикации/подписки и блокировки очереди, которые могут реализовать простую систему очереди сообщений. Кроме того, это нельзя сравнить с профессиональным промежуточным ПО для сообщений.

7.8 Битовая операция

Он используется в сценариях с объемом данных в сотни миллионов, таких как системная регистрация сотен миллионов пользователей, статистика по количеству повторных входов в систему, находится ли пользователь в сети и т. д. У Tencent 1 миллиард пользователей, как я могу проверить, находится ли пользователь в сети за несколько миллисекунд? Не говорите создать ключ для каждого пользователя, а потом записывать их по одному (можете посчитать требуемую память, это будет ужасно, да и подобных требований много. Тут надо оперировать на месте - используйте setbit, команды getbit, bitcount.Принцип такой: построить достаточно длинный массив в redis, каждый элемент массива может иметь только два значения 0 и 1, а затем индекс индекса этого массива используется для представления идентификатора пользователя ( должно быть числом), то очевидно, что этот Большой массив длиной в сотни миллионов может построить систему памяти с индексами и значениями элементов (0 и 1).

8. Каковы механизмы сохранения Redis? Расскажите о преимуществах и недостатках

Redis — это нереляционная база данных K-V, основанная на памяти, так как она основана на памяти, и если сервер Redis зависнет, данные будут потеряны. Во избежание потери данных Redis предоставляетУпорство, который сохраняет данные на диск.

Redis предоставляетРБД и АОФСуществует два механизма сохранения.Постоянный процесс загрузки файла выглядит следующим образом:

8.1 RDB

RDB, который должен сохранять данные памяти на диск в виде моментальных снимков.

Что такое снимок, его можно понять так, сфотографировать данные в текущий момент, а потом сохранить.

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

Преимущества RDB

  • Подходит для крупномасштабных сценариев восстановления данных, таких как резервное копирование, полная репликация и т. д.

Недостатки РБД

  • Невозможно добиться постоянства в реальном времени/постоянства второго уровня.
  • Существует проблема совместимости с форматом RDB между новой и старой версиями.

AOF

AOF (добавить только файл)Постоянство, запись каждой операции записи в виде журнала, добавление ее в файл и повторное выполнение команды в файле AOF для восстановления данных при перезапуске. В основном это решает проблему сохранения данных в реальном времени. По умолчанию он отключен.

Рабочий процесс AOF выглядит следующим образом:

Преимущества АОФ

  • Повышение согласованности и целостности данных

Недостатки АОФ

  • Чем больше записей AOF, тем больше размер файла и медленнее восстановление данных.

9. Как добиться высокой доступности Redis?

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

9.1 Ведущий-ведомый режим

В режиме «ведущий-ведомый» Redis развертывает несколько машин, при этом главный узел отвечает за операции чтения и записи, а подчиненный узел отвечает только за операции чтения. Данные ведомого узла поступают от ведущего узла, и принцип реализации таков.Механизм репликации master-slave

Репликация master-slave включает полную репликацию и добавочную репликацию. Как правило, когда ведомое устройство начинает подключаться к ведущему в первый раз или считает это первым соединением, оно используетполная копия, процесс полного копирования выглядит следующим образом:

  • 1. Ведомое устройство отправляет команду синхронизации ведущему устройству.
  • 2. После того как мастер получает команду SYNC, он выполняет команду bgsave для создания полного файла RDB.
  • 3. Мастер использует буфер для записи всех команд записи во время создания моментального снимка RDB.
  • 4. После того, как мастер выполняет bgsave, он отправляет файл моментального снимка RDB всем ведомым устройствам.
  • 5. После того, как подчиненное устройство получит файл снимка RDB, оно загрузит и проанализирует полученный снимок.
  • 6. Мастер использует буфер для записи всех команд записи, сгенерированных во время синхронизации RDB.
  • 7. После отправки ведущего снапшота он начинает посылать команду записи в буфер ведомому;
  • 8.salve принимает командный запрос и выполняет команду записи из главного буфера

После версии 2.8 Redis он использовалсяpsync вместо синхронизации, так как команда синхронизации потребляет системные ресурсы, psync более эффективен.

После того, как ведомое устройство полностью синхронизируется с ведущим устройством, если данные на ведущем устройстве снова обновятся, оно сработает.Инкрементная репликация.

Когда на главном узле происходит увеличение или уменьшение данных, он будет активирован.replicationFeedSalves()функция, каждая последующая команда, вызываемая на главном узле, будет использоватьreplicationFeedSlaves()для синхронизации с подчиненным узлом. Перед выполнением этой функции главный узел оценит, имеет ли команда, выполняемая пользователем, обновление данных, если есть обновление данных, а подчиненный узел не пуст, эта функция будет выполнена. Что делает эта функция:Отправить команду, выполненную пользователем, на все подчиненные узлы, пусть подчиненный узел выполняется. Процесс выглядит следующим образом:

9.2 Сторожевой режим

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

Режим стража, система Sentinel, состоящая из одного или нескольких экземпляров Sentinel, она может отслеживать все главные и подчиненные узлы Redis, и когда контролируемый главный узел переходит в автономное состояние,Автоматически обновлять подчиненный узел на автономном главном сервере до нового главного узла.. Однако если дозорный процесс отслеживает узел Redis, могут возникнуть проблемы (проблема с одной точкой), поэтому для мониторинга узлов Redis можно использовать несколько дозорных, и мониторинг также будет выполняться между каждым дозорным.

Sentinel哨兵模式

Проще говоря, дозорный режим имеет три функции:

  • Отправьте команду и подождите, пока сервер Redis (включая главный сервер и подчиненный сервер) вернется, чтобы отслеживать его рабочее состояние;
  • Когда часовой обнаруживает, что главный узел не работает, он автоматически переключает подчиненный узел на главный узел, а затем уведомляет другие подчиненные узлы через режим публикации-подписки, модифицирует файл конфигурации и позволяет им переключить узел;
  • Sentinels также будут контролировать друг друга для достижения высокой доступности.

Каков процесс аварийного переключения?

Предполагая, что основной сервер не работает, Sentinel 1 обнаруживает этот результат первым, и система не сразу выполняет процесс failover, просто Sentinel 1 субъективно считает, что основной сервер недоступен, и это явление становится субъективным офлайн. Когда следующие дозорные также обнаружат, что основной сервер недоступен, и число достигнет определенного значения, между дозорными будет проведено голосование, и результат голосования будет инициирован дозорным для выполнения операции аварийного переключения. После успешного переключения каждый дозорный переключает хост с сервера, за которым они наблюдают, с помощью модели публикации-подписки Этот процесс называется объективным автономным режимом. Таким образом, все прозрачно для клиента.

Часовые работают следующим образом:

  1. Каждый Sentinel отправляет команду PING главному, подчиненному и другим экземплярам Sentinel, о которых он знает, один раз в секунду.
  2. Если экземпляр превышает значение, указанное параметром down-after-milliseconds с момента последнего действительного ответа на команду PING, экземпляр будет помечен Sentinel как субъективно отключенный.
  3. Если Мастер помечен как субъективно отключенный, все Стражи, наблюдающие за Мастером, должны подтверждать, что Мастер действительно перешел в субъективное автономное состояние с частотой один раз в секунду.
  4. Когда достаточное количество Стражей (большее или равное значению, указанному в файле конфигурации) подтвердит, что Мастер действительно перешел в субъективное автономное состояние в течение указанного диапазона времени, Мастер будет помечен как объективный в автономном режиме.
  5. Как правило, каждый Sentinel будет отправлять команды INFO всем ведущим и ведомым устройствам, о которых он знает, каждые 10 секунд.
  6. Когда Мастер помечен Sentinel как объективно отключенный, частота отправки команд INFO всем ведомым устройствам отключенного Мастера от Sentinel будет изменена с одного раза каждые 10 секунд на один раз в секунду.
  7. Если количество Стражей недостаточно, чтобы согласиться с тем, что Мастер был в автономном режиме, объективный статус Мастера в автономном режиме будет удален; если Мастер возвращает действительный ответ на команду PING Sentinel, субъективный статус Мастера в автономном режиме будет удален.

9.3 Кластерный режим кластера

Режим Sentinel основан на режиме master-slave, который реализует разделение чтения и записи, а также может автоматически переключаться, а доступность системы выше. Однако данные, хранящиеся на каждом узле, одинаковы, что приводит к трате памяти и затруднению расширения в сети. Так появился кластер Cluster, который был добавлен в Redis3.0 и реализовал возможности Redis.Распределенное хранилище. Шардить данные, т.е.На каждом узле Redis хранится разный контент., чтобы решить проблему онлайн-экспансии. А также предоставляет возможности репликации и аварийного переключения.

Связь кластерных узлов кластера

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

Кластер Redis Cluster обменивается данными через протокол Gossip. Узлы постоянно обмениваются информацией. Обмен информацией включает в себя сбой узла, присоединение нового узла, информацию об изменении главного и подчиненного узлов, информацию о слотах и ​​т. д. Обычно используемые сплетни делятся на четыре типа: пинг, понг, встреча, фейл.

  • сообщение о встрече: уведомляет новый узел о присоединении. Отправитель сообщения уведомляет получателя о присоединении к текущему кластеру.После нормального завершения обмена сообщениями о встрече принимающий узел присоединится к кластеру и будет периодически обмениваться сообщениями ping и pong.
  • Сообщение проверки связи: сообщение, которым чаще всего обмениваются в кластере.Каждый узел в кластере отправляет сообщения проверки связи нескольким другим узлам каждую секунду, чтобы определить, находятся ли узлы в сети, и обмениваются информацией о состоянии друг с другом.
  • сообщение pong: когда получено сообщение ping and meet, оно ответит отправителю в качестве ответного сообщения, чтобы подтвердить нормальную передачу сообщения. Сообщение pong инкапсулирует внутри свои собственные данные о состоянии. Узлы также могут транслировать свои собственные сообщения pong в кластер, чтобы уведомить весь кластер о необходимости обновления своего состояния.
  • сообщение об ошибке: когда узел определяет, что другой узел в кластере находится в автономном режиме, он передает кластеру сообщение об ошибке, а другие узлы обновляют соответствующий узел до автономного состояния после получения сообщения об ошибке.

В частности, каждый узелКластерная шинаобщаться с другими узлами. При общении используйте специальный номер порта, то есть номер порта внешней службы плюс 10000. Например, если номер порта узла — 6379, то номер порта, через который он взаимодействует с другими узлами, — 16379. Для связи между узлами используется специальный бинарный протокол.

Алгоритм слота Hash Slot

Поскольку это распределенное хранилище, распределенный алгоритм, используемый кластером Cluster,Согласованный хэшЧто ж? Нет, ноАлгоритм слота Hash Slot.

алгоритм слотаВся база данных разбита на 16384 слота (слота), и каждая пара ключ-значение, которая входит в Redis, хешируется по ключу и назначается одному из 16384 слотов. Используемая хеш-карта также относительно проста: используется алгоритм CRC16 для вычисления 16-битного значения, а затем по модулю 16384. Каждый ключ в базе данных принадлежит одному из этих 16384 слотов, и каждый узел в кластере может обрабатывать эти 16384 слота.

Каждый узел в кластере отвечает за часть хеш-слотов, например, в текущем кластере есть узлы A, B и C, а количество хэш-слотов на каждом узле = 16384/3, тогда получается:

  • Узел A отвечает за хеш-слоты 0~5460.
  • Узел B отвечает за хеш-слоты 5461~10922.
  • Узел C отвечает за хеш-слоты 10923~16383.

Кластерный кластер Redis

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

Поэтому для обеспечения высокой доступности кластер Cluster вводит репликацию master-slave, где главный узел соответствует одному или нескольким подчиненным узлам. Когда другие главные узлы пингуют главный узел A, если более половины главных узлов взаимодействуют с A сверхурочно, то главный узел A считается отключенным. Если главный узел выходит из строя, подчиненный узел включается.

На каждом узле Redis есть две вещи, одна — слот, и ее диапазон значений равен 0.16383. Другой — кластер, который можно понимать как подключаемый модуль управления кластером. Когда ключ, к которому мы обращаемся, прибудет, Redis получит 16-битное значение в соответствии с алгоритмом CRC16, а затем возьмет результат по модулю 16384. Каждому ключу Jiangzi будет соответствовать число 0Хэш-слот между 16383, с помощью этого значения найдите узел, соответствующий соответствующему слоту, а затем автоматически перейдите к соответствующему узлу для операций доступа.

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

отказоустойчивость

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

Кластер Redis реализует обнаружение сбоев с помощью сообщений ping/pong. Эта среда включаетСубъективный нижестоящий и объективный нижестоящий.

Субъективный офлайн:Узел считает, что другой узел недоступен, то есть автономное состояние.Это состояние не является окончательным суждением о неисправности, а только представляет мнение одного узла, и могут быть ошибочные суждения.

主观下线

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

  • Если узел A отмечает узел B как субъективно отключенный, через некоторое время узел A отправляет состояние узла B другим узлам через сообщение.Когда узел C получает сообщение и анализирует тело сообщения, если он находит состояние pfail для узел B, который запустит целевой автономный процесс;
  • Когда главный узел переходит в автономный режим, кластер Redis Cluster голосует за главный узел, удерживающий слот, чтобы увидеть, достигает ли количество голосов половины.объективно офлайнгосударство.

Процесс выглядит следующим образом:

客观下线

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

  • Проверка приемлемости: проверьте, имеет ли подчиненный узел право заменить отказавший главный узел.
  • Время подготовки к выборам: после прохождения проверки приемлемости обновите время выборов, которое вызывает сбой.
  • Инициировать выборы: когда наступит время выбора по ошибке, проведите выборы.
  • Предвыборное голосование: только те, у кого есть слотыглавный узелЕсть только голоса, и достаточное количество голосов (более половины) собирается с узла, что приводит к срабатываниюЗаменить основную операцию

10. Использовали ли вы распределенную блокировку Redis? На какие моменты обратить внимание?

Распределенная блокировка, представляет собой реализацию блокировки, которая контролирует общий доступ различных процессов в распределенной системе к общим ресурсам. Распределенные блокировки необходимы для бизнес-сценариев, таких как заказ за секунды, захват красных конвертов и т. д. Redis часто используется в качестве распределенной блокировки в нашем проекте.

Было выбрано несколько способов реализации распределенной блокировки Redis, давайте обсудим их и посмотрим, есть ли проблема.

  • Команда setnx+expire пишется отдельно
  • setnx + value value - время истечения срока действия
  • Команда расширения SET (Set EX PX NX)
  • установить ex px nx + проверить уникальное случайное значение, затем удалить

10.1 Команда setnx+expire пишется отдельно

if(jedis.setnx(key,lock_value) == 1){ //加锁
    expire(key,100); //设置过期时间
    try {
        do something  //业务请求
    }catch(){
  }
  finally {
       jedis.del(key); //释放锁
    }
}

Если законченоsetnxЕсли процесс дает сбой или его необходимо перезапустить для обслуживания, когда он собирается выполнить expire, чтобы установить время истечения срока действия, блокировка будет «бессмертной».Никакой другой поток никогда не сможет получить блокировкуЛах, так распределены замкине можетЭто достигается.

10.2 setnx + значение value - это время истечения срока действия

long expires = System.currentTimeMillis() + expireTime; //系统时间+设置的过期时间
String expiresStr = String.valueOf(expires);

// 如果当前锁不存在,返回加锁成功
if (jedis.setnx(key, expiresStr) == 1) {
        return true;
} 
// 如果锁已经存在,获取锁的过期时间
String currentValueStr = jedis.get(key);

// 如果获取到的过期时间,小于系统当前时间,表示已经过期
if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {

     // 锁已过期,获取上一个锁的过期时间,并设置现在锁的过期时间(不了解redis的getSet命令的小伙伴,可以去官网看下哈)
    String oldValueStr = jedis.getSet(key_resource_id, expiresStr);
    
    if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
         // 考虑多线程并发的情况,只有一个线程的设置值和当前值相同,它才可以加锁
         return true;
    }
}
        
//其他情况,均返回加锁失败
return false;
}

Автор видел, что некоторые партнеры-разработчики реализуют таким образом распределенные блокировки, но эта схема также имеет этинедостаток:

  • Время истечения генерируется самим клиентом, в распределенной среде время каждого клиента должно быть синхронизировано.
  • Не сохраняет уникальную личность владельца и может быть разблокирован/разблокирован другими клиентами.
  • Когда срок блокировки истекает, несколько одновременных клиентов запрашивают одновременно, и все они выполняются.jedis.getSet(), в конце концов, только один клиент может успешно заблокироваться, но время истечения срока действия блокировки клиента может быть перезаписано другими клиентами.

10.3: Расширенная команда для set (set ex px nx) (обратите внимание на возможные проблемы)

if(jedis.set(key, lock_value, "NX", "EX", 100s) == 1){ //加锁
    try {
        do something  //业务处理
    }catch(){
  }
  finally {
       jedis.del(key); //释放锁
    }
}

Это решение может иметь следующие проблемы:

  • Блокировка просрочена и снята, а дело не выполнено.
  • Блокировка была случайно удалена другим потоком.

10.4 установить ex px nx + проверить уникальность случайного значения, а затем удалить

if(jedis.set(key, uni_request_id, "NX", "EX", 100s) == 1){ //加锁
    try {
        do something  //业务处理
    }catch(){
  }
  finally {
       //判断是不是当前线程加的锁,是才释放
       if (uni_request_id.equals(jedis.get(key))) {
        jedis.del(key); //释放锁
        }
    }
}

Здесь определяется, является ли блокировка, добавленная текущим потоком, и освобождение блокировки атомарной операцией. Если вы вызываете jedis.del() для снятия блокировки, блокировка может больше не принадлежать текущему клиенту.Разблокирует замки, добавленные другими.

Обычно также используетсялуа-скриптзаменять. Lua-скрипт выглядит следующим образом:

if redis.call('get',KEYS[1]) == ARGV[1] then 
   return redis.call('del',KEYS[1]) 
else
   return 0
end;

Этот метод относительно хорош, и в целом этот метод реализации уже можно использовать. но существуетБлокировка просрочена и снята, а дело не выполнено.(На самом деле оценить время обработки дела вообще не проблема).

11. Вы использовали Redisson? скажи мне, как это работает

Распределенная блокировкаЭто может существоватьБлокировка просрочена и снята, а дело не завершено.. Некоторые друзья считают, что достаточно установить срок действия блокировки немного дольше. В самом деле, давайте представим, можно ли запустить синхронизированный поток демона для потока, который получил блокировку, и проверять, существует ли блокировка через равные промежутки времени.Если она существует, время истечения блокировки будет продлено, чтобы предотвратить блокировки от предварительного освобождения.

ТекущийФреймворк с открытым исходным кодом RedissonЭто решает проблему распределенной блокировки. Давайте посмотрим на основной принцип Redisson:

Пока поток успешно заблокирован, он запуститwatch dogСторожевой таймер, который является фоновым потоком, будет проверять каждые 10 секунд. Если поток 1 все еще удерживает блокировку, он продолжит продлевать срок службы ключа блокировки. Следовательно, Redisson решается с помощью RedissonБлокировка просрочена и освобождена, а дело не завершенопроблема.

12. Что такое алгоритм Redlock

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

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

Чтобы решить эту проблему, автор Redis antirez предлагает расширенный алгоритм распределенной блокировки:Redlock. Основная идея Redlock заключается в следующем:

Разверните несколько мастеров Redis, чтобы гарантировать, что они не отключатся одновременно. И эти мастер-ноды полностью независимы друг от друга, и между ними нет синхронизации данных. В то же время необходимо убедиться, что в этих нескольких главных экземплярах используется тот же метод для получения и снятия блокировок, что и в одном экземпляре Redis.

Мы предполагаем, что в настоящее время существует 5 главных узлов Redis, на которых запущены эти экземпляры Redis на 5 серверах.

Этапы внедрения RedLock следующие:

  • 1. Получить текущее время в миллисекундах.
  • 2. Запросите блокировки от 5 мастер-узлов последовательно. Клиент устанавливает время ожидания сетевого подключения и ответа, причем время ожидания должно быть меньше времени истечения блокировки. (Предполагая, что время автоматического отказа блокировки составляет 10 секунд, время ожидания обычно составляет от 5 до 50 миллисекунд. Предположим, что время ожидания составляет 50 мс). Если время ожидания истекло, пропустите главный узел и попробуйте следующий главный узел как можно скорее.
  • 3. Клиент использует текущее время минус время начала получения блокировки (то есть время, записанное на шаге 1), чтобы получить время, использованное для получения блокировки. Если и только если более половины (N/2+1, здесь 5/2+1=3 узлов) главных узлов Redis получили блокировку, а время использования меньше времени истечения срока действия блокировки, блокировка будет снята. быть успешно приобретенным. (Как показано выше, 10 с> 30 мс + 40 мс + 50 мс + 4 мс + 50 мс)
  • Если блокировка получена, реальное время действия ключа изменится, и время, использованное для получения блокировки, необходимо вычесть.
  • Если блокировку не удалось получить (блокировка не была получена по крайней мере в N/2+1 мастер-экземплярах, или время получения блокировки превысило действительное время), клиенту необходимо разблокировать все мастер-узлы (даже если некоторые на мастер-узлах его вообще нет. Если блокировка прошла успешно, ее также нужно разблокировать, чтобы предотвратить какое-то проскальзывание по сети).

Следующие шаги упрощены:

  • Запросить блокировки от 5 мастер-узлов последовательно
  • В соответствии с установленным временем ожидания решается, следует ли пропустить главный узел.
  • Если более или равно трем узлам успешно заблокировано, а использованное время меньше периода действия блокировки, можно определить, что блокировка прошла успешно.
  • Если он не может получить замок, разблокируйте его!

13. Таблица переходов Redis

跳跃表

  • Таблица пропуска — одна из базовых реализаций упорядоченного набора zset.
  • Таблица перехода поддерживает усреднениеО(логN), поиск узлов с наименьшей сложностью O(N), а также может выполнять пакетную обработку узлов с помощью последовательных операций.
  • Таблица пропуска реализованаzskiplist и zskiplistNodeОн состоит из двух структур, в которых zskiplist используется для сохранения информации о таблице пропуска (такой как узел заголовка, узел нижнего колонтитула, длина), а zskiplistNode используется для представления узлов таблицы пропуска.
  • Таблица пропуска основана на связанном списке с добавлением многоуровневого индекса для повышения эффективности поиска.

14. Как MySQL и Redis обеспечивают согласованность двойной записи

  • Кэш задерживает двойное удаление
  • Удалить механизм повторных попыток кеша
  • Читать biglog асинхронно удалять кеш

14.1 Отсроченное двойное удаление?

Что такое отложенное двойное удаление? Блок-схема выглядит следующим образом:

延时双删流程

  1. сначала удалите кеш
  2. Обновите базу данных еще раз
  3. Переждите некоторое время (например, 1 секунду) и снова удалите кеш.

Этот сон на некоторое время, вообще как долго? Это все 1 секунда?

Это время ожидания = время, потраченное на чтение данных бизнес-логики + сотни миллисекунд. Чтобы гарантировать завершение запроса на чтение, запрос на запись может удалить кэшированные грязные данные, которые может принести запрос на чтение.

Это решение неплохое, только в период сна (например, 1 секунду) могут быть грязные данные, и общий бизнес это примет. но еслиНе удалось удалить кеш во второй разШерстяная ткань? Данные в кеше и базе данных могут все еще быть несогласованными, верно? Как насчет того, чтобы установить естественное время истечения срока действия для ключа и позволить ему истечь автоматически? Должен ли бизнес принимать несоответствия данных в течение срока действия? Или есть другое лучшее решение?

14.2 Удалить механизм повторения кеша

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

删除缓存重试流程

  1. написать запрос на обновление базы данных
  2. Удаление кеша не удалось по какой-то причине
  3. Поместите ключ, который не удалось удалить, в очередь сообщений
  4. Использовать сообщение очереди сообщений и получить ключ для удаления
  5. Повторите операцию удаления кеша.

14.3 Асинхронное чтение biglog с удалением кеша

Можно повторить попытку удалить механизм кэширования, но это приведет кВторжение в бизнес-код. На самом деле его можно оптимизировать и таким образом: ключ отсеивается асинхронно через бинлог БД.

Возьмите mysql в качестве примера

  • Вы можете использовать канал Али для сбора логов binlog и отправки их в очередь MQ
  • Затем подтвердите обработку сообщения об обновлении через механизм ACK, удалите кэш и убедитесь в целостности кэша данных.

15. Почему Redis 6.0 перешел на многопоточность?

  • До Redis 6.0, когда Redis обрабатывал клиентские запросы, включая чтение сокетов, анализ, выполнение и запись сокетов, все они обрабатывались последовательным и последовательным основным потоком, который назывался «один поток».
  • Почему Redis 6.0 не использует многопоточность? При использовании Redis практически не бывает ситуаций, когда ЦП становится узким местом, а Redis в основном ограничивается памятью и сетью. Например, в обычной системе Linux Redis может обрабатывать 1 миллион запросов в секунду с помощью конвейерной обработки, поэтому, если приложение в основном использует команды O(N) или O(log(N)), оно вряд ли займет много процессорного времени.

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

Цель этого заключается в том, что узким местом производительности Redis является сетевой ввод-вывод, а не ЦП.Использование многопоточности может повысить эффективность чтения и записи ввода-вывода, тем самым повышая производительность Redis в целом.

16. Расскажите о механизме транзакций Redis

Redis черезМУЛЬТИ, ИСПОЛНЕНИЕ, СМОТРЕТЬДождитесь набора команд для реализации механизма транзакции. Транзакции поддерживают выполнение нескольких команд одновременно, и все команды в транзакции будут сериализованы. Во время выполнения транзакции команды в очереди будут сериализованы и выполнены последовательно, а запросы команд, отправленные другими клиентами, не будут вставлены в последовательность команд выполнения транзакции.

Короче говоря, транзакция Redisпоследовательный, одноразовый, исключительныйВыполняет последовательность команд в очереди.

Процесс Redis, выполняющий транзакцию, выглядит следующим образом:

  • Начать транзакцию (МУЛЬТИ)
  • очередь команд
  • Выполнить транзакцию (EXEC), отменить транзакцию (DISCARD)
Заказ описывать
EXEC Выполнять команды во всех блоках транзакций
DISCARD Отменить транзакцию, отказавшись от выполнения всех команд в блоке транзакции
MULTI Отмечает начало блока транзакции
UNWATCH Отмените наблюдение за всеми ключами командой WATCH.
WATCH Следите за ключом, если ключ будет изменен другими командами до выполнения транзакции, то транзакция будет прервана.

17. Как справиться с конфликтом хэшей в Redis

В качестве базы данных K-V в памяти Redis использует глобальный хэш для хранения всех пар ключ-значение. Эта хеш-таблица состоит из нескольких хэш-сегментов, и элемент записи в хэш-сегменте хранитключ иуказатель значения, где *key указывает на фактический ключ, а *value указывает на фактическое значение.

Скорость поиска в хэш-таблице очень высокая, чем-то похожая на HashMap в Java, она позволяет нам быстро находить пары ключ-значение с временной сложностью O(1). Сначала вычислите хеш-значение по ключу, найдите соответствующее местоположение хеш-контейнера, затем найдите запись и найдите соответствующие данные в записи.

Что такое хеш-коллизия?

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

Для разрешения коллизий хэшей Redis используетцепной хеш. Сцепленное хеширование означает, что в одном и том же хеш-корзине несколько элементов хранятся в связанном списке, и они по очереди связаны указателями.

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

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

18. Может ли Redis одновременно обрабатывать запросы на запись во время создания RDB?

В ПОРЯДКЕ, Redis предоставляет две инструкции для создания RDB, а именно:сохранить и сохранить.

  • Если это инструкция сохранения, она будет заблокирована, поскольку выполняется основным потоком.
  • Если это команда bgsave, то это ответвление дочернего процесса для записи файла RDB, сохранение моментального снимка полностью обрабатывается дочерним процессом, а родительский процесс может продолжать обрабатывать запрос клиента.

19. Какой протокол используется на нижнем уровне Redis?

RESP, полное английское название Redis Serialization Protocol, представляет собой протокол сериализации, специально разработанный для Redis. Этот протокол фактически появился в версии 1.2 Redis, но, наконец, стал стандартом протокола связи Redis после Redis 2.0.

RESP в основном имеетПростая реализация, быстрый синтаксический анализ и хорошая читабельностьИ Т. Д.

20. Фильтр Блума

откликпроникновение в кешпроблема, мы можем использоватьФильтр Блума. Что такое фильтр Блума?

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

Каков принцип работы фильтра Блума?Предположим, у нас есть множество A с n элементами. использоватьk хэшейфункция, которая преобразует каждый элемент в AкартаДля разных позиций в массиве B длиной a бит все двоичные числа в этих позициях устанавливаются равными 1. Если проверяемый элемент отображается с помощью k хэш-функций, то находятся двоичные числа в его k позициях.все 1, этот элемент, скорее всего, принадлежит множеству A, иначене должен принадлежать множеству A.

Давайте рассмотрим простой пример, предположим, что множество A имеет 3 элемента, которые {d1,d2,d3}. Существует 1 хэш-функция, котораяHash1. Теперь сопоставьте каждый элемент A с массивом B длиной 16 бит.

Теперь мы сопоставляем d1, предполагая, что Hash1(d1) = 2, мы изменим сетку с нижним индексом 2 в массиве B на 1 следующим образом:

мы сейчас ставимd2Он также отображается, предполагая Hash1 (d2) = 5, мы также меняем сетку с индексом 5 в массиве B на 1 следующим образом:

Затем мы кладемd3Он также отображается, предполагая, что Hash1 (d3) также равен 2, это также сетка с индексом 2 и индексом 1:

Следовательно, чтобы подтвердить, находится ли элемент dn в множестве A, нам нужно только вычислить нижний индекс индекса, полученный Hash1(dn), поскольку он равен 0, это означает, что этот элементнет в наборе А, что, если нижний индекс индекса равен 1? этот элементвозможныйявляется элементом А. Потому что вы видите, что значения нижнего индекса, полученные d1 и d3, могут быть равны 1, или они могут отображаться другими числами Фильтр Блума существует.недостаток: будет существоватьхэш-коллизияВызываются ложные срабатывания, и возникает ошибка в суждении.

какуменьшить эту ошибкуШерстяная ткань?

  • Делайте больше сопоставлений хеш-функций, чтобы уменьшить вероятность коллизии хэшей.
  • В то же время увеличение битовой длины массива B может увеличить диапазон данных, генерируемых хеш-функцией, и снизить вероятность коллизии хэшей.

Добавляем еще один Hash2хэш-картаФункция, предполагающая, что Hash2(d1)=6, Hash2(d3)=8, они не будут конфликтовать, как показано ниже:

Даже с ошибками мы можем обнаружить, что фильтр Блума не работает.Полные данные не сохраняются, он просто вычисляет позицию, используя ряд функций хэш-карты, а затем заполняет двоичный вектор. еслиЕсли количество большое, фильтр Блума имеет очень низкий уровень ошибок в обмен на большую экономию места для хранения, что весьма рентабельно.

В настоящее время существуют библиотеки классов с открытым исходным кодом для фильтров Блума, такие какБиблиотека Google Guava, библиотеке классов Algebird от Twitter, вы можете сделать это на кончиках ваших пальцев или реализовать свой собственный дизайн на основе растровых изображений, поставляемых с Redis.

Ссылка и спасибо