Что такое Redis и каковы его основные сценарии использования в бэкенд-разработке?

Ответ

Redis (REmote DIctionary Server) — это высокопроизводительная, опенсорсная, in-memory (хранящая данные в оперативной памяти) база данных типа «ключ-значение».

Главное отличие Redis от простых key-value хранилищ — поддержка сложных структур данных, таких как:

  • Strings — строки
  • Lists — списки
  • Sets — множества
  • Sorted Sets — упорядоченные множества
  • Hashes — хэш-таблицы
  • Bitmaps и HyperLogLogs
  • Streams — потоки данных

Ключевые особенности:

  • Высокая производительность: Данные хранятся в ОЗУ, что обеспечивает минимальные задержки при чтении и записи.
  • Персистентность: Redis может сохранять данные на диск (через RDB-снэпшоты или AOF-логи), чтобы не потерять их при перезапуске.
  • Атомарность операций: Большинство команд выполняются атомарно.
  • Репликация и кластеризация: Поддержка master-slave репликации и шардирования для масштабирования и отказоустойчивости.

Основные сценарии использования:

  1. Кэширование: Самый популярный сценарий. Кэширование ответов от БД или тяжелых вычислений.
  2. Хранение сессий: Быстрое хранение и доступ к данным пользовательских сессий.
  3. Очереди сообщений: Использование списков (Lists) или потоков (Streams) для создания простых и быстрых очередей задач.
  4. Счетчики и аналитика в реальном времени: Атомарные операции инкремента (INCR) идеально подходят для подсчета лайков, просмотров и т.д.
  5. Pub/Sub (Издатель-подписчик): Создание систем для обмена сообщениями в реальном времени.

Пример на Go с go-redis:

import (
    "context"
    "fmt"
    "github.com/go-redis/redis/v8"
)

var ctx = context.Background()

func main() {
    client := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379", // Адрес сервера Redis
        Password: "",               // Пароль, если есть
        DB:       0,                // Номер базы данных
    })

    // Устанавливаем значение с TTL (время жизни) 1 час
    err := client.Set(ctx, "user:1:profile", "some_json_data", time.Hour).Err()
    if err != nil {
        panic(err)
    }

    val, err := client.Get(ctx, "user:1:profile").Result()
    if err == redis.Nil {
        fmt.Println("Ключ не найден")
    } else if err != nil {
        panic(err)
    } else {
        fmt.Println("Найденное значение:", val)
    }
}