ITADN

Optional cross-slot mget helper for Redis Cluster (scatter-gather)

#3198ClosedtheSatvik 创建于 2026-03-16
T
theSatvikcommented
### Description When using Redis Cluster with the Node.js clients (`node-redis` / `ioredis`), multi-key commands such as `MGET` only work when all keys belong to the same hash slot. Otherwise Redis returns a `CROSSSLOT` error. While this behavior is correct according to Redis Cluster semantics, other client libraries (e.g. Go and Python) provide a convenience abstraction where `MGET` internally performs a scatter-gather: 1. compute hash slot for each key 2. group keys by cluster node 3. send parallel `MGET` commands per node 4. merge results and return them in the original order This allows developers to efficiently retrieve multiple keys across the cluster without manually implementing slot grouping and pipelining. ### Problem Currently in Node.js, users must manually implement this logic every time they need a cluster-wide multi-key read. In many applications (cache lookups, session reads, user state fetches, etc.), retrieving multiple unrelated keys is common. Typical workarounds today are: * manually issuing multiple `GET` calls * building custom slot-grouping utilities * redesigning key schemas to force hash-slot colocation However, the first two approaches lead to duplicated implementations across projects. ### Proposed Solution Provide an **optional helper API** that performs scatter-gather internally without modifying the semantics of the existing `mget` command. Example API: ```js await cluster.mgetCluster(["k1", "k2", "k3"]) ``` Possible implementation strategy: 1. calculate slot for each key 2. map slots to cluster nodes 3. group keys per node 4. send `MGET` commands to each node in parallel (pipelined if needed) 5. merge responses while preserving the original key order This keeps the current behavior of `mget()` unchanged while providing an opt-in utility for cluster users. ### Benefits * reduces duplicated scatter-gather implementations * improves ergonomics for cluster users * maintains compatibility with existing Redis semantics * aligns with convenience features provided in other Redis client ecosystems ### Alternatives * continue implementing custom scatter-gather utilities in application code * enforce key schema design using hash tags ### Additional Context Many high-throughput systems already implement this logic internally to efficiently fetch multiple keys across Redis Cluster nodes. Providing a helper at the client level could standardize this pattern for the Node.js ecosystem. ### Basic Code Example ```JavaScript async function mgetScatter(keys) { const nodeGroups = new Map(); const results = new Array(keys.length); const keyIndex = new Map(); // store original ordering keys.forEach((key, i) => keyIndex.set(key, i)); // group keys by node for (const key of keys) { const slot = calculateSlot(key); const node = cluster.nodes("master").find(n => { const slots = n.slots; return slots.some(([start, end]) => slot >= start && slot <= end); }); if (!nodeGroups.has(node)) { nodeGroups.set(node, []); } nodeGroups.get(node).push(key); } // send parallel MGET per node const tasks = []; for (const [node, nodeKeys] of nodeGroups.entries()) { tasks.push( node.mget(...nodeKeys).then(values => { values.forEach((val, i) => { const key = nodeKeys[i]; results[keyIndex.get(key)] = val; }); }) ); } await Promise.all(tasks); return results; } ```
关闭于 2026-03-17 2 条评论