Как найти все ключи по шаблону в Redis
Redis — одна из самых популярных in-memory баз данных, широко используемых для кэширования, хранения сессий, очередей и временных данных. Одной из частых задач при работе с Redis становится поиск ключей по определённому шаблону. Это может быть необходимо при отладке, мониторинге, очистке устаревших данных или анализе структуры хранилища. В отличие от реляционных СУБД, Redis не поддерживает полноценные SQL-подобные запросы, поэтому прямой выбор по маске требует понимания специфики его API и потенциальных ограничений производительности.
- Когда использовать KEYS, а когда SCAN?
- Сравнение KEYS и SCAN
- Как эффективно использовать SCAN с MATCH
- Реализация на Python с использованием redis-py
- Обработка ошибок и таймауты
- Распространённые шаблоны и примеры использования
- Поиск всех сессий
- Очистка кэша товаров
- Поиск ключей по диапазону ID
- Использование Lua-скриптов для сложных условий
- Проблемы производительности и как их избежать
- Как минимизировать влияние
- Альтернативы сканированию
- Лучшие практики работы с ключами в Redis
- Автоматизация поиска и очистки
- Безопасность
- Экспертное мнение
- Вопросы и ответы
- Заключение
Когда использовать KEYS, а когда SCAN?
Команда KEYS — самое простое решение для поиска ключей по шаблону. Она принимает один аргумент — паттерн, например user:*:session, и возвращает список всех совпадающих ключей. Синтаксис шаблона соответствует стандартным правилам glob-подобного сопоставления:
*— любое количество любых символов;?— ровно один символ;[abc]— один символ из указанного набора;[a-z]— диапазон символов.
Например:
KEYS user:123:*
вернёт все ключи, начинающиеся с user:123:.
Однако у команды KEYS есть критический недостаток: она полностью сканирует всю ключевую базу и блокирует сервер на время выполнения. В системах с миллионами ключей это может занять секунды, что делает её неприемлемой для использования в рабочих средах.
Альтернатива — команда SCAN. Она работает итеративно, возвращая небольшие порции ключей за один вызов. Это позволяет обходить весь набор ключей без блокировки сервера. SCAN поддерживает параметр MATCH, позволяя фильтровать результаты по шаблону прямо на стороне Redis.
Сравнение KEYS и SCAN
Критерий |
KEYS |
SCAN |
|---|---|---|
Блокировка сервера |
Да (полная) |
Нет (постепенная) |
Производительность при большом числе ключей |
Низкая |
Высокая |
Поддержка шаблонов |
Да |
Да (через MATCH) |
Использование в продакшене |
Не рекомендуется |
Рекомендуется |
Тип возврата |
Массив ключей |
Итератор + часть ключей |
Как эффективно использовать SCAN с MATCH
Команда SCAN использует концепцию курсоров. Вы начинаете с курсора 0 и повторяете вызовы до тех пор, пока он снова не вернёт 0, что означает завершение обхода.
Формат команды:
SCAN cursor [MATCH pattern] [COUNT count]
- cursor — текущая позиция в обходе (возвращается предыдущим вызовом);
- MATCH pattern — необязательный шаблон для фильтрации;
- COUNT count — примерное количество элементов, которые следует вернуть за одну итерацию (не гарантируется).
Пример использования в CLI:
SCAN 0 MATCH session:* COUNT 100
Первый вызов возвращает что-то вроде:
1) "456" 2) 1) "session:abc" 2) "session:def"
Где 456 — следующий курсор. Затем нужно вызвать:
SCAN 456 MATCH session:* COUNT 100
И так до тех пор, пока курсор не станет равен 0.
Реализация на Python с использованием redis-py
Библиотека redis-py предоставляет удобный метод scan_iter(), который автоматизирует итерации:
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
pattern = 'user:*:settings'
for key in r.scan_iter(match=pattern, count=100):
print(key.decode('utf-8'))
Этот код безопасно перебирает все ключи по шаблону, не блокируя ни клиент, ни сервер.
Обработка ошибок и таймауты
При длительном сканировании возможны сетевые разрывы или таймауты. Рекомендуется реализовать механизм восстановления:
- Сохраняйте текущий курсор в лог или временное хранилище;
- При сбое продолжайте с последнего известного курсора;
- Используйте таймауты соединения и повторные попытки (retry logic).
Распространённые шаблоны и примеры использования
Правильное именование ключей — основа эффективного поиска. Используйте осмысленные префиксы и разделители.
user:123:profile— профиль пользователя;cache:product:456— кэш товара;session:xyz— сессия;rate_limit:ip:192.168.0.1— лимиты по IP.
Примеры полезных шаблонов:
Поиск всех сессий
SCAN 0 MATCH session:* COUNT 100
Очистка кэша товаров
DEL $(redis-cli --raw SCAN 0 MATCH cache:product:* COUNT 100 | xargs)
(Внимание: массовое удаление через подстановку может перегрузить сервер.)
Лучше использовать UNLINK вместо DEL:
UNLINK $(...)
UNLINK удаляет ключ асинхронно, не блокируя основной поток.
Поиск ключей по диапазону ID
Шаблон user:[1-9]*:data найдёт ключи, где ID начинается с цифры от 1 до 9. Однако он не различает числовые диапазоны — это важно учитывать.
Использование Lua-скриптов для сложных условий
Для поиска по составным условиям можно использовать EVAL с Lua:
EVAL "local keys = redis.call('SCAN', 0, 'MATCH', 'temp:*') return keys[2]" 0
Но будьте осторожны: Lua-скрипты тоже блокируют сервер, если выполняются долго.
Проблемы производительности и как их избежать
Поиск ключей — ресурсоёмкая операция, даже при использовании SCAN. Основные риски:
- Высокая нагрузка на CPU — каждый вызов SCAN требует вычислений;
- Сеть — передача тысяч ключей увеличивает трафик;
- Память — накопление списка ключей на клиенте может исчерпать RAM.
Как минимизировать влияние
- Используйте максимально узкие шаблоны:
logs:error:2026*вместоlogs:*. - Устанавливайте адекватный COUNT: 100–500 обычно достаточно.
- Выполняйте сканирование в периоды низкой нагрузки.
- Не запускайте параллельные SCAN-операции — они суммируют нагрузку.
Альтернативы сканированию
- Хранение метаинформации: при создании ключа добавляйте его в Set или Sorted Set.
ZADD keys_by_type 0 mykey:type1
- Использование RedisJSON или RediSearch: если данные структурированы, можно индексировать их и выполнять сложные запросы.
- Sharding по префиксам: распределяйте ключи по разным экземплярам Redis по типу (например, сессии → redis-sessions, кэш → redis-cache).
Лучшие практики работы с ключами в Redis
Чтобы избежать необходимости массового поиска, следуйте этим принципам:
- Стандартизируйте имена ключей. Используйте единые правила: префикс:сущность:id:атрибут.
- Ограничивайте TTL. Почти все ключи должны иметь срок жизни, чтобы избежать накопления мусора.
- Мониторьте объём данных. Используйте
INFO memoryиDBSIZEдля отслеживания роста. - Регулярно аудируйте ключи. Запускайте сканирование (в off-peak) для выявления устаревших или битых ключей.
Автоматизация поиска и очистки
Создайте скрипт, который:
- Находит ключи по шаблону с помощью SCAN;
- Фильтрует по TTL (если нужно);
- Удаляет или архивирует их через UNLINK или экспорт.
Пример cron-задачи:
0 2 * * * /opt/scripts/redis-cleanup.sh
Безопасность
- Ограничьте доступ к командам KEYS и FLUSHDB через ACL (Redis 6+).
- Запрещайте KEYS на production-инстансах.
- Используйте отдельные пользователи для административных операций.
Экспертное мнение
Поиск ключей по шаблону — это симптом, а не цель. Чаще всего он требуется, потому что отсутствует контроль над жизненным циклом данных. Лучший способ «найти все ключи» — не искать их вовсе, а организовать хранение так, чтобы нужные данные были доступны через индексы или метаданные.
Redis не является полноценной базой данных с запросами. Он оптимизирован под скорость, а не гибкость. Поэтому архитектурное решение — делегировать сложные поисковые операции другим системам: Elasticsearch, PostgreSQL с расширением для JSON или модулям типа RediSearch.
Тем не менее, SCAN остаётся важным инструментом администрирования. Его следует использовать осознанно, с учётом нагрузки и времени выполнения. Автоматизация, мониторинг и документирование схемы ключей сводят необходимость в ручном поиске к минимуму.
Вопросы и ответы
CLUSTER NODES для получения списка нод, затем подключайтесь к каждой и запускайте сканирование.user:123 добавлять его в Set index:users. Это позволит быстро получать списки без поиска.Заключение
Поиск ключей по шаблону в Redis — задача, требующая баланса между функциональностью и производительностью. Команда KEYS проста, но опасна в продакшене. SCAN — правильный выбор для реальных систем: она не блокирует сервер и позволяет контролировать нагрузку.
Главное — не доводить до ситуации, когда поиск становится частой необходимостью. Продуманная схема именования, использование TTL, индексация через Sets и мониторинг помогут избежать ручных операций. Redis создан для скорости, а не для аналитики. Если вам регулярно нужно искать или агрегировать данные — рассмотрите интеграцию с другими системами.
- Никогда не используйте KEYS в продакшене.
- Всегда применяйте SCAN с параметром MATCH и разумным COUNT.
- Стандартизируйте имена ключей и используйте префиксы.
- Ограничивайте TTL и регулярно очищайте устаревшие данные.
- Рассмотрите RediSearch или внешние индексы для сложных запросов.
⚠️ Дисклеймер — нажмите, чтобы развернуть
Материалы, опубликованные в разделе «Блог» на сайте RU DESIGN SHOP (rudesignshop.ru), носят исключительно информационный и ознакомительный характер и не являются руководством к действию, финансовой рекомендацией, медицинской услугой, ветеринарным назначением либо рекламой товаров и услуг, включая азартные игры. Публикации не содержат призывов к участию в азартных играх и не направлены на продвижение соответствующих операторов.
Безопасность применения товаров и веществ: при использовании строительных материалов, бытовой химии, пестицидов и агрохимикатов необходимо строго следовать инструкциям производителя и действующему законодательству Российской Федерации, включая Федеральный закон РФ от 19.07.1997 № 109-ФЗ «О безопасном обращении с пестицидами и агрохимикатами».
Упоминание товарных знаков, брендов и организаций носит исключительно информационный характер и не означает наличие партнёрских отношений или одобрения со стороны правообладателей.
Материалы, содержащие сведения о медицинских, ветеринарных или косметических средствах, представлены в справочных целях и не являются медицинской консультацией или назначением. Перед применением рекомендуется обратиться к врачу, ветеринарному специалисту или иному сертифицированному профессионалу.
Возрастные ограничения: материалы, содержащие сведения о продукции категории 18+, включая алкоголь или азартные игры, предназначены исключительно для совершеннолетней аудитории и публикуются в информационных целях.
Правовая ответственность: решения, принятые на основе опубликованной информации, пользователь принимает самостоятельно и на свой риск; редакция и авторы несут ответственность в пределах, установленных законодательством Российской Федерации.
Редакция не допускает публикаций, содержащих пропаганду экстремизма, терроризма, наркотических средств или суицида; подобные материалы подлежат немедленному удалению.
Упоминание организаций с ограниченным статусом: компания Meta Platforms Inc. (социальные сети Facebook и Instagram) признана экстремистской организацией решением суда РФ, её деятельность запрещена на территории Российской Федерации; любые упоминания приводятся исключительно в информационных целях.
Авторские права и источники: информация собирается из открытых источников; её актуальность указывается на дату публикации и может изменяться.
Изображения и иллюстрации используются на условиях, разрешённых правообладателями. При возникновении претензий редакция готова оперативно рассмотреть обращение и внести необходимые изменения.
Персональные данные и cookies: сайт использует cookies и обрабатывает персональные данные пользователей в соответствии с Федеральным законом № 152-ФЗ «О персональных данных» и Политикой конфиденциальности RU DESIGN SHOP.
Мнения авторов могут не совпадать с позицией государственных органов или коммерческих организаций, упомянутых в материалах.