Ответ
Redis — это хранилище структур данных (data structure store), а не просто key-value хранилище. Ключ всегда является строкой, а значение может быть одного из следующих типов:
| Тип | Описание | Пример использования |
|---|---|---|
| String | Простейший тип: строка, целое число или бинарные данные (до 512 МБ). | Кэширование HTML, счетчики, флаги. |
| List | Список строк, упорядоченный по порядку вставки. Поддерживает операции с обеих сторон (двусторонняя очередь). | Очередь задач (FIFO), лента новостей. |
| Set | Неупорядоченная коллекция уникальных строк. Поддерживает пересечения, объединения. | Теги, уникальные посетители, «друзья». |
| Sorted Set (ZSet) | Set, где каждый элемент имеет числовой score для сортировки. Элементы уникальны, score могут повторяться. |
Рейтинги, лидерборды, временные шкалы. |
| Hash | Коллекция пар field-value (аналог словаря или объекта). Идеален для представления объектов. |
Хранение профиля пользователя (user:123 -> {name: "Alice", age: 30}). |
| Stream | Лог-ориентированная структура, добавленная в Redis 5.0. Сообщения имеют ID и состоят из пар ключ-значение. | Очередь событий (event sourcing), аудит-лог. |
| Bitmap | Расширение типа String для битовых операций (установка/получение бита по индексу). | Статистика онлайн-пользователей за день, флаги фич. |
| HyperLogLog | Вероятностная структура для оценки количества уникальных элементов с минимальной памятью (погрешность ~0.81%). | Подсчет уникальных поисковых запросов за день. |
| Geospatial | Надстройка над Sorted Set для хранения координат (широта/долгота) и выполнения геопоиска. | Поиск ближайших точек интереса. |
Примеры команд и кода:
# String (кэширование)
> SET page:home "<html>..." EX 60
> GET page:home
# Hash (объект пользователя)
> HSET user:1000 name "John" age 30 email "john@doe.com"
> HGETALL user:1000
# Sorted Set (лидерборд)
> ZADD leaderboard 1500 "player1"
> ZADD leaderboard 1700 "player2"
> ZREVRANGE leaderboard 0 2 WITHSCORES # Топ-3
// Пример на C# с использованием StackExchange.Redis
IDatabase db = redis.GetDatabase();
// Работа с Hash
await db.HashSetAsync("user:1000", new HashEntry[] {
new("name", "John"),
new("age", 30)
});
var user = await db.HashGetAllAsync("user:1000");
// Работа с Sorted Set (добавление и получение топа)
await db.SortedSetAddAsync("leaderboard", "player1", 1500);
var topPlayers = await db.SortedSetRangeByRankWithScoresAsync("leaderboard", 0, 2, Order.Descending);
Важно: Все данные Redis по умолчанию хранятся в оперативной памяти (in-memory), что обеспечивает высокую скорость. Для персистентности можно настроить RDB (снимки) или AOF (лог операций).
Ответ 18+ 🔞
А, ну это же про Redis, да? Вот смотри, тут есть один важный момент, который многие не понимают, блядь.
Все думают, что Redis — это просто такая шустрая ключ-значение база, типа словарик на максималках. А на самом деле, это, сука, целый зоопарк структур данных под капотом! Ключ — это всегда строка, это да. А вот значение — тут уже начинается цирк, ёпта.
Смотри, какие у него есть типы, я тебе по полочкам разложу, а то потом будешь как дурак строкой список эмулировать:
String — это просто строка, ну или число, или бинарник до 512 мегов. Для кэша, счетчиков, каких-то флагов — идеально. Посадил на 60 секунд и забыл.
List — это типа очереди, можно с двух концов пихать и вытаскивать. Задачи в очередь кидать, ленту новостей формировать — самое то.
Set — это неупорядоченная куча уникальных строк. Теги там, уникальные айпишники посетителей. Можно между сетами пересечения искать — очень удобно, блядь.
Sorted Set (ZSet) — это как сет, но у каждого элемента есть вес (score). Они по этому весу сортируются. Рейтинги, таблицы лидеров — вот это всё. Уникальные элементы, но веса могут повторяться, да.
Hash — это, блядь, прям мой любимый тип. Как словарик внутри ключа. Поля и значения. Для хранения объекта пользователя — просто пиздец как удобно. Вместо кучи ключей user:1000:name, user:1000:age — один ключ user:1000 и внутри всё лежит.
Stream — это уже постарше, с пятой версии. Типа лог событий, очередь сообщений. Для всякого event sourcing — то, что надо.
Bitmap — это вообще магия на битах. Тип String, но с ним можно работать как с битовым массивом. Отметить, что пользователь с ID 12345 был онлайн вчера — это просто бит в определенной позиции выставить. Памяти жрёт дохуя меньше, чем если бы ты сет хранил.
HyperLogLog — это ваще космос, блядь. Вероятностная структура. Ты ей скормил миллион уникальных айдишников, а она тебе, не напрягаясь, говорит: "Ну тут примерно 1 008 423 уникальных, погрешность 0.81%". И памяти сожрала всего ничего. Для подсчета уникальных поисковых запросов за день — просто сказка, а не инструмент.
Geospatial — это надстройка над ZSet для работы с координатами. Найти все бары в радиусе километра — одна команда.
Вот, а теперь смотри, как этим пользоваться, чтобы не выглядеть как чайник:
# Кэшируем страничку на минуту
> SET page:home "<html>...ебись оно конём..." EX 60
# Работаем с объектом пользователя через Hash
> HSET user:1000 name "Василий" age 35 city "Москва"
> HGETALL user:1000
# И тебе не надо десять запросов делать, всё одним махом
# Лидерборд на ZSet
> ZADD leaderboard 1500 "player_ivan"
> ZADD leaderboard 1700 "player_petr"
> ZREVRANGE leaderboard 0 2 WITHSCORES # Получаем топ-3 с очками
На C# это выглядит как-то так, если через StackExchange.Redis:
IDatabase db = redis.GetDatabase();
// Хэш — красота же
await db.HashSetAsync("user:1000", new HashEntry[] {
new("name", "Василий"),
new("age", 35),
new("city", "Москва")
});
var user = await db.HashGetAllAsync("user:1000"); // Всё одним запросом, а не десятью!
// ZSet для рейтинга
await db.SortedSetAddAsync("leaderboard", "player_ivan", 1500);
var topPlayers = await db.SortedSetRangeByRankWithScoresAsync("leaderboard", 0, 2, Order.Descending);
И главное, чувак, помни: всё это летает в оперативке, поэтому такое быстрое. Но если сервер перезагрузить — всё, пиши пропало. Поэтому если надо сохранять на диск, настраивай либо RDB (снимки время от времени), либо AOF (каждую команду в лог пишет). Но это уже другая история, блядь.
Короче, не используй Redis как дурак, только для строк. Выбирай структуру под задачу — и жизнь станет проще, а код быстрее. Всё, лекция окончена, иди делай.