-
-
Notifications
You must be signed in to change notification settings - Fork 35
Description
Background
Currently, the Redis adapters in this project use a single Redis client (and thus a shared connection pool) for both reading/polling operations and writing operations.
The Problem
Using a single Redis client for both read and write operations introduces significant performance and scalability bottlenecks under heavy load:
- Connection Blocking / Pool Starvation: Read operations like
XREAD BLOCK(in Redis Streams) orSUBSCRIBE(in standard Redis Pub/Sub) are blocking or long-lived by nature. Sharing the same connection pool for high-throughput write operations (e.g.,XADD,PUBLISH,SETfor session persistence) can lead to connection starvation, where writes are delayed because connections are held by blocking reads. - Inability to Scale via Redis Replicas: In production environments, it is a common best practice to route read operations to Redis Replicas and write operations to the Redis Master. The current single-client design prevents users from utilizing Redis read replicas effectively.
Affected Adapters
This issue applies to all current Redis-based adapters:
RedisAdapterShardedRedisAdapterRedisStreamsAdapter
Proposed Solution
We should introduce read/write separation by allowing users to provide two distinct Redis clients in the adapter options.
For example, following the convention in the official socket.io-redis ecosystem, the API could accept a pubClient (for writes/publishing) and a subClient (for reads/subscribing/polling):
// Example API design
type RedisAdapterOptions struct {
WriteClient *redis.RedisClient // Used for PUBLISH, XADD, SET, etc.
ReadClient *redis.RedisClient // Used for SUBSCRIBE, XREAD, GET, etc.
// ... other options
}(If only one client is provided, it can fallback to using the same client for both to maintain backward compatibility).
Benefits
- Performance: Eliminates the risk of blocking read operations starving the connection pool for write operations.
- High Availability & Scaling: Allows users to configure the
ReadClientto target a Redis read-replica endpoint, distributing the load and preventing the Redis Master from being overwhelmed. - Ecosystem Consistency: Aligns with the standard Node.js
socket.io-redisimplementation which heavily utilizes separatepubClientandsubClientconfigurations.