Skip to content

Commit 48396d0

Browse files
committed
docs: add Azure Cache for Redis and Redis Enterprise configuration guide (#72)
Fixes #72 - Document proper client configuration for Azure Cache for Redis and Redis Enterprise deployments that use proxy layers. Changes: - Add comprehensive Azure/Enterprise configuration section to README - Add test demonstrating correct client configuration approach - Clarify that standard Redis client should be used, not RedisCluster - Explain proxy architecture and why it requires this configuration The key is that Azure Cache for Redis and similar enterprise deployments use a proxy layer that makes clusters appear as single endpoints. This requires using a standard Redis client rather than a cluster-aware client to avoid detection issues and cross-slot errors.
1 parent cf6a202 commit 48396d0

File tree

3 files changed

+409
-1
lines changed

3 files changed

+409
-1
lines changed

README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,62 @@ If you're using a Redis version lower than 8.0, you'll need to ensure these modu
4040

4141
Failure to have these modules available will result in errors during index creation and checkpoint operations.
4242

43+
### Azure Cache for Redis / Redis Enterprise Configuration
44+
45+
If you're using **Azure Cache for Redis** (especially Enterprise tier) or **Redis Enterprise**, there are important configuration considerations:
46+
47+
#### Client Configuration
48+
49+
Azure Cache for Redis and Redis Enterprise use a **proxy layer** that makes the cluster appear as a single endpoint. This requires using a **standard Redis client**, not a cluster-aware client:
50+
51+
```python
52+
from redis import Redis
53+
from langgraph.checkpoint.redis import RedisSaver
54+
55+
# ✅ CORRECT: Use standard Redis client for Azure/Enterprise
56+
client = Redis(
57+
host="your-cache.redis.cache.windows.net", # or your Redis Enterprise endpoint
58+
port=6379, # or 10000 for Azure Enterprise with TLS
59+
password="your-access-key",
60+
ssl=True, # Azure/Enterprise typically requires SSL
61+
ssl_cert_reqs="required", # or "none" for self-signed certs
62+
decode_responses=False # RedisSaver expects bytes
63+
)
64+
65+
# Pass the configured client to RedisSaver
66+
saver = RedisSaver(redis_client=client)
67+
saver.setup()
68+
69+
# ❌ WRONG: Don't use RedisCluster client with Azure/Enterprise
70+
# from redis.cluster import RedisCluster
71+
# cluster_client = RedisCluster(...) # This will fail with proxy-based deployments
72+
```
73+
74+
#### Why This Matters
75+
76+
- **Proxy Architecture**: Azure Cache for Redis and Redis Enterprise use a proxy layer that handles cluster operations internally
77+
- **Automatic Detection**: RedisSaver will correctly detect this as non-cluster mode when using the standard client
78+
- **No Cross-Slot Errors**: The proxy handles key distribution, avoiding cross-slot errors
79+
80+
#### Azure Cache for Redis Specific Settings
81+
82+
For Azure Cache for Redis Enterprise tier:
83+
- **Port**: Use port `10000` for Enterprise tier with TLS, or `6379` for standard
84+
- **Modules**: Enterprise tier includes RediSearch and RedisJSON by default
85+
- **SSL/TLS**: Always enabled, minimum TLS 1.2 for Enterprise
86+
87+
Example for Azure Cache for Redis Enterprise:
88+
```python
89+
client = Redis(
90+
host="your-cache.redisenterprise.cache.azure.net",
91+
port=10000, # Enterprise TLS port
92+
password="your-access-key",
93+
ssl=True,
94+
ssl_cert_reqs="required",
95+
decode_responses=False
96+
)
97+
```
98+
4399
## Installation
44100

45101
Install the library using pip:

langgraph/checkpoint/redis/aio.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,9 @@ async def alist(
709709
if isinstance(checkpoint_data, dict)
710710
else orjson.loads(checkpoint_data)
711711
)
712-
channel_values = self._recursive_deserialize(checkpoint_dict.get("channel_values", {}))
712+
channel_values = self._recursive_deserialize(
713+
checkpoint_dict.get("channel_values", {})
714+
)
713715
else:
714716
# If checkpoint data is missing, the document is corrupted
715717
# Set empty channel values rather than attempting a fallback

0 commit comments

Comments
 (0)