Skip to content

Redis Key Topology & Data Structures ​

OxMQ strictly adheres to BullMQ v5's Redis key topology. Understanding these keys helps during cluster operations, capacity planning, and debugging with tools like redis-cli or Bull-Board.


🗄️ Redis Key Architecture ​

Assuming the default prefix bull and queue name orders:

Redis KeyTypeDescription
bull:orders:idStringAtomic integer counter generating unique sequential job IDs.
bull:orders:metaHashQueue metadata (e.g. paused state, custom prefix configuration).
bull:orders:waitListFIFO list holding IDs of jobs waiting to be claimed by workers.
bull:orders:activeListList holding IDs of jobs currently locked and executing on workers.
bull:orders:delayedSorted SetScheduled/delayed jobs scored by millisecond execution timestamp.
bull:orders:pausedListJobs waiting while the queue is paused.
bull:orders:waiting-childrenSorted SetParent DAG jobs scored by remaining pending children count.
bull:orders:completedSorted SetIDs of successfully finished jobs scored by completion timestamp.
bull:orders:failedSorted SetIDs of failed jobs scored by failure timestamp.
bull:orders:stalledSorted SetIDs of jobs whose worker lock expired without completion.
bull:orders:<jobId>HashThe primary job record (payload, options, timestamps, attempts).
bull:orders:<jobId>:logsListAppend-only list of chronological string logs recorded for the job.
bull:orders:<jobId>:processedHashIn DAG workflows, stores return values from completed child jobs.
bull:orders:eventsStreamRedis stream emitting real-time events (active, completed, etc.).
bull:orders:limiterSorted SetSliding window timestamps used for rate limiting.
bull:orders:repeatSorted SetRegistered recurring/cron job schedulers.

🔍 Inspecting Keys with redis-cli ​

1. View Waiting Jobs Count ​

bash
redis-cli LLEN bull:orders:wait

2. Inspect an Individual Job Hash ​

bash
redis-cli HGETALL bull:orders:101

Sample output:

text
1) "name"
2) "process-payment"
3) "data"
4) "{\"orderId\":\"ord_101\",\"amount\":99.0}"
5) "opts"
6) "{\"attempts\":3,\"delay\":0}"
7) "timestamp"
8) "1773321600000"
9) "processedOn"
10) "1773321600050"
11) "attemptsMade"
12) "1"

3. Check Delayed Jobs ​

bash
# Get the next 5 delayed jobs ordered by due timestamp
redis-cli ZRANGE bull:orders:delayed 0 4 WITHSCORES

4. Read Live Stream Events ​

bash
# Read the last 5 events emitted by the queue
redis-cli XREVRANGE bull:orders:events + - COUNT 5

🌐 Redis Cluster & Hash-Tag Routing ​

In Redis Cluster, keys are partitioned across 16,384 hash slots. Multi-key operations and atomic Lua scripts require that all keys referenced in the script hash to the exact same slot.

1. Single Queue Cluster Tagging ​

By default or when enabling oxmq.cluster-hash-tags=true (or OXMQ_CLUSTER_HASH_TAGS=true), OxMQ wraps {prefix:queueName} in curly braces so all keys for that queue (wait, active, meta, etc.) hash to the identical slot:

{bull:orders}:wait
{bull:orders}:active
{bull:orders}:101

2. Multi-Queue DAG Workflows (FlowProducer.forCluster) ​

When running parent-child workflows where parent and children reside on different queues (e.g. order-queue and inventory-queue), child completion atomically updates the parent job in the same Lua script.

To guarantee zero CROSSSLOT exceptions in Redis Cluster, use FlowProducer.forCluster(...) with a shared cluster workflow tag:

java
// Guarantees all queues in this workflow hash to CRC16("order-pipeline")
FlowProducer flowProducer = FlowProducer.forCluster("order-pipeline", connectionManager);

FlowJob<String> child = FlowJob.of("inventory-queue", "reserve", itemSku);
FlowJob<String> parent = FlowJob.of("order-queue", "charge", orderId);
parent.addChild(child);

// Enqueued with keys:
// {order-pipeline}:bull:order-queue:...
// {order-pipeline}:bull:inventory-queue:...
flowProducer.add(parent);

Or configure custom QueueKeys directly:

java
QueueKeys keys = QueueKeys.forClusterFlow("order-pipeline", "bull", "inventory-queue");

Released under the Apache 2.0 / MIT Open-Source Licenses.