Queue (Redis)¶
Note
Not part of core. Install it separately:
composer require kinetis/queue-redis
Adds Redis as a backend for Queue. Switching to it changes configuration, not application code.
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
QUEUE_VISIBILITY_TIMEOUT_SECONDS=300
vendor/bin/kinetis queue:work --queue=high,default
Redis transport and Cluster¶
kinetis/queue-redis sends every command through kinetis/redis
(Redis), which Composer installs with it: a transport that never
re-sends a command whose reply it did not receive.
kinetis/redis supports Redis Cluster for application use: its
ClusterClient routes commands by slot (see
Redis Cluster), and kinetis/cache-redis
uses it under REDIS_CLUSTER=true (see Appendix: Satellite Packages).
This queue backend’s supported connection is a
single Redis node. Its scripts name several keys with no shared hash
tag, so it reads its connection’s REDIS_CLUSTER and rejects true
with an InvalidArgumentException naming that key, before any client is
built. It requires REDIS_URL or REDIS_HOST and follows no cluster
redirect, so point it at a standalone Redis server, not at a cluster.
The check reads only the queue connection’s own key: an application
whose cache uses a cluster gives the queue its own server through a
named connection, whose REDIS_JOBS_CLUSTER is unset and so false:
REDIS_CLUSTER=true
REDIS_CLUSTER_SEEDS=10.0.0.1:6379,10.0.0.2:6379,10.0.0.3:6379
QUEUE_CONNECTION_NAME=jobs
QUEUE_JOBS_CONNECTION=redis
REDIS_JOBS_HOST=queue-redis.internal
Configuring¶
Besides QUEUE_VISIBILITY_TIMEOUT_SECONDS, the backend reads the REDIS_*
keys the cache reads, scoped by the queue connection’s name (see
Queue’s “Named connections”): REDIS_URL, or
REDIS_HOST with REDIS_PORT and REDIS_DATABASE; REDIS_PASSWORD;
REDIS_TIMEOUT; and REDIS_TLS, REDIS_TLS_VERIFY_PEER and
REDIS_TLS_CA_FILE. Configuration lists their defaults. The queue opens
its own connection rather than sharing the cache’s, so REDIS_TIMEOUT is
its own per-command budget.
Lease timeout¶
QUEUE_VISIBILITY_TIMEOUT_SECONDS (default 300, at least 1) is how
long a popped job stays leased to its worker. When a worker dies before
settling a job, any worker’s next pop() on that queue takes the job
back once the lease expires, with its attempt count increased. No
separate reaper process runs.
queue:work renews the lease automatically while the job runs, at half
this window, so the setting sizes how long a crashed worker’s job
waits to come back rather than how long a job may take. A handler that
never yields to the event loop cannot be renewed, and neither can one
whose worker has died — delivery stays at-least-once either way.
Redis mechanisms describes the lease
algorithm and Reservation renewal what
the worker does with it.
When a Redis command fails¶
A command whose reply never arrives raises
Kinetis\Redis\Exception\OutcomeUnknown, and the transport never sends
it again. From push(), the job may be queued. From pop(), a job may
stay leased to no worker until its lease expires. From ack(),
release() or fail(), the settlement may or may not have happened and
the job may run again. Kinetis\Redis\Exception\ConnectionFailed means
the command never reached Redis. Raised inside queue:work, either
exception stops the worker.
Connection lifetime¶
The queue opens a Kinetis\Redis\Client of its own rather than sharing
the cache’s, and RedisQueueFactory::fromConfig() hands the queue that
client’s close(). A queue the bootstrap binds, or one
queue:work --connection=<name> builds, has its connection closed when
the worker ends, with no wiring of yours; build the backend
yourself and registering $app->onDispose($queue->dispose(...)) is
yours too. A RedisQueue constructed around an Amp\Redis\RedisClient
you built closes nothing — see Appendix: Queue Contracts’s “Connection
ownership”.
Clearing a queue¶
RedisQueue declares ClearableQueueInterface (see Queue’s
“Clearing is a separate capability”). Clearing removes a queue’s pending
and delayed jobs and reports how many; jobs leased to a running worker
are untouched. queue:stats counts pending jobs, delayed jobs and
expired leases.
Delays and retries¶
A delayed job becomes available on the first pop() sweep after its
delay elapses, so it runs late while every worker is busy. The delay is
measured with the clocks of the pushing and popping hosts, so keep them
synchronized; lease expiry uses the Redis server’s clock. Retries follow
Queue: maxAttempts, QUEUE_MAX_ATTEMPTS and
QUEUE_RETRY_BASE_DELAY_SECONDS. A delayed retry goes into the same
delayed sorted set a delayed push uses, written inside the one fenced
script that removes the lease.
See also¶
Queue — jobs, workers, retries and delivery guarantees.
Appendix: Queue Contracts — the lease algorithm and delivery contracts.
Redis — the transport, Redis Cluster, and what a failed command’s outcome means.
Appendix: Satellite Packages —
kinetis/cache-redis, the cluster-capable cache that reads the sameREDIS_*keys.Configuration — named connections and every
REDIS_*key.