← Назад к вопросам
Какие операции с ключами можно делать в Redis?
1.3 Junior🔥 171 комментариев
#Базы данных (NoSQL)
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Операции с ключами в Redis
Redis предоставляет мощный набор команд для работы с ключами. Это основа для всех остальных операций. Рассмотрю основные операции и примеры использования с Python.
1. Базовые операции с ключами
SET — установить значение
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
# Базовое присваивание
r.set('user:1:name', 'Alice')
# С временем жизни (TTL) в секундах
r.set('session:abc123', 'data', ex=3600) # истечет через 1 час
# С временем жизни в миллисекундах
r.set('temp_token', 'xyz', px=600000) # истечет через 10 минут
# Только если ключ не существует
r.set('new_key', 'value', nx=True) # OK если ключа нет
# Только если ключ существует
r.set('existing_key', 'new_value', xx=True) # OK если ключ есть
GET — получить значение
value = r.get('user:1:name')
print(value) # 'Alice'
# Если ключа нет, вернет None
value = r.get('nonexistent')
print(value) # None
# Получить несколько значений
values = r.mget('key1', 'key2', 'key3')
print(values) # [value1, value2, value3]
DEL — удалить ключи
# Удалить один ключ
deleted_count = r.delete('user:1:name')
print(deleted_count) # 1 — количество удаленных ключей
# Удалить несколько ключей
deleted_count = r.delete('key1', 'key2', 'key3')
print(deleted_count) # Сколько было удалено
2. Проверка существования и типа
# EXISTS — проверить существование
if r.exists('user:1:name'):
print("Ключ существует")
# Проверить несколько ключей
count = r.exists('key1', 'key2', 'key3')
print(count) # Сколько из них существует
# TYPE — узнать тип данных
data_type = r.type('some_key')
print(data_type) # 'string', 'list', 'set', 'hash', 'zset' или 'none'
# STRLEN — длина строкового значения
length = r.strlen('user:1:name')
print(length) # Количество символов
3. Операции с TTL (время жизни)
# EXPIRE — установить TTL (в секундах)
r.set('temp_data', 'value')
r.expire('temp_data', 300) # Удалится через 5 минут
# PEXPIRE — TTL в миллисекундах
r.pexpire('temp_data', 300000) # Удалится через 5 минут
# TTL — узнать оставшееся время (секунды)
remaining = r.ttl('temp_data')
if remaining == -1:
print("Ключ без TTL")
elif remaining == -2:
print("Ключ не существует")
else:
print(f"Ключ истечет через {remaining} секунд")
# PTTL — оставшееся время в миллисекундах
remaining_ms = r.pttl('temp_data')
# PERSIST — убрать TTL
r.persist('temp_data') # Ключ больше не удалится
4. Переименование и копирование
# RENAME — переименовать ключ
r.set('old_name', 'value')
r.rename('old_name', 'new_name')
# Теперь данные в 'new_name', 'old_name' удален
# RENAMENX — переименовать только если новое имя не существует
result = r.renamenx('old_key', 'new_key')
print(result) # True если успешно, False если new_key уже существует
# COPY — скопировать значение (Redis 6.2+)
copied = r.copy('source_key', 'dest_key')
print(copied) # True если скопировано
5. Поиск и сканирование ключей
# KEYS — найти все ключи по паттерну (ОПАСНО на больших БД!)
keys = r.keys('user:*') # Все ключи, начинающиеся с 'user:'
print(keys) # ['user:1:name', 'user:2:name', ...]
# SCAN — итеративный поиск (лучше для больших БД)
cursor = 0
all_keys = []
while True:
cursor, keys = r.scan(cursor, match='user:*', count=100)
all_keys.extend(keys)
if cursor == 0:
break
print(all_keys)
# Более простой способ
for key in r.scan_iter(match='user:*'):
print(key)
6. Атомарные операции
# APPEND — добавить к строке
r.set('message', 'Hello')
r.append('message', ' World')
print(r.get('message')) # 'Hello World'
# GETSET — получить старое значение и установить новое
old_value = r.getset('counter', 100)
print(old_value) # Старое значение
print(r.get('counter')) # 100 — новое значение
# GETRANGE — получить подстроку
r.set('text', 'Hello World')
substring = r.getrange('text', 0, 4) # 'Hello'
print(substring)
# SETRANGE — заменить часть строки
r.setrange('text', 6, 'Redis') # 'Hello Redis'
7. Числовые операции
# INCR — увеличить на 1
r.set('counter', '10')
r.incr('counter')
print(r.get('counter')) # '11'
# INCRBY — увеличить на N
r.incrby('counter', 5)
print(r.get('counter')) # '16'
# INCRBYFLOAT — увеличить на число с плавающей точкой
r.incrbyfloat('price', 1.5)
print(r.get('price')) # '1.5'
# DECR — уменьшить на 1
r.decr('counter')
print(r.get('counter')) # '15'
# DECRBY — уменьшить на N
r.decrby('counter', 3)
print(r.get('counter')) # '12'
# Практический пример: счетчик просмотров
def increment_page_views(page_id):
r.incr(f'page:{page_id}:views')
def get_page_views(page_id):
return int(r.get(f'page:{page_id}:views') or 0)
for _ in range(5):
increment_page_views('homepage')
print(get_page_views('homepage')) # 5
8. Пакетные операции
# MSET — установить несколько ключей
r.mset({
'key1': 'value1',
'key2': 'value2',
'key3': 'value3'
})
# MSETNX — установить несколько только если все не существуют
result = r.msetnx({
'new1': 'val1',
'new2': 'val2'
})
print(result) # True если все установлены, False если хотя бы один существует
# Получить несколько значений
values = r.mget('key1', 'key2', 'key3')
print(values) # [value1, value2, value3]
9. Продвинутые операции
# RANDOMKEY — получить случайный ключ
random_key = r.randomkey()
print(random_key)
# DBSIZE — количество ключей в БД
key_count = r.dbsize()
print(key_count)
# FLUSHDB — очистить текущую БД
r.flushdb() # ОСТОРОЖНО!
# FLUSHALL — очистить все БД
r.flushall() # ОЧЕНЬ ОСТОРОЖНО!
# Получить информацию о ключе
info = r.object('refcount', 'some_key') # Количество ссылок
encoding = r.object('encoding', 'some_key') # Внутреннее представление
idletime = r.object('idletime', 'some_key') # Время неиспользования
10. Практические примеры
Кеш с автоматическим истечением
def cache_result(func, ttl=3600):
def wrapper(*args):
cache_key = f"{func.__name__}:{':'.join(map(str, args))}"
# Проверяем кеш
cached = r.get(cache_key)
if cached:
return cached
# Вычисляем и кешируем
result = func(*args)
r.set(cache_key, result, ex=ttl)
return result
return wrapper
@cache_result
def expensive_operation(x, y):
return x * y
Счетчик с ограничением по времени
def is_rate_limited(user_id, limit=100, window=60):
key = f"rate:{user_id}"
count = r.incr(key)
if count == 1:
r.expire(key, window) # Первый запрос — установить TTL
return count > limit
if not is_rate_limited('user123'):
print("Запрос разрешен")
else:
print("Лимит превышен")
Распределенная блокировка
def acquire_lock(lock_name, timeout=10):
return r.set(lock_name, '1', nx=True, ex=timeout)
def release_lock(lock_name):
r.delete(lock_name)
if acquire_lock('resource:database'):
try:
# Критическая секция
print("Работаю с ресурсом")
finally:
release_lock('resource:database')
else:
print("Ресурс заблокирован")
Резюме важных команд
| Команда | Назначение | Частота использования |
|---|---|---|
| SET/GET | Базовое присваивание | ⭐⭐⭐⭐⭐ |
| DEL | Удаление ключей | ⭐⭐⭐⭐ |
| EXISTS | Проверка существования | ⭐⭐⭐⭐ |
| EXPIRE/TTL | Управление временем жизни | ⭐⭐⭐⭐⭐ |
| INCR/DECR | Числовые операции | ⭐⭐⭐⭐ |
| MGET/MSET | Пакетные операции | ⭐⭐⭐ |
| SCAN | Итеративный поиск | ⭐⭐⭐⭐ |
| APPEND | Конкатенация строк | ⭐⭐ |
Эти операции составляют основу для работы с Redis и применяются при кешировании, сеансах, счетчиках и очередях.