База данных Redis, реализация истечения срока действия ключа

задняя часть база данных сервер

Оригинальный адрес:у-у-у-у. xilidu.com/2018/03/20/…

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

Прочитав эту статью, вы узнаете:

  • Реализация базы данных Redis
  • Политика истечения срока действия ключа Redis

Реализация базы данных

Давайте сначала посмотрим кодserver.h/redisServer

struct redisServer{
    ...

    //保存 db 的数组
    redisDb *db;
    
    //db 的数量
    int dbnum;

    ...
}

Посмотрите еще раз на код redisDb:

typedef struct redisDb {
    dict *dict;                 /* The keyspace for this DB */
    dict *expires;              /* Timeout of keys with a timeout set */
    dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP)*/
    dict *ready_keys;           /* Blocked keys that received a PUSH */
    dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */
    int id;                     /* Database ID */
    long long avg_ttl;          /* Average TTL, just for stats */
} redisDb;

В общем, сервер redis содержит несколько (по умолчанию 16) баз данных redisDb.

db

Redis — это база данных типа «ключ-значение» для хранилища k-v. Словарь dict содержит все пары ключ-значение в базе данных, это место называетсяkeyspaceДословный перевод — «ключевое пространство».

Таким образом, мы можем так подумать, в Redisdb мы используем Dict (словарь) для поддержания ключевого пространства.

  • Ключ пространства ключей — это ключ базы данных, а каждый ключ — строковый объект. Обратите внимание не на строки, а на строковые объекты.

  • Значением keyspace является значение базы данных, которое может быть одним из redis, строкового объекта, объекта списка, объекта хеш-таблицы, объекта набора или упорядоченного объекта.

Операции чтения и записи базы данных

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

Когда мы выполняем:

>redis SET mobile "13800000000"

По сути, в пространство ключей добавляется ключ, представляющий собой строковый объект, содержащий строку «мобильный», а значением — строковый объект, содержащий символ «13800000000».

Посмотрите на картинку:

db

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

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

  • Ведите счетчики попаданий и промахов. Используется для подсчета частоты попаданий в кэш Redis.
  • Обновите время LRU ключа и запишите последнее активное время ключа.
  • Если при чтении обнаруживается, что срок действия ключа истек, Redis сначала удаляет ключ с истекшим сроком действия, а затем выполняет оставшуюся часть операции.
  • Если клиент выполняет операцию WATCH для этого ключа, он помечает ключ как грязный, позволяя транзакции заметить, что ключ был изменен.
  • Грязный увеличится на 1, если он не будет изменен один раз.
  • Если сервер включил функцию уведомления базы данных, после изменения ключа уведомление будет отправлено в соответствии с конфигурацией.

Реализация ключа истечения срока действия

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

Команды, связанные с истечением срока действия, в Redis

  • EXPIRE устанавливает время жизни ключа в секундах
  • EXPIREAT устанавливает время истечения срока действия ключа в секундах.
  • PEXPIRE устанавливает время жизни ключа в миллисекундах.
  • PEXPIREAT устанавливает момент истечения срока действия ключа в миллисекундах.

На самом деле эти команды, лежащие в основе команды, реализуются REXPIREAT.

Словарь *expires используется в redisDb для хранения времени истечения срока действия. Ключ указывает на ключ в пространстве ключей (указатель на языке C), а значение представляет собой длинную отметку времени, которая отмечает момент времени, когда истечет срок действия ключа в миллисекундах.

Если мы добавим время истечения срока действия мобильного телефона выше.

>redis PEXPIREAT mobile 1521469812000

В это время в словарь с истекшим сроком действия будет добавлена ​​пара ключ-значение. Как показано ниже:

db

Логика суждения об истечении срока действия очень проста:

  1. Срок действия ключа в словаре истекает.
  2. Если ключ существует, будет ли временная метка значения меньше текущей системной временной метки.

Далее нам нужно обсудить стратегию удаления ключей с истекшим сроком действия.

Существует три стратегии удаления ключа:

  1. Регулярное удаление, Redis регулярно удаляет все пары ключ-значение с истекшим сроком действия в памяти, что может обеспечить удобство использования памяти, и ключи с истекшим сроком действия будут удалены, но если количество ключей велико, одно удаление требует работы ЦП, что не требует ЦП. дружелюбно.
  2. При ленивом удалении вызывается только ключ, чтобы проверить, истек ли срок действия пары ключ-значение, но это приведет к сохранению в памяти большого количества пар ключ-значение с истекшим сроком действия, что не очень удобно для памяти, но значительно снижает нагрузка на ЦП.
  3. Удаление части по времени, Redis регулярно сканирует ключи с истекшим сроком действия, но удаляет только часть, а количество ключей для удаления определяется в соответствии с текущим состоянием Redis.

Три стратегии — это разные склонности ко времени и пространству. Чтобы сбалансировать время и пространство, Redis использует две последние стратегии: отложенное удаление и частичное удаление по времени.

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

Политика временного удаления просроченных ключей реализуется функцией expire.c/activeExpireCycle(), а server.c/serverCron() вызывается регулярноactivieExpireCycle().

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

static unsigned int current_db = 0; /* Last DB tested. */
static int timelimit_exit = 0;      /* Time limit hit in previous call? */
static long long last_fast_cycle = 0; /* When last fast cycle ran. */
  • первые триstaticГлобальные параметры соответственно записывают текущий пройденный индекс db, было ли последнее удаление завершено по тайм-ауту и ​​когда была выполнена последняя быстрая операция.

  • рассчитатьtimelimit = 1000000*ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC/server.hz/100;Это можно понять как 25% процессорного времени.

  • Если размер expire в db равен 0, не работайте

  • просроченные счета составляют менее 1% от общего числа ключей, не работают

  • num = dictSize(db->expires); num — это количество ключей, используемых при истечении срока действия.

  • slots = dictSlots(db->expires); slots — это размер словаря с истекающим сроком действия.

  • Если используемый ключ (число) больше, чем ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP, установите для него значение ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP. То есть одновременно проверяются только ключи ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP.

  • Случайно получить ключ с истекшим сроком действия. Рассчитайте, истек ли он и удалил его, если он истекает.

  • Затем различная статистика, в том числе количество удалений ключа и среднее время истечения срока действия.

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

  • Если удаленный ключ с истекшим сроком действия больше 1\4 от ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP, он выйдет из цикла и завершится.

Шаги посложнее, подытожим: (здесь все описано в конфигурации по умолчанию)

  1. Redis будет использовать до 25% процессорного времени для обработки истечения срока действия ключа.
  2. Перебрать все redisDbs
  3. В каждом redisDb, если в данных нет ключа с истекшим сроком действия или доля ключей с истекшим сроком действия слишком мала, он напрямую войдет в следующий redisDb.
  4. В противном случае пройдитесь по ключам с истекшим сроком действия в redisDb.Если удаленный ключ достигает 25% ключа со временем истечения срока действия или время работы превышает 25% времени процессора, текущий цикл будет завершен и будет введен следующий redisDb. .

постскриптум

В этой статье в основном объясняется, как реализована база данных Redis, а также представлена ​​логика обработки Redis ключей с истекшим сроком действия. Чем больше вы смотрите на код Redis, тем больше вы обнаруживаете, что на самом деле Redis занимается балансировкой, балансировкой пространства и времени программы. На самом деле обычный бизнес-дизайн заключается в том, чтобы сбалансировать время и пространство системы на макроуровне. Итак, я хочу сказать, что просмотр исходного кода позволяет нам изучить архитектуру системы на микроуровне, и это единственный способ для каждого архитектора. Давайте, все вместе.

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

Базовая структура данных Redis (1) Переменная строка, связанный список, словарь

Базовая структура данных Redis (II) целые числа, таблица перехода, список сжатия

Базовая структура данных Redis (3) Объекты

Добро пожаловать в мой публичный аккаунт WeChat:

二维码