Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Введение в Redis и установку
intro

Введение в Redis и установку

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

Введение в Redis и установку

Redis — это не просто кэш. Это мощный инструмент для решения десятков production-задач: от кэширования API до очередей задач, real-time аналитики и управления сессиями.

#Что такое Redis

Redis (Remote Dictionary Server) — это in-memory база данных типа key-value store с открытым исходным кодом. Ключевые особенности:

  • In-Memory: все данные хранятся в оперативной памяти, что обеспечивает latency < 1ms и throughput до 1M+ операций в секунду
  • Key-Value модель: данные доступны по уникальным ключам, но значения могут быть сложными структурами
  • 11 структур данных: Strings, Hashes, Lists, Sets, Sorted Sets, Bitmaps, HyperLogLog, Streams, Geo, и другие
  • Персистентность (сохранение на диск): данные можно сохранять через RDB (снапшоты) или AOF (лог операций)
  • Репликация: master-replica архитектура для масштабирования чтения и отказоустойчивости
  • Кластеризация: встроенная поддержка шардирования данных

#Когда использовать Redis

#✅ Отлично подходит

ЗадачаКак Redis помогает
КэшированиеКэш ответов API, результатов тяжёлых запросов, HTML-страниц
СессииХранение пользовательских сессий с TTL для авто-очистки
Rate limitingОграничение запросов на IP/пользователя через INCR + EXPIRE
Очереди задачLists или Streams для фоновой обработки через Celery/ARQ
Pub/SubReal-time уведомления, чаты, веб-сокеты
ЛидербордыSorted Sets для рейтингов с автоматической сортировкой
АналитикаHyperLogLog для уникальных посетителей, Bitmaps для активности
ГеоданныеGeo-команды для поиска объектов рядом
Распределённые блокировкиКоординация между воркерами через SETNX

#❌ Не подходит

ЗадачаПочему не Redis
Основная БДНет ACID-гарантий, ограниченный объём RAM, нет сложных запросов
Долгосрочное хранениеДорогая память, риск потери данных при сбое питания
Сложные JOINНет реляционной модели, только простые lookup по ключу
Большие бинарные файлыМаксимальный размер значения 512 MB, но это плохая практика

#Архитектура Redis

┌─────────────────────────────────────────────────────────┐
│                    Redis Server                          │
│  ┌───────────────────────────────────────────────────┐  │
│  │              In-Memory Database                    │  │
│  │  ┌─────┐ ┌──────┐ ┌─────┐ ┌─────┐ ┌───────────┐  │  │
│  │  │Strings│ │Hashes│ │Lists│ │Sets │ │Sorted Sets│  │  │
│  │  └─────┘ └──────┘ └─────┘ └─────┘ └───────────┘  │  │
│  │  ┌────────┐ ┌───────────┐ ┌───────┐ ┌─────────┐  │  │
│  │  │Bitmaps│ │HyperLogLog│ │Streams│ │   Geo   │  │  │
│  │  └────────┘ └───────────┘ └───────┘ └─────────┘  │  │
│  └───────────────────────────────────────────────────┘  │
│                          │                               │
│         ┌────────────────┼────────────────┐             │
│         │                │                │             │
│    ┌────▼────┐    ┌─────▼─────┐   ┌──────▼──────┐     │
│    │   RDB   │    │    AOF    │   │ Replication │     │
│    │ (snapshot)│   │  (logging) │   │  (async)    │     │
│    └──────────┘   └────────────┘   └─────────────┘     │
└─────────────────────────────────────────────────────────┘

Однопоточная модель: Redis обрабатывает команды в одном потоке, что исключает race conditions и упрощает логику. I/O операции выполняются через event loop (epoll/kqueue).

Почему быстро:

  • Данные в RAM → доступ за наносекунды
  • O(1) сложность большинства операций
  • Нет блокировок (single-threaded)
  • Эффективные структуры данных (skiplist, hashtable, linked list)

#Установка Redis

#Через Docker (рекомендуется для разработки)

Создайте docker-compose.yml:

version: '3.8' services: redis: image: redis:7-alpine container_name: redis_dev ports: - "6379:6379" volumes: - redis_data:/data command: redis-server --appendonly yes healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 volumes: redis_data:

Запуск:

docker-compose up -d redis

Флаги:

  • --appendonly yes — включает AOF персистентность
  • --requirepass <password> — устанавливает пароль (для production!)

#Через Homebrew (macOS)

brew install redis brew services start redis

#Через apt (Ubuntu/Debian)

sudo apt update sudo apt install redis-server sudo systemctl start redis-server sudo systemctl enable redis-server

#Проверка установки

redis-cli ping # PONG

#Базовые команды CLI

Redis поставляется с CLI-клиентом redis-cli. Основные команды:

#Работа с ключами

# Проверка существования EXISTS user:1001 # Удаление DEL user:1001 # Время жизни (TTL) в секундах TTL session:abc123 # Установить TTL EXPIRE session:abc123 3600 # Найти ключи по паттерну (не использовать в production!) KEYS user:* # Итерация по ключам (безопасно для production) SCAN 0 MATCH user:* COUNT 100 # Тип значения TYPE user:1001

⚠️ Никогда не используйте KEYS в production — он блокирует Redis до завершения. Используйте SCAN.

#Работа со Strings

# Установка значения SET user:1001:name "Alice" # Получение значения GET user:1001:name # Установка с TTL (атомарно) SETEX session:abc123 3600 '{"user_id": 1001}' # Инкремент (атомарно) INCR page:views:123 INCRBY page:views:123 5 # Декремент DECR counter:visits

#Работа с Hashes

# Установка полей HSET user:1001 name "Alice" age 25 email "alice@example.com" # Получение поля HGET user:1001 name # Получение всех полей HGETALL user:1001 # Удаление поля HDEL user:1001 age # Инкремент поля HINCRBY user:1001 login_count 1

#Работа с Lists

# Push слева (в начало) LPUSH tasks "task1" "task2" "task3" # Push справа (в конец) RPUSH queue:emails "email1@example.com" # Pop слева LPOP tasks # Pop справа RPOP queue:emails # Длина списка LLEN tasks # Диапазон элементов LRANGE tasks 0 -1

#Подключение из Python

Установите библиотеку redis-py:

pip install redis

Базовое подключение:

import redis # Синхронный клиент client = redis.Redis( host='localhost', port=6379, db=0, decode_responses=True, # Возвращать str вместо bytes socket_timeout=5, # Таймаут операций socket_connect_timeout=5, # Таймаут подключения ) # Проверка подключения client.ping() # True # Базовые операции client.set('user:1001:name', 'Alice') client.get('user:1001:name') # 'Alice'

#Асинхронный клиент (для FastAPI)

import redis.asyncio as redis # Асинхронный клиент redis_client = redis.Redis( host='localhost', port=6379, db=0, decode_responses=True, socket_timeout=5, socket_connect_timeout=5, ) # Использование в async контексте await redis_client.set('user:1001:name', 'Alice') value = await redis_client.get('user:1001:name')

#В чём разница: синхронный vs асинхронный клиент

АспектСинхронный (redis.Redis)Асинхронный (redis.asyncio.Redis)
БлокировкаБлокирует поток до завершения операцииНе блокирует, освобождает event loop
Где использоватьСинхронный код, скрипты, CLIFastAPI, asyncio-приложения
Вызов методовclient.get(), client.set()await client.get(), await client.set()
ПроизводительностьОдин запрос = один потокМножество запросов в одном потоке
ПодключениеСоздаётся сразу при инициализацииСоздаётся при первом await (лениво)

#Пример: проблема с синхронным клиентом в FastAPI

# ❌ ПЛОХО: блокирует event loop from fastapi import FastAPI import redis app = FastAPI() client = redis.Redis(host='localhost', port=6379) @app.get("/user/{user_id}") def get_user(user_id: int): # Блокирует весь сервер на время запроса к Redis! data = client.get(f"user:{user_id}") return {"data": data}

#Пример: правильное использование в FastAPI

# ✅ ХОРОШО: не блокирует event loop from fastapi import FastAPI import redis.asyncio as redis app = FastAPI() redis_client = redis.Redis(host='localhost', port=6379) @app.get("/user/{user_id}") async def get_user(user_id: int): # Освобождает event loop во время ожидания data = await redis_client.get(f"user:{user_id}") return {"data": data}

#Инициализация через lifespan (рекомендуется для FastAPI)

from contextlib import asynccontextmanager import redis.asyncio as redis @asynccontextmanager async def lifespan(app: FastAPI): # При запуске приложения redis_client = redis.Redis( host='localhost', port=6379, decode_responses=True, ) await redis_client.ping() # Проверка подключения yield {"redis": redis_client} # При остановке приложения await redis_client.close() app = FastAPI(lifespan=lifespan) @app.get("/user/{user_id}") async def get_user(user_id: int, redis: redis.Redis = Depends()): data = await redis.get(f"user:{user_id}") return {"data": data}

Правило: для FastAPI всегда используйте redis.asyncio — синхронный клиент заблокирует event loop и убьёт производительность.

#Production checklist для установки

НастройкаDevelopmentProduction
ПарольНе требуетсяrequirepass <strong-password>
Bind0.0.0.0127.0.0.1 или private IP
Port63796379 (или кастомный)
Персистентность (сохранение на диск)Выключена или AOFRDB + AOF
MaxmemoryНе ограничено70-80% RAM сервера
Eviction policynoevictionallkeys-lru или volatile-lru
TLSНетДа (для внешних подключений)
Rename dangerous commandsНетДа (FLUSHALL, CONFIG, DEBUG)

Пример production redis.conf:

# Безопасность bind 127.0.0.1 port 6379 requirepass SuperSecretPassword123! # Переименование опасных команд rename-command FLUSHALL "" rename-command FLUSHDB "" rename-command CONFIG "" rename-command DEBUG "" # Персистентность save 900 1 save 300 10 save 60 10000 appendonly yes appendfsync everysec # Память maxmemory 4gb maxmemory-policy allkeys-lru # Логирование loglevel notice logfile /var/log/redis/redis-server.log

Далее: Структуры данных Redis