You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 6860a0c
Browse filesBrowse the repository at this point in the historyBrowse files
Add documentation for Redis read routing and replica support
Details the `ReadMode` configuration for Redis providers, including usage examples and safety considerations regarding replication lag for cache, queue, and file storage implementations.
All Redis providers support a `ReadMode` option that controls how read operations are routed in a master-replica topology. By default, reads go to the master node (`CommandFlags.None`). Set `ReadMode` to `CommandFlags.PreferReplica` to distribute reads to replica nodes, reducing load on the master and improving read throughput.
580
+
581
+
### Configuration
582
+
583
+
```csharp
584
+
usingStackExchange.Redis;
585
+
586
+
// Enable replica reads on cache
587
+
varcache=newRedisCacheClient(o=>o
588
+
.ConnectionMultiplexer(redis)
589
+
.ReadMode(CommandFlags.PreferReplica));
590
+
591
+
// Enable replica reads on queue
592
+
varqueue=newRedisQueue<WorkItem>(o=>o
593
+
.ConnectionMultiplexer(redis)
594
+
.ReadMode(CommandFlags.PreferReplica));
595
+
596
+
// Enable replica reads on file storage
597
+
varstorage=newRedisFileStorage(o=>o
598
+
.ConnectionMultiplexer(redis)
599
+
.ReadMode(CommandFlags.PreferReplica));
600
+
```
601
+
602
+
`PreferReplica` is safe on single-node deployments -- it falls back to the master when no replica exists. Write operations always go to the master regardless of this setting. Distributed locks are not affected (all lock operations use writes or Lua scripts on the master).
Redis/Valkey replication is asynchronous. When using `PreferReplica`, reads may return stale data during the replication lag window (typically sub-millisecond on AWS ElastiCache, but variable under load). Review the scenarios below before enabling replica reads.
634
+
:::
635
+
636
+
| Scenario | Risk | Impact |
637
+
|----------|------|--------|
638
+
|**Queue: dequeue payload read**|**High**| After enqueue writes a payload, a dequeue on another process reads it back. If the replica hasn't replicated yet, the payload is `null`, the item is removed from the work list, and the message is silently lost. |
639
+
|**Queue: abandon retry count**| Medium | The attempts counter is incremented on master, then read back during abandon. A stale replica read returns an old count, giving the item one extra retry before dead-lettering. |
640
+
|**Queue: maintenance renewal check**| Medium | Lock renewal writes a timestamp to master. Maintenance reads it to check timeout. A stale read may auto-abandon an item that was just renewed, causing spurious re-processing. |
641
+
|**Queue: maintenance wait time**| Low | Wait times for retry delays are read from cache. A stale read makes an item wait slightly longer before retry. |
642
+
|**File storage: rename after save**| Low-Medium |`RenameFileAsync` reads file content immediately after save. A stale replica read could miss the just-written content. |
643
+
|**Cache: sorted set expiration**| Low | Reads the highest score from a sorted set to determine TTL. A stale read sets a slightly inaccurate expiration. |
644
+
|**Distributed locks**|**None**| Lock acquire, release, and renewal all use writes or Lua scripts that execute on master. |
645
+
646
+
**Per-provider guidance:**
647
+
648
+
-**RedisCacheClient**: `PreferReplica` is safe for most read-heavy workloads. Risk exists only if you read a key immediately after writing it from a different process.
649
+
-**RedisQueue**: Use caution. Under very high throughput, dequeue can fail to read a just-enqueued payload, causing message loss. Consider keeping `CommandFlags.None` for queues processing critical work items.
650
+
-**RedisFileStorage**: Generally safe. The rename-after-save edge case is unlikely in practice.
651
+
572
652
## Next Steps
573
653
574
654
-[Azure Implementation](./azure) - Azure Storage and Service Bus
0 commit comments