skip to content

Which Redis commands and features behave differently, or stop working entirely, when an application moves from a single Redis instance to Redis Cluster mode?

level: middleimportance: should knowfreq 45%

answer

  1. only db 0: no SELECT n, no SWAPDB, no MOVE
  2. KEYS/SCAN/DBSIZE/FLUSHALL are per node
  3. SCRIPT LOAD and FUNCTION LOAD per master
  4. classic PUBLISH broadcasts; SPUBLISH is per shard (7.0+)
  5. WAIT and blocking commands are per shard

basics

~20 s

Only database 0 exists, so SELECT beyond 0, SWAPDB and MOVE are gone. Multi-key commands, scripts and transactions must stay within one slot. KEYS, SCAN, DBSIZE, FLUSHALL and RANDOMKEY act per node and need fan-out. Classic Pub/Sub broadcasts cluster-wide unless you use sharded channels.

solid answer

~50 s

Four groups of change: **1. Multiple databases disappear.** Cluster supports only db 0: `SELECT 1` errors, and `SWAPDB` and `MOVE` are unavailable. Namespacing must move into key prefixes. **2. Multi-key scope.** Any command naming several keys, plus `EVAL`/`FCALL` and `MULTI` blocks, must stay inside one hash slot or fail with `CROSSSLOT`. **3. Administrative and scanning commands become per-node.** `KEYS`, `SCAN`, `DBSIZE`, `RANDOMKEY`, `FLUSHDB`/`FLUSHALL`, `INFO keyspace` and script caching each address one node; a cluster-wide operation means iterating every master (`redis-cli --cluster call`). `SCRIPT LOAD`/`FUNCTION LOAD` likewise must run on every master. **4. Pub/Sub changes shape.** Classic `PUBLISH` is propagated across the cluster bus to every node, which costs bandwidth at scale; Redis 7.0 added sharded Pub/Sub (`SPUBLISH`/`SSUBSCRIBE`) where the channel name is hashed to a slot and stays on one shard. Also: `WAIT` is per shard, and keyspace notifications are node-local.

code

text · 12 lines
text
> SELECT 1
(error) ERR SELECT is not allowed in cluster mode

> DBSIZE                       # only this node's slots
(integer) 2103440

$ redis-cli --cluster call 127.0.0.1:7000 DBSIZE     # fan out to every master
$ redis-cli --cluster call 127.0.0.1:7000 SCRIPT LOAD "return 1"

# 7.0+ sharded pub/sub: channel name is hashed to a slot
> SSUBSCRIBE orders:{eu}
> SPUBLISH orders:{eu} "created"

go deeper

for a junior

Name the headline changes: only database 0, multi-key commands must share a slot, and KEYS/DBSIZE only see one node.

for a middle

Add script and function distribution per master, blocking-command scope, and the Pub/Sub broadcast versus sharded distinction.

for a senior

Turn it into a migration checklist - grep for SELECT, KEYS, FLUSHALL, multi-key and EVAL usage - and explain the fan-out tooling and the WAIT per-shard caveat.

for a principal

Discuss what the loss of databases and cluster-wide primitives means for isolation strategy: prefixes are not isolation, and genuinely independent workloads may warrant separate clusters.

## Why anything changes at all Every Redis Cluster node owns a subset of slots and serves commands locally. Anything whose semantics implicitly assumed "one process holds the entire keyspace" either becomes per-node, becomes restricted, or is removed. ## Databases are gone Standalone Redis has 16 logical databases selectable with `SELECT`. Cluster mode supports **only database 0**. `SELECT` with a non-zero index returns an error, and `SWAPDB` and `MOVE` (which moves a key between databases) are unavailable. Applications that used databases for environment or tenant separation must switch to key prefixes - and note that prefixes do not isolate `FLUSHDB`, memory accounting, or `SCAN` cost the way separate databases did, so genuinely independent workloads often want separate clusters instead. ## Multi-key scope restrictions Covered in depth elsewhere, but for completeness: `MGET`/`MSET`, set and sorted-set store operations, `RENAME`, `COPY`, `SMOVE`, `LMOVE`, `PFMERGE`, `BITOP`, `ZRANGESTORE`, multi-stream `XREAD`, `SORT ... BY/GET`, multi-key `DEL`/`EXISTS`/`TOUCH`, and any `EVAL`/`FCALL` or `MULTI` block must confine themselves to a single hash slot. Some clients transparently split a few of these per node, at the cost of atomicity. ## Keyspace-wide commands become per-node These still exist, but their scope silently shrinks to the node you sent them to: - `KEYS`, `SCAN`, `RANDOMKEY`, `DBSIZE`, `INFO keyspace`, `MEMORY STATS`, `FLUSHDB`, `FLUSHALL` - each covers only that node's slots. A cluster-wide sweep means iterating over every master. `redis-cli --cluster call <node> <cmd>` fans a command out, and `redis-cli --scan` against each master collects the full keyspace. - This is a frequent source of wrong conclusions: "we only have 2 million keys" measured with one `DBSIZE` on a six-master cluster. - Cursor semantics also change: a `SCAN` cursor is meaningful only for the node that issued it; you cannot carry it to another node. ## Script and function distribution `SCRIPT LOAD` populates the script cache of one node (and its replicas via replication). `EVALSHA` against a master that never saw the script returns `NOSCRIPT`, which well-behaved clients handle by re-sending the full source. `FUNCTION LOAD` (Redis 7.0+) is likewise per-shard, so libraries must be loaded on every master and re-loaded when a new shard joins. `SCRIPT FLUSH`/`FUNCTION FLUSH` are equally node-local. ## Pub/Sub Classic `PUBLISH`/`SUBSCRIBE` still work and preserve cluster-wide semantics: a message published on any node is propagated over the cluster bus so subscribers on any node receive it. The cost is that every publish is broadcast to all nodes regardless of where subscribers are, which does not scale with cluster size. Redis 7.0 introduced **sharded Pub/Sub**: `SPUBLISH`/`SSUBSCRIBE`/`SUNSUBSCRIBE` hash the *channel name* to a slot, so the message stays within the shard owning that slot and clients must subscribe on the right node. That scales, at the price of channel-to-shard affinity. Keyspace notifications are node-local too - you must subscribe on every master to see all events. ## Other differences worth naming - **`WAIT`** asks for acknowledgements from replicas of the node handling the command, so it is a per-shard guarantee, not a cluster-wide one. - **Blocking commands** (`BLPOP`, `BRPOPLPUSH`, `BLMOVE`, `XREAD BLOCK`) work, but only over keys in one slot, and the block is on one node - a failover cancels it. - **Client-side caching / RESP3 invalidation** is per-connection to a node, so a client caching keys from several shards maintains several invalidation channels. - **Cluster-specific commands appear**: `CLUSTER KEYSLOT`, `CLUSTER SHARDS`, `CLUSTER COUNTKEYSINSLOT`, `CLUSTER SETSLOT`, `ASKING`, `READONLY`/`READWRITE`. - **Connections are per node**, so connection counts, `CONFIG SET` and `maxmemory` are all per node; changing configuration means fanning out. ## How to prepare for a migration Grep the codebase for: `SELECT`, `SWAPDB`, `MOVE`, `KEYS`, `FLUSHALL`, `RANDOMKEY`, multi-key commands, `EVAL` calls with more than one key or with runtime-built keys, `MULTI` blocks, and Pub/Sub usage. Each hit is either a rewrite, a hash-tag decision, or a fan-out. Doing this inventory before the cutover is far cheaper than discovering the constraints one production error at a time.

  • An operator runs DBSIZE on one node of a six-master cluster and reports the cluster's key count. What is wrong?
    DBSIZE only counts keys in the slots owned by that node, so the number is roughly a sixth of the truth and is skewed by uneven slot assignment. Cluster-wide totals require fanning the command out to every master and summing, for example with redis-cli --cluster call.
  • Why did Redis 7.0 add sharded Pub/Sub when classic Pub/Sub already works in cluster mode?
    Classic PUBLISH propagates every message over the cluster bus to all nodes so that a subscriber anywhere receives it, which means publish cost grows with cluster size regardless of where subscribers are. Sharded Pub/Sub hashes the channel name to a slot and keeps the message inside that shard, so throughput scales with the number of shards at the cost of clients having to subscribe on the owning node.

saying these in an interview costs you the question

  • Using multiple Redis databases and expecting SELECT to work in cluster mode
  • Reporting DBSIZE, KEYS or SCAN results from one node as cluster-wide
  • Assuming SCRIPT LOAD or FUNCTION LOAD reaches every master automatically
  • Thinking classic PUBLISH is cheap in a large cluster
  • Believing WAIT gives a cluster-wide durability acknowledgement

context