Pro Features
Общие переменные — Redis
Общее состояние между машинами агентов — Redis-драйвер шагов shared variables в распределённых мульти-инстанс прогонах
Обзор
Общие переменные координируют VU внутри
прогона — очереди producer/consumer, общие счётчики, барьеры. Встроенный
драйвер memory делит их между VU одного процесса агента. Драйвер
redis на этой странице — платная возможность (тарифы Scale и
Enterprise), которую зарегистрированные платные агенты добавляют на тот же
seam драйверов: хранилище переезжает в Redis-сервер, и все агенты,
указывающие на него, делят одно состояние — очередь, наполняемая на
одной машине, разбирается на другой.
На OSS-сборке, или на агенте без настроенного URL, driver: redis падает с
перечнем зарегистрированных драйверов — всегда видно, какая сборка нужна.
Всё остальное идентично драйверу memory — форма шага, операции
(set / get / increment / append / pop), блокирующий wait_for,
маппинги extract и обязательные объявления shared_variables: с
валидацией до старта. Меняется только хранилище:
| Драйвер | Хранилище | Общее между |
|---|---|---|
memory (по умолчанию) | Карта внутри процесса | VU одного процесса агента |
redis | Redis-сервер | VU всех агентов, указывающих на сервер |
Настройка агента
URL Redis — настройка уровня агента: общая переменная — это
инфраструктура, а не эндпоинт конкретного шага, поэтому url в шаге нет.
Каждый агент, который должен присоединиться к общему хранилищу, запускается
с:
# .env на машине агента
PERFSCALE_SHARED_REDIS_URL=redis://:secret@redis.internal:6379/0
redis://[:password@]host:6379[/db], илиrediss://для TLS.- Агенты без этой переменной просто не регистрируют драйвер — их шаги с
driver: redisпадают с перечнем зарегистрированных драйверов. - Два независимых окружения на одном Redis-сервере: используйте разные
логические БД в URL (
/0,/1, …) — имя переменной ничего не значит между БД. - Агенты на другой машине: не публикуйте «голый» Redis на публичном порту.
В infra compose есть
redis-gateway— nginx stream с TLS-терминацией на:6479; внешние агенты используютrediss://:<password>@<host>:6479/0.
Соединение мультиплексированное и само восстанавливается; сбой брокера рушит затронутый шаг, а не агента.
Пример
Объявления живут в конфиг-файле, точно так же, как с memory:
# config.yaml
shared_variables:
pending_orders: [] # список → append / pop
approved_count: 0 # число → increment
# producer.yaml — запускается на агенте A
steps:
- name: enqueue order
use: std/set_shared_variable@v1
with:
driver: redis
name: pending_orders
op: append
value: { id: "${{ uuid }}", total: 42.50 }
# consumer.yaml — запускается на агенте B, разбирает то, что произвёл A
steps:
- name: take next order
use: std/get_shared_variable@v1
with:
driver: redis
name: pending_orders
op: pop
wait_for: { length_gte: 1, timeout_ms: 10000 }
outputs:
order_id: value.id
Атомарность — одна Redis-команда на операцию
Каждая операция маппится на одну атомарную серверную команду — тот же
контракт, что драйвер memory даёт одним захватом блокировки. Нет пары
«прочитал-изменил-записал», которой можно было бы срасовать, и нет
примитива блокировки, на котором можно было бы зависнуть.
| Операция | Redis-команда | Результат |
|---|---|---|
increment (целая дельта) | INCRBY | новое значение, остаётся целым |
increment (дробная дельта) | INCRBYFLOAT | новое значение |
append | RPUSH | новая длина списка |
pop | LPOP | первый элемент, null для пустого |
set | SET / DEL+RPUSH (списки) | записанное значение |
get | GET / LRANGE (списки) | записанное значение |
Значения хранятся так, чтобы эти команды применялись напрямую: числа —
простыми строками, элементы списков — JSON, остальные скаляры — JSON-строками.
get различает список и скаляр через серверный TYPE ключа, поэтому агенты
всегда корректно читают записи друг друга.
Жизненный цикл прогона
- Ключи живут по адресу
perfscale:shared:<name>. - Старт прогона: каждый агент пересиживает объявленные ключи (
DEL+ начальное значение) и удаляет ключи, оставшиеся от его прошлого прогона. Прогон всегда стартует с объявленных начальных значений — перенос состояния между прогонами намеренно невозможен. - Старт нескольких агентов: каждый агент пересиживает в момент
своего старта, поэтому значение, записанное до подключения последнего
агента, будет сброшено. Паттерны, строящие состояние во время прогона
(блок
before:, наполняющий очередь, одновременно стартующие producer'ы), не затронуты; не рассчитывайте на «прогретое» хранилище, пока все агенты не подключились. wait_forопрашивает сервер с небольшой паузой между проверками — на удалённом Redis каждый опрос это сетевой round-trip, поэтому выбирайте таймауты в секундах, а не в миллисекундах.