← Назад к вопросам
К какому типу NoSQL БД относится Redis
2.0 Middle🔥 201 комментариев
#Базы данных и SQL
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ответ
Redis относится к типу In-Memory Key-Value (KV) Store, а если быть более точным — это In-Memory Data Structure Server.
Классификация NoSQL БД
Ниже приведена таблица типов NoSQL:
┌─ NoSQL БД
├─ Key-Value Store
│ ├─ Redis ✓
│ ├─ Memcached
│ └─ DynamoDB
├─ Document DB
│ ├─ MongoDB
│ ├─ CouchDB
│ └─ Firebase Firestore
├─ Column Family Store
│ ├─ HBase
│ └─ Cassandra
├─ Search Engines
│ ├─ Elasticsearch
│ └─ Solr
└─ Graph DB
├─ Neo4j
└─ JanusGraph
Основные характеристики Redis
1. In-Memory — данные в оперативной памяти
Все данные Redis хранятся в RAM, это обеспечивает:
- Микросекундная задержка — доступ к памяти вместо диска
- Очень быстрые операции — 100,000+ операций в секунду на одном сервере
Типичная скорость операций:
Memcached ~1,000,000 ops/sec
Redis ~100,000 ops/sec
MySQL ~1,000 ops/sec
PostgreSQL ~500 ops/sec
2. Key-Value структура
// Простая пара ключ-значение
redis.set("user:123:name", "John"); // Ключ: "user:123:name", Значение: "John"
String name = redis.get("user:123:name"); // Возвращает "John"
3. Поддержка различных типов данных
В отличие от простого Key-Value (где значение только строка), Redis поддерживает:
@Service
public class RedisCacheService {
@Autowired
private StringRedisTemplate redisTemplate;
// 1. String (текст, числа)
public void setString() {
redisTemplate.opsForValue().set("key", "value");
String val = redisTemplate.opsForValue().get("key");
}
// 2. List (очередь, стек)
public void setList() {
redisTemplate.opsForList().rightPush("queue:messages", "msg1");
redisTemplate.opsForList().rightPush("queue:messages", "msg2");
List<String> messages = redisTemplate.opsForList().range("queue:messages", 0, -1);
// ["msg1", "msg2"]
}
// 3. Set (уникальные значения, intersection)
public void setSet() {
redisTemplate.opsForSet().add("user:123:followers", "user:1", "user:2", "user:3");
Set<String> followers = redisTemplate.opsForSet().members("user:123:followers");
// {"user:1", "user:2", "user:3"}
}
// 4. Sorted Set (с приоритетом)
public void setSortedSet() {
// score — число для сортировки
redisTemplate.opsForZSet().add("leaderboard", "player1", 100);
redisTemplate.opsForZSet().add("leaderboard", "player2", 150);
Set<String> topPlayers = redisTemplate.opsForZSet().range("leaderboard", 0, 2);
// ["player1", "player2"] отсортированы по score
}
// 5. Hash (структура типа объекта)
public void setHash() {
Map<String, String> userHash = new HashMap<>();
userHash.put("name", "John");
userHash.put("email", "john@example.com");
userHash.put("age", "30");
redisTemplate.opsForHash().putAll("user:123", userHash);
String email = (String) redisTemplate.opsForHash().get("user:123", "email");
// "john@example.com"
}
}
Практическое использование в Spring
1. Кэширование
@Service
public class UserService {
@Autowired
private UserRepository repository;
@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
log.info("Fetching from DB: {}", id);
return repository.findById(id).orElseThrow();
// На второй вызов вернётся из Redis кэша, БД не будет затронута
}
@CacheEvict(value = "users", key = "#id")
public void updateUser(Long id, UpdateUserRequest request) {
User user = repository.findById(id).orElseThrow();
user.setName(request.getName());
repository.save(user);
// После обновления очищаем кэш
}
}
// Конфигурация Redis кэша
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10)); // TTL 10 минут
return RedisCacheManager.create(connectionFactory);
}
}
2. Session Store
// Spring Session + Redis
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
public class SessionConfig {
// Все HTTP сессии автоматически хранятся в Redis
}
// В коде работаешь как с обычной сессией
@RestController
public class LoginController {
@PostMapping("/login")
public ResponseEntity<Void> login(HttpSession session, LoginRequest request) {
User user = userService.authenticate(request);
session.setAttribute("userId", user.getId()); // Сохранится в Redis
return ResponseEntity.ok().build();
}
}
3. Очередь задач
@Service
public class TaskQueueService {
@Autowired
private StringRedisTemplate redisTemplate;
// Producer — добавляет задачу в очередь
public void enqueueTask(String taskId, String taskData) {
redisTemplate.opsForList().rightPush("task:queue", taskId + "|" + taskData);
}
// Consumer — обрабатывает задачи
public void processQueue() {
while (true) {
String task = redisTemplate.opsForList().leftPop("task:queue"); // Блокирующий pop
if (task != null) {
String[] parts = task.split("\\|");
processTask(parts[0], parts[1]);
}
}
}
}
4. Rate Limiting (ограничение частоты запросов)
@Component
public class RateLimitingService {
@Autowired
private StringRedisTemplate redisTemplate;
public boolean allowRequest(String userId) {
String key = "rate-limit:" + userId;
Long requestCount = redisTemplate.opsForValue().increment(key);
if (requestCount == 1) {
// Первый запрос — устанавливаем TTL
redisTemplate.expire(key, Duration.ofSeconds(60));
}
return requestCount <= 100; // Максимум 100 запросов в минуту
}
}
@RestController
public class ApiController {
@GetMapping("/api/data")
public ResponseEntity<Data> getData(@RequestHeader String userId) {
if (!rateLimitingService.allowRequest(userId)) {
return ResponseEntity.status(429).build(); // Too Many Requests
}
// Обработка запроса
return ResponseEntity.ok(new Data());
}
}
5. Real-time Leaderboard
@Service
public class LeaderboardService {
@Autowired
private StringRedisTemplate redisTemplate;
// Добавляем/обновляем счёт игрока
public void updateScore(String playerId, double score) {
redisTemplate.opsForZSet().add("game:leaderboard", playerId, score);
}
// Получаем топ-10
public List<String> getTopPlayers(int limit) {
Set<String> topPlayers = redisTemplate.opsForZSet()
.reverseRange("game:leaderboard", 0, limit - 1);
return new ArrayList<>(topPlayers);
}
// Получаем ранк игрока
public Long getPlayerRank(String playerId) {
return redisTemplate.opsForZSet().reverseRank("game:leaderboard", playerId);
}
}
Преимущества Redis
✅ Исключительная скорость — микросекунды
✅ Гибкие типы данных — String, List, Set, ZSet, Hash
✅ TTL (Time To Live) — автоматическое удаление через время
✅ Atomic операции — никогда не будет race condition
✅ Persistence (RDB/AOF) — опционально сохранить на диск
✅ Replication — для высокой доступности
✅ Cluster mode — горизонтальное шкалирование
✅ Pub/Sub — для message broadcasting
✅ Lua скрипты — сложные операции атомарно
Ограничения Redis
❌ Размер данных ограничен памятью сервера
❌ Нет сложных query (как в SQL)
❌ Нет ACID транзакций (только multi/exec)
❌ Нет автоматического шардирования (нужен Redis Cluster)
❌ Данные в RAM — потеря при сбое (нужна Replication)
Redis vs Memcached
Redis:
✅ Более функциональный (разные типы данных)
✅ Persistence (RDB/AOF)
✅ Pub/Sub
✅ Lua скрипты
❌ Немного медленнее
Memcached:
✅ Быстрее (простая архитектура)
✅ Лучше масштабируется (simpler)
❌ Только Key-Value
❌ Нет Persistence
❌ Нет Pub/Sub
Архитектура
Приложение (Java/Spring)
↓
Lettuce Driver (async/reactive)
↓
Redis Client Protocol
↓
Redis Server
┌──────────────────────┐
│ In-Memory Data Store │
│ Strings, Lists, │
│ Sets, ZSets, Hashes │
│ │
│ [Optional] Disk RDB/ │
│ AOF Persistence │
└──────────────────────┘
Итог
Redis — это Key-Value In-Memory Data Structure Store, который:
- Хранит все данные в RAM для молниеносного доступа
- Поддерживает разные типы данных (String, List, Set, ZSet, Hash)
- Идеален для кэширования, очередей, leaderboards, rate limiting
- Используется как дополнительный слой поверх основной БД
- Никогда не используется как основная БД из-за ограничения памяти