Files
crm.clientright.ru/ticket_form/docs/REDIS_VS_POSTGRESQL_SPEED.md

199 lines
7.1 KiB
Markdown
Raw Normal View History

# Redis vs PostgreSQL: Когда что использовать?
## Скорость доступа
### Redis:
-**0.1-1 мс** (данные в памяти)
- Мгновенный доступ
- Идеально для частых чтений
### PostgreSQL:
- 🐢 **1-10 мс** (с индексами)
- Зависит от нагрузки и индексов
- Но всё равно очень быстро
---
## Когда Redis имеет смысл
### ✅ Используй Redis, если:
1. **Очень частые чтения** (каждый запрос, каждый клик)
- Например: счетчики, rate limiting, сессии
2. **Временные данные** (TTL, автоочистка)
- Например: SMS коды, временные токены
3. **Кеширование результатов запросов**
- Например: результаты AI классификации, шаблоны визардов
4. **Pub/Sub события** (реал-тайм)
- Например: `ocr_events:{claim_id}` для SSE
---
## Когда PostgreSQL достаточно
### ✅ Используй только PostgreSQL, если:
1. **Данные читаются не так часто**
- Загрузка страницы, переход между шагами
- Пользователь не заметит разницу 1-10 мс
2. **Важна консистентность**
- Нужна гарантия актуальности данных
- Нет риска рассинхронизации
3. **Данные уже в PostgreSQL**
- Не нужно дублировать
- Проще архитектура
---
## Для веб-формы: Анализ использования
### Когда читаются данные заявки:
1. **При загрузке страницы** (1 раз)
- Пользователь открывает форму
- Можно загрузить из PostgreSQL (10 мс) - не критично
2. **При переходах между шагами** (редко)
- Пользователь нажимает "Далее"
- Можно загрузить из PostgreSQL (10 мс) - не критично
3. **При обновлении данных** (редко)
- Пользователь заполняет форму
- Сохраняется в PostgreSQL
### Вывод:
-**НЕ критично по скорости** - пользователь не заметит разницу
-**Важнее консистентность** - данные всегда актуальные
-**Проще архитектура** - один источник истины
---
## Компромиссное решение
### Вариант: Кеширование в Redis с инвалидацией
```python
# При чтении данных заявки
async def get_claim(claim_id: str):
# 1. Пробуем Redis (быстро)
cached = await redis.get(f"claim:{claim_id}")
if cached:
return json.loads(cached)
# 2. Если нет в кеше - из PostgreSQL
claim = await db.get_claim(claim_id)
# 3. Сохраняем в кеш на 1 час
await redis.set(f"claim:{claim_id}", json.dumps(claim), ttl=3600)
return claim
# При обновлении данных
async def update_claim(claim_id: str, data: dict):
# 1. Обновляем PostgreSQL
await db.update_claim(claim_id, data)
# 2. Инвалидируем кеш (удаляем из Redis)
await redis.delete(f"claim:{claim_id}")
# Или обновляем кеш сразу
await redis.set(f"claim:{claim_id}", json.dumps(data), ttl=3600)
```
### Плюсы:
- ✅ Быстрый доступ (если есть в кеше)
- ✅ Актуальные данные (инвалидация при обновлении)
- ✅ Fallback на PostgreSQL (если кеш пуст)
### Минусы:
- ❌ Дополнительная сложность
- ❌ Нужно инвалидировать кеш при каждом обновлении
- ❌ Риск устаревших данных (если забыли инвалидировать)
---
## Рекомендация для веб-формы
### Вариант 1: Только PostgreSQL (рекомендую)
**Когда использовать:**
- Данные читаются не так часто (загрузка страницы, переходы)
- Важна консистентность
- Простота архитектуры важнее скорости
**Плюсы:**
- ✅ Просто (один источник данных)
- ✅ Всегда актуальные данные
- ✅ Нет рассинхронизации
- ✅ PostgreSQL с индексами всё равно быстро (1-10 мс)
**Минусы:**
- ❌ Чуть медленнее, чем Redis (но не критично)
---
### Вариант 2: PostgreSQL + Redis кеш (если нужна скорость)
**Когда использовать:**
- Очень частые чтения (каждый запрос)
- Критична скорость (но для веб-формы это не так)
**Плюсы:**
- ✅ Быстрый доступ (0.1-1 мс)
- ✅ Меньше нагрузки на PostgreSQL
**Минусы:**
- ❌ Сложнее (нужна инвалидация кеша)
- ❌ Риск устаревших данных
- ❌ Больше кода для поддержки
---
## Итог
### Для веб-формы:
**Рекомендую: Только PostgreSQL**
**Почему:**
1. ⚡ PostgreSQL с индексами быстро (1-10 мс) - пользователь не заметит
2. ✅ Всегда актуальные данные (нет рассинхронизации)
3. ✅ Проще архитектура (один источник истины)
4. ✅ Данные читаются не так часто (не каждый запрос)
**Redis используй только для:**
- ✅ Pub/Sub (`ocr_events:{claim_id}`) - события в реальном времени
- ✅ Кеширование AI ответов (классификация, визарды) - если нужно
- ✅ SMS коды, временные токены - с TTL
**НЕ используй Redis для:**
- ❌ Основных данных заявки (есть в PostgreSQL)
- ❌ Документов (есть в PostgreSQL)
- ❌ Ответов визарда (есть в PostgreSQL)
---
## Если всё-таки нужен Redis кеш
Можно добавить опциональное кеширование:
```python
# В n8n workflow после claimsave
if (channel === 'web_form' && enable_cache === true) {
// Опционально: кешируем в Redis на 1 час
await redis.set(
`claim:${claim_id}`,
JSON.stringify(claim_data),
ttl=3600
);
}
```
Но это опционально и не обязательно для веб-формы.