Для чего можно использовать Redis

Redis
Для чего можно использовать Redis

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

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

Китайскую версию можно посмотреть по адресу:redisdoc.com/index.html

Англоязычную версию можно посмотреть на официальном сайте:redis.io/commands

String

Введение

Тип данных String является наиболее часто используемым и простейшим типом ключ-значение, и обычное хранилище ключей-значений можно отнести к этой категории. value может быть не только строкой, но и числом. Строки безопасны для двоичных файлов, поэтому вы можете хранить содержимое файла изображения в виде строки. Строка Redis может полностью реализовать текущую функцию Memcached. Помимо предоставления тех же операций get, set, incr, decr и других, что и Memcached, Redis также предоставляет следующие дополнительные операции:

  • получить длину строки
  • добавить содержимое в конец строки
  • Установить и перехватить часть строки
  • Битовые операции, Redis может поддерживать до 2 ^ 23 - 1 битных битовых операций
  • Пакетный набор содержимого серии строк

Сценарии применения

тайник

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

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

считать статистику

Redis обрабатывает команды в одном потоке, поэтому INCR, INCRBY, DECR, DECRBY и другие инструкции Redis могут достигать эффекта атомарного подсчета. С помощью этих команд Redis можно выполнить некоторые простые требования к статистике и подсчету в бизнесе.

GetSet устанавливает новое значение и возвращает старое значение. Например, чтобы реализовать счетчик, вы можете использовать GetSet, чтобы получить счетчик и сбросить его на 0.

Распределенный генератор идентификаторов

Наиболее широко используемый распределенный генератор идентификаторов — это алгоритм SnowFlake с открытым исходным кодом Twitter. Если количество одновременных запросов невелико, вы также можете использовать команды Redis INCR и INCRBY для реализации idmaker, то есть для создания глобального уникального идентификатора, который строго самоувеличивается.

Данные с истекшим сроком действия

Redis может установить время истечения срока действия для любого ключа с помощью команды EXPIRE, поэтому данные, срок действия которых должен регулярно истечь, можно хранить в Redis, который может легко реализовать функцию истечения срока действия. Например, для реализации системы распределенных сеансов. Когда сеанс установлен, session_key сохраняется в Redis и устанавливается время истечения срока действия. При проверке session_key сначала роути на соответствующий redis по uid.Если session_key не удалось получить, значит срок действия session_key просрочен и нужно авторизоваться заново, если session_key получен и проверка пройдена, срок действия время session_key может быть повторно обновлено.

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

Команда Set nx или SetNx выполняется успешно, только если ключ не существует. Его можно использовать для выбора Мастера или для реализации распределенных блокировок: все клиенты продолжают пытаться использовать мастер SetNx myName для упреждающей регистрации Мастера, а успешный клиент продолжает обновлять время истечения срока действия с помощью Expire. Если Мастер повесит трубку, ключ станет недействительным, и на оставшихся узлах произойдет новый раунд захвата.

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

При блокировке получите блокировку с помощью команды set nx ex|px Если установка выполнена успешно, блокировка выполнена успешно. Когда блокировка будет успешной, будет установлен тайм-аут для автоматического сброса времени, чтобы избежать взаимоблокировки. При снятии блокировки сначала получите информацию о блокировке через сценарий lua, и, если он будет подтвержден как блокировщик, удалите ключ, чтобы завершить снятие блокировки. Что касается распределенной блокировки Redis, для ее объяснения будет использована отдельная статья.

Команда блокировки:

 SET resource-name anystring NX EX max-lock-time

Снимите блокировку:

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

Битовая операция для статистики данных

Команды Redis GetBit, SetBit, BitOp, BitCount используются для выполнения битовых операций. Способ BitMap, например, подсчитывает количество чекинов пользователя.После того, как пользователь чекинится, соответствующая позиция смещения будет равна 1, а затем количество 1 в указанном диапазоне может быть подсчитано через подсчет битов, что то есть количество чекинов пользователя. Можно посчитать отдельно, количество заездов в течение недели, количество заездов в течение месяца и т.д.

Манипуляции со строками

Команды Redis Append, SetRange, GetRange и StrLen соответственно реализуют расширение текста, замену, перехват и вычисление длины, что очень полезно для определенных форматов данных.

предел частоты

Для HTTP-запросов, чтобы предотвратить злонамеренное считывание интерфейса или ограничить рабочую частоту пользователя, часто используется компонент ограничения частоты, чтобы пользователь мог запрашивать интерфейс только дважды в течение периода времени (например, 1 секунды). И Redis может легко реализовать периодическое ограничение частоты с помощью скрипта lua и команды INCR. Пример кода выглядит следующим образом:

   # KEYS和ARGV是redis命令传入lua脚本的参数,KEYS[1]是频率限制的KEY,ARGV[1]是增加的次数,ARGV[2]是KEY过期时间
   # 将计数加ARGV[1],如果KEY不存在,INCRBY命令会创建KEY,并初始化该KEY的值为ARGV[1]
   "local current = redis.call('INCRBY',KEYS[1],ARGV[1]);"
   # 如果增加后的值与传入的值相同,说明是新创建的KEY,表示是该周期内第一次更新,则给该key设定过期时间
   "if tonumber(current) == tonumber(ARGV[1]) "
   "then "
   "redis.call('EXPIRE',KEYS[1], ARGV[2]) "
   "end "
   # 返回当前计数值
   "return current";

Метод реализации

Строка хранится внутри Redis как строка, но строка представляет собой объект динамической строки, реализованный самим Redis, и динамические символы могут быть автоматически расширены. Целые числа также хранятся в виде строк, но при выполнении таких команд, как INCR, которые могут выполняться только для числовых типов, Redis преобразует строки в числовые типы для операции, а затем преобразует результаты операции в строки и записывает их в память.

Hash

Введение

Хэш хранит сопоставление между строками и строковыми значениями. Хэш хранит различные свойства объекта на карте и может только читать/обновлять некоторые свойства объекта.

Сценарии применения

Кэшировать структурированные данные

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

И строка, и хеш могут хранить структурированные данные, так как же выбрать эти две структуры данных?

[1] Если вы хотите получить доступ к большинству полей в структурированных данных большую часть времени, используйте строку, в противном случае используйте хэш;

[2] Если вы большую часть времени изменяете только значение поля в структурированных данных, используйте хэш, в противном случае используйте строку;

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

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

показатель

Например, объект User, в дополнение к id, иногда запрашивается по имени, и можно создать отдельный объект Hash с ключом name_id для хранения отношения отображения от имени к id. При вставке объекта User (set user:101 {"id":101,"name":"calvin"}), кстати, вставьте в этот хэш (hset name_id calvin 101), тогда в качестве ключа используется calvin в хэше значение равно 101. При запросе по имени используйте hget user:name:id calvin, чтобы получить идентификатор из ключа с именем calvin. Если вам нужно использовать несколько индексов для поиска определенной части данных, вы можете использовать один хеш-ключ, чтобы избежать использования нескольких строковых ключей для хранения значений индекса.

счет и другие функции

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

Метод реализации

Значение, соответствующее Redis Hash, на самом деле является HashMap. Здесь будут две разные реализации. Когда члены этого Hash относительно малы, Redis вместо этого будет использовать метод одномерного массива для компактного хранения, чтобы сэкономить память. использования реальной структуры HashMap. Кодировка значения redisObject — zipmap. Когда количество членов увеличивается, он будет автоматически преобразован в реальную структуру HashMap. В настоящее время используется кодировка ht.

List

Введение

Список — это двусвязный список, который поддерживает двунаправленное всплывающее/проталкивание. Поскольку он реализован в связанном списке, даже если в списке миллионы элементов, операция push может быть выполнена с постоянной временной сложностью. Однако связанные списки также усложняют доступ к элементам по индексу O (N). Толкайте слева или толкайте справа.Правила рек и озёр вообще то толкают с левого конца, а выталкивают с правого, то есть lpush/rpop, а ещё есть блокирующий вариант blpop/brpop, где клиент может заблокировать, пока не придет сообщение. Есть еще rpoplpush/brpoplpush, при появлении и возврате к клиенту он проталкивает себя в другой список, и llen получает длину списка. Также есть операции по значению: lrem (удаление элементов по значению), linster (вставка до и после элемента определенного значения), сложность O(N), N — длина списка, т.к. список не уникален, поэтому для обхода всех элементов и установки поиска требуется сложность времени O (log (N)) .

Сценарии применения

различные списки

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

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

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

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

Другой способ — добавить дополнительный список для каждого воркера, вместо этого использовать rpoplpush при всплывающих задачах, одновременно поместить сообщение в собственный список воркера и использовать lrem, чтобы удалить его, когда закончите. Если руководство кластера (такое как zookeeper) обнаружит, что рабочий процесс завис, он поместит содержимое списка рабочего процесса обратно в основной список.

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

Пейджинговый запрос

С помощью lrange можно легко реализовать функцию пейджинга содержимого списка.

Получить последние N фрагментов данных

Операция получения последних данных N: lpush используется для вставки идентификатора контента, который хранится как ключевое слово в начале списка. lrem используется для ограничения количества элементов в списке до 5000. Если объем данных, которые необходимо извлечь пользователю, превышает этот объем кэша, то запрос необходимо отправить в базу данных.

Метод реализации

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

Set

Введение

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

Сценарии применения

дедупликация данных

Набор, который не имеет требований к порядку, но требует, чтобы элементы не повторялись, тогда набор является наиболее подходящим выбором. И набор предоставляет важный интерфейс для определения того, находится ли элемент в коллекции наборов, что также не предоставляется списком.

Пересечение и союз достигают общей цели

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

Метод реализации:

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

Sorted Set

Введение

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

сцены, которые будут использоваться

хронологический список

Во многих сценариях список необходимо расположить в хронологическом порядке. Как правило, самое последнее время должно быть ранжировано первым. Затем временная метка может использоваться в качестве оценки для реализации хронологического списка.

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

Отсортированный набор может быть отсортирован в соответствии с оценкой, поэтому индексные данные таблицы лидеров могут использоваться в качестве оценки, а информация о пользователе может быть сохранена в структуре отсортированного набора в качестве значения. Попасть в топ-100 самых результативных пользователей очень просто: таблица лидеров ZREVRANGE 0 99. Запрос рейтинга пользователя также очень прост: таблица лидеров ZRANK.

Список, упорядоченный по некоторому весу

Например, статьи, рекомендованные Nuggets, будут вычислять значение веса каждой статьи в соответствии с такой информацией, как время и популярность.Вы можете использовать это значение веса в качестве оценки, а значение — это идентификатор статьи, тогда вы можете реализовать список статей в горячем списке.

Задержка задачи

Сцена задержки также очень часто используется задачей, например, неоплачиваемые бизнес-пользователи поставщика электроэнергии автоматически отменяют заказ в течение 30 минут и так далее. Можно легко выполнить задачи zset redis delay, в частности, я вижу эту статью:Реализация задачи задержки на базе REDIS

Метод реализации

Отсортированный набор использует список пропуска (SkipList) для реализации упорядоченного хранения данных. Кроме того, чтобы быстрее запрашивать оценку указанного элемента, Redis также помещает сопоставление от члена к оценке в хэш-карте, поэтому оценку указанного элемента можно запросить в классе временной сложности O (1).