Why the Redis KEYS Command Is Dangerous and How to Replace It
The article explains that Redis's KEYS command scans all keys, blocks the server for seconds, can trigger failover issues, and provides faster alternatives like SCAN or storing keys in a set, while also showing how KEYS works in a Redis Cluster and its real‑world latency measurements.
What the KEYS Command Does
The KEYS pattern command scans the entire keyspace of a Redis instance and returns every key that matches the given pattern (which can be a glob‑style pattern, not a full regular expression). Because it must examine every key, the command is O(N) in the number of keys and blocks the Redis event loop while it runs.
Risks in Production
While KEYS is executing, the Redis server cannot process any other commands. If the block lasts longer than the Sentinel down‑after‑milliseconds timeout, Sentinel may start a failover. Should the original master recover during the failover, a split‑brain situation can arise, potentially causing data inconsistency.
For this reason the KEYS command is generally disabled in production environments.
Common Alternatives
Use SCAN (or SSCAN, HSCAN, ZSCAN) to iterate over keys incrementally. SCAN returns a small batch of keys per call and never blocks the server.
Maintain a dedicated SET that contains the identifiers you need to enumerate. This avoids a full keyspace scan, but be aware that very large sets become “big keys” and can affect memory fragmentation.
Execution in Redis Cluster (Jedis Example)
In a Redis Cluster the KEYS command does not know which node holds a particular key, unlike GET. The Java Jedis client therefore executes KEYS on every cluster node and merges the results before returning them to the caller.
public Set<byte[]> keys(byte[] pattern) {
// Execute KEYS on each node
Collection<Set<byte[]>> keysPerNode = connection.getClusterCommandExecutor()
.executeCommandOnAllNodes((JedisClusterCommandCallback<Set<byte[]>>) client -> client.keys(pattern))
.resultsAsList();
// Merge results into a single set
Set<byte[]> keys = new HashSet<>();
for (Set<byte[]> keySet : keysPerNode) {
keys.addAll(keySet);
}
return keys;
}This code shows that the client issues KEYS on each node, collects the per‑node sets, and returns the union.
Performance Observation
A slow‑query log from a Tencent Cloud Redis Cluster recorded a KEYS execution time of roughly 250 ms – 300 ms. The cluster node held about 1.53 million keys, consuming >300 MB of memory, with an average key‑value size of 0.208 KB (213 bytes).
Because KEYS only returns key names, its latency scales with the total number of keys, not with the size of the values. Extrapolating from the observed data, a node storing ~3 GB of data (proportionally more keys) could block the server for around 3 seconds during a KEYS operation.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
dbaplus Community
Enterprise-level professional community for Database, BigData, and AIOps. Daily original articles, weekly online tech talks, monthly offline salons, and quarterly XCOPS&DAMS conferences—delivered by industry experts.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
