RE:NODE

Базы данных12 мин чтения

Valkey: первые шаги - valkey-cli, AUTH и первые команды

Подключитесь к серверу Valkey через valkey-cli или redis-cli, безопасно пройдите аутентификацию, соберите строку подключения для приложения и освойте ежедневные команды.

0 прочтений

Чтобы пользоваться сервером Valkey, нужны три вещи: хост, порт и пароль. С ними valkey-cli -h <host> -p <port> --askpass открывает интерактивный сеанс, PING отвечает PONG, а ваше приложение подключается по URL вида redis://default:<password>@<host>:<port>/0. Поскольку Valkey говорит на протоколе Redis, redis-cli работает ровно так же, как valkey-cli, и любая клиентская библиотека Redis подключается без изменений. Остальная часть статьи - подробности: как поставить на свою машину клиент командной строки, как пройти аутентификацию, не раскрыв пароль, как собирать URL, которые переживут специальные символы, двадцать команд, которые вы будете использовать каждый день, подключение из кода и что означают типичные сообщения об ошибках.

Что нужно, прежде чем начать#

Тот, кто управляет сервером, даёт вам:

  • Хост: имя или IP-адрес, например db.example.net.
  • Порт: по соглашению 6379, хотя размещённый у провайдера сервер часто слушает другой номер.
  • Пароль: requirepass Valkey или пароль ACL-пользователя. Без имени пользователя вы аутентифицируетесь как встроенный пользователь default.
  • TLS или нет: ждёт ли сервер зашифрованного соединения. Если да, схема URL - rediss://, а CLI нужен --tls; если нет, TLS-клиент упадёт на рукопожатии.

Запишите их в менеджер паролей, а не в текстовый файл на рабочем столе. По умолчанию у Valkey нет задержки при входе и нет блокировки после неудачных попыток; между портом и вашими данными стоит только пароль, поэтому он должен быть длинным и случайным. Открытость наружу, ACL-пользователи и опасные команды разобраны в статье безопасность Valkey и ACL.

Где взять клиент командной строки

Сервер локально устанавливать не нужно, только клиент.

ПлатформаКак получить клиент
Debian, UbuntuПакет redis-tools (redis-cli); в новых релизах есть и пакеты с инструментами Valkey
FedoraПакет valkey, в который входит valkey-cli
macOSbrew install valkey
WindowsWSL с пакетом Linux или Docker
Везде, где есть Dockerdocker run --rm -it valkey/valkey valkey-cli -h <host> -p <port>

redis-cli из любого релиза Redis 6 или 7 без проблем общается с Valkey. Графические инструменты, сделанные для Redis, - RedisInsight, Another Redis Desktop Manager и другие - как правило, тоже работают с Valkey, потому что говорят на том же протоколе; ими приятно просматривать ключи, но знание CLI они не заменяют.

Подключение и аутентификация#

Очевидный способ заодно и дырявый:

bash
$ valkey-cli -h db.example.net -p 6380 -a 'the-password'Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

Предупреждение заслуженное. Пароль в командной строке виден любому, кто может посмотреть список процессов на этой машине, и попадает в историю командной оболочки. Способы получше, в порядке предпочтения:

bash
# Prompt for it$ valkey-cli -h db.example.net -p 6380 --askpass# Or pass it through the environment$ export VALKEYCLI_AUTH='the-password'      # redis-cli reads REDISCLI_AUTH$ valkey-cli -h db.example.net -p 6380# Or authenticate inside the session$ valkey-cli -h db.example.net -p 6380db.example.net:6380> AUTH the-passwordOK

AUTH password аутентифицирует как пользователя default; AUTH username password - как ACL-пользователя. CLI также принимает --user для имени пользователя. Если сервер использует TLS, добавьте --tls, а для частного удостоверяющего центра - --cacert ca.pem.

Первый сеанс должен состоять из четырёх команд:

code
db.example.net:6380> PINGPONGdb.example.net:6380> INFO server# Serverredis_version:7.2.4server_name:valkeyvalkey_version:8.1.1...db.example.net:6380> DBSIZE(integer) 0db.example.net:6380> QUIT

INFO server точно говорит, к чему вы подключены. Valkey сообщает redis_version:7.2.4 ради старых клиентов, а свою настоящую версию - в valkey_version. Запомните эту версию: команды, добавленные после форка, есть только в тех релизах, которые их включают.

Строки подключения#

Большинство клиентских библиотек и фреймворков принимают один URL, и тогда вся конфигурация укладывается в одну переменную окружения.

code
redis://[username]:[password]@[host]:[port]/[database]
URLЗначение
redis://:s3cret@db.example.net:6380/0Только пароль, пользователь default, база 0
redis://default:s3cret@db.example.net:6380/0То же самое, с явно указанным пользователем
redis://app:s3cret@db.example.net:6380/2ACL-пользователь app, база 2
rediss://:s3cret@db.example.net:6380/0То же самое поверх TLS

Ловушка - специальные символы. Пароль, содержащий @, :, /, #, ? или %, ломает разбор URL, обычно с обманчивой ошибкой «connection refused» или «invalid port». Кодируйте их через проценты - @ становится %40, / - %2F, # - %23 - или генерируйте пароли только из букв и цифр, что при сорока символах не уступит по стойкости ничему, что вам может понадобиться.

bash
$ python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=""))' 'p@ss/w#rd'p%40ss%2Fw%23rd

Некоторые клиенты, сделанные специально для Valkey, принимают и valkey:// и valkeys://, но redis:// понимают все клиенты и фреймворки, поэтому это более надёжный вариант по умолчанию. Храните URL в переменной окружения, например VALKEY_URL или REDIS_URL, - почему ему не место в репозитории, объясняет статья переменные окружения и секреты.

Команды, которыми вы будете пользоваться каждый день#

Valkey - хранилище «ключ - значение», где у каждого значения есть тип, а команды привязаны к типу. Сеанс, затрагивающий основные из них:

code
> SET greeting "hello" EX 60OK> GET greeting"hello"> TTL greeting(integer) 57> INCR page:views(integer) 1> HSET user:42 name "Anna" plan "pro"(integer) 2> HGETALL user:421) "name"2) "Anna"3) "plan"4) "pro"> LPUSH jobs "send-email:913"(integer) 1> RPOP jobs"send-email:913"> SADD online:users 42 57(integer) 2> ZADD leaderboard 3100 anna 2800 ben(integer) 2> ZREVRANGE leaderboard 0 9 WITHSCORES1) "anna"2) "3100"3) "ben"4) "2800"> TYPE user:42hash> EXPIRE user:42 3600(integer) 1> UNLINK greeting(integer) 1
КомандаЧто делает
SET key value EX 60Сохраняет строку со сроком жизни 60 секунд
SET key value NXСохраняет, только если ключа нет (блокировки, дедупликация)
GET, MGETЧитает одну или много строк за одно обращение
INCR, INCRBYАтомарные счётчики
EXPIRE, TTL, PERSISTЗадать, прочитать и убрать срок жизни
HSET, HGET, HGETALLЗаписи из пар «поле - значение»
LPUSH, RPOP, BRPOPСписки как очереди, блокирующее извлечение для исполнителей
SADD, SISMEMBERМножества уникальных элементов
ZADD, ZRANGEСортированные множества: таблицы лидеров, индексы по времени
DEL, UNLINKУдаление; UNLINK освобождает память в фоне
SCANБезопасный перебор ключей, по странице за раз

Когда какой тип использовать, подробнее рассказано в статье типы данных Valkey простыми словами.

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

Создайте один клиент при запуске приложения и используйте его повторно. Открытие соединения на каждый запрос тратит обращение на рукопожатие и AUTH и приводит к утечке соединений, когда что-то бросает исключение.

Node.js с `ioredis`:

javascript
import Redis from "ioredis";const valkey = new Redis(process.env.VALKEY_URL, {  maxRetriesPerRequest: 3,});await valkey.set("greeting", "hello", "EX", 60);console.log(await valkey.get("greeting"));

Python с `redis-py`:

python
import osimport redisvalkey = redis.Redis.from_url(os.environ["VALKEY_URL"], decode_responses=True)valkey.set("greeting", "hello", ex=60)print(valkey.get("greeting"))

decode_responses=True возвращает str вместо bytes, а это то, что вам нужно, если только вы не храните двоичные значения.

.NET со StackExchange.Redis, который использует собственный формат строки подключения, а не URL:

code
db.example.net:6380,password=s3cret,abortConnect=false

Передайте её в ConnectionMultiplexer.Connect один раз и используйте мультиплексор во всём приложении; он задуман как синглтон. abortConnect=false позволяет приложению запуститься и продолжать попытки, если сервер ненадолго недоступен, а не падать при старте.

Число соединений важнее, чем принято думать: каждый процесс, исполнитель и задача cron держат собственные соединения. Как их рассчитывать, описано в статье пулы соединений и лимиты.

Имена ключей и срок жизни#

Имена ключей и нумерованные базы

В Valkey нет таблиц, поэтому структура живёт в именах ключей. Принято разделять части двоеточиями, от общего к частному: user:42, session:9f2c..., cache:v3:report:team:7:2026-10-08. Префикс для каждого приложения (shop:, api:) не даёт двум приложениям на одном сервере столкнуться, а сегмент версии в ключах кэша означает, что смена формы значения - это смена префикса, а не сброс всего.

У отдельного сервера есть ещё и нумерованные базы данных, по умолчанию от 0 до 15, которые выбираются командой SELECT 2 или /2 в конце URL. У них общие память, сохранение данных и пароль, а FLUSHALL очищает их все, так что изоляция у них слабее, чем кажется. Префикс обычно понятнее; настоящая изоляция - это отдельный сервер.

Как работает срок жизни

У любого ключа может быть время жизни. SET key value EX 60 задаёт его при записи; EXPIRE key 60 добавляет его существующему ключу; TTL key показывает остаток в секундах, PTTL - в миллисекундах. Два значения, которые возвращает TTL, сбивают людей с толку: -1 означает, что ключ существует без срока жизни, а -2 - что ключа нет вовсе.

Истёкшие ключи удаляются двумя путями. Когда клиент обращается к ключу, время которого вышло, тот удаляется на месте, и клиент ничего не видит. Кроме того, сервер в фоне выборочно проверяет ключи со сроком жизни и удаляет найденные истёкшие. Вместе это означает, что память от истёкших ключей освобождается постепенно, а не мгновенно, и поэтому DBSIZE может ненадолго учитывать ключи, которые ни один клиент уже не прочитает.

Правило, которое приносит больше всего сюрпризов: обычный SET существующего ключа снимает его срок жизни. Если код обновляет закэшированное значение через SET key newvalue без EX, ключ теперь живёт вечно. Либо передавайте срок жизни при каждой записи, либо используйте SET key newvalue KEEPTTL, чтобы сохранить прежний. EXPIRE также принимает NX, XX, GT и LT, чтобы задавать срок жизни, только если его нет, только если он есть или только если новый позже или раньше прежнего, - удобно для скользящих тайм-аутов сессий. PERSIST key намеренно снимает срок жизни.

Задавайте срок жизни всему, что является кэшем или сессией. Ключ без срока жизни - это обещание, что кто-то его удалит, а никто не удаляет.

Конвейеры и транзакции#

Каждая команда стоит одного сетевого обращения туда и обратно, а от сервера приложения до базы данных это обычно от долей миллисекунды до нескольких миллисекунд. Цикл, который отправляет тысячу команд GET по одной, почти всё время проводит в ожидании. Исправляют это два инструмента.

Команды для нескольких ключей выполняют несколько операций за одно обращение: MGET и MSET для строк, HMGET для нескольких полей хеша и вариативные формы SADD, LPUSH и DEL.

Конвейер отправляет много команд, не дожидаясь каждого ответа, а затем читает все ответы разом. Его поддерживает любая клиентская библиотека - pipeline() в ioredis и redis-py, пакеты в StackExchange.Redis, - и обычно он ускоряет массовую работу в десять раз и больше. Конвейер не атомарен; между вашими командами могут выполняться команды других клиентов.

Когда нужна атомарность, MULTI ставит команды в очередь, а EXEC выполняет их вместе, и команды других клиентов между ними не вклиниваются. Отката нет: если одна команда в блоке завершится ошибкой, остальные всё равно выполнятся. WATCH key перед MULTI заставляет транзакцию прерваться, если отслеживаемый ключ за это время изменился, и это даёт оптимистичную блокировку. Для логики, которая должна прочитать, а потом решить, скрипт Lua через EVAL выполняется на сервере как один атомарный шаг и часто проще, чем WATCH, - разобранный пример есть в статье ограничение частоты запросов на Valkey.

Valkey на RE:NODE#

В линейке баз данных каждый сервер Valkey поставляется со сгенерированным паролем и доступен по хосту и порту, которые показаны в панели для этого тарифа, без слота прокси посередине - ваше приложение подключается к этому адресу напрямую, через redis://default:<password>@<host>:<port>/0 или аналог в вашем клиенте. Данные сохраняются на диск через AOF и снимки, так что перезапуск их не стирает. Тарифы начинаются с 256 МБ памяти, из которых для данных, по описанию тарифа, доступно примерно 200 МБ. Если приложение работает на тарифе для приложений, положите URL в переменную окружения на его вкладке Startup.

Когда подключение не удаётся#

`NOAUTH Authentication required.` Вы подключились, но не прошли аутентификацию. Добавьте пароль в URL или в CLI.

`WRONGPASS invalid username-password pair or user is disabled.` Пароль неверный или испорчен при разборе URL. Проверьте тот же пароль через --askpass в CLI; если там работает, проблема в кодировании URL.

`Connection refused` или тайм-аут. Неверный хост или порт, файрвол между вами и сервером или несоответствие TLS. valkey-cli -h <host> -p <port> PING с той же машины, где работает приложение, отделяет сетевые проблемы от проблем приложения.

`OOM command not allowed when used memory > 'maxmemory'.` Сервер заполнен, а его политика вытеснения не позволяет ничего вытеснять. Как это исправить, рассказано в статье память Valkey и политики вытеснения.

`ERR max number of clients reached`. Что-то допускает утечку соединений, обычно клиент, создаваемый на каждый запрос. CLIENT LIST показывает, кто подключён и откуда.

`LOADING` ... loading the dataset in memory. Сервер только что запустился и читает свой снимок или проигрывает append-only файл. Пока он не закончит, команды отклоняются; для небольшого набора данных это секунды, для большого - дольше. Хорошие клиенты сами повторяют запрос при этой ошибке; если ваш не умеет, добавьте короткий повтор с нарастающей задержкой на время запуска.

`READONLY You can't write against a read only replica.` Вы подключены к реплике, а не к основному серверу. Проверьте хост и порт - обычно это значит, что конфигурацию скопировали из другого окружения.

Соединения обрываются после нескольких минут простоя. Что-то между клиентом и сервером - файрвол, NAT-шлюз, балансировщик нагрузки - забывает простаивающие TCP-соединения. На стороне сервера есть timeout (закрывать простаивающих клиентов через N секунд, по умолчанию 0, то есть никогда) и tcp-keepalive (отправлять keepalive-пробы, по умолчанию 300 секунд). На стороне клиента включите keepalive в параметрах библиотеки и убедитесь, что она автоматически переподключается, - ioredis, redis-py и StackExchange.Redis при соответствующей настройке это умеют.

`MISCONF` ... unable to persist to disk. Последнее фоновое сохранение не удалось, и сервер перестаёт принимать записи, чтобы вы это заметили. Обычно заполнен диск или форку для сохранения не хватило памяти.

FAQ#

Можно ли использовать redis-cli с Valkey?

Да. redis-cli из Redis 6 или 7 говорит на том же протоколе и работает со всеми командами, общими для Valkey и Redis. Разница лишь косметическая: valkey-cli читает пароль из VALKEYCLI_AUTH, а redis-cli - из REDISCLI_AUTH.

Какое имя пользователя указывать, если мне дали только пароль?

default. Встроенный пользователь Valkey называется default, и AUTH password без имени пользователя аутентифицирует именно как него. В URL либо оставьте имя пользователя пустым (redis://:password@host), либо явно напишите default.

Безопасно ли запускать MONITOR, чтобы посмотреть, что делает приложение?

На несколько секунд во время отладки - да. MONITOR транслирует каждую команду, которую получает сервер, что заметно снижает пропускную способность загруженного сервера и выводит каждое значение, включая данные сессий и всё конфиденциальное. Никогда не оставляйте его работать и никогда не публикуйте его вывод.

Как узнать, сколько памяти занимают мои данные?

INFO memory показывает used_memory_human для всего сервера, а MEMORY USAGE keyname - для одного ключа. valkey-cli --bigkeys и --memkeys делают выборку по пространству ключей и находят самые большие ключи, не блокируя сервер.

Почему пароль работает в CLI, но не в приложении?

Почти всегда дело в кодировании URL. Символ вроде @, / или # в пароле читается как часть структуры URL. Закодируйте его через проценты или сгенерируйте пароль заново только из букв и цифр.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000