Using Redis Secondary Indexes to Replace FLUSHDB for Targeted Cache Invalidation
The article examines the risks of using the dangerous FLUSHDB command in Redis, explores common alternatives like SCAN, async deletion, and expiration, and proposes a secondary‑index solution using sets and sorted sets to efficiently invalidate only the affected cache entries without blocking the service.
In response to a business request to enable the FLUSHDB command for clearing cache, the author explains why this operation is blocked in the production Redis service due to its single‑threaded nature and the potential to stall the entire system.
Background
A developer asked for FLUSHDB to clear a database, but the operations team rejected it because long‑running commands can freeze Redis and affect high‑availability monitoring.
Common Alternatives
SCAN
Iterate over all keys with SCAN and delete them manually; however, this may accidentally remove live data and cause blocking if many keys are processed.
Async Deletion
Redis 4.0+ supports FLUSHDB ASYNC , which runs without blocking the main thread, but the command is still blocked in the managed environment, requiring manual intervention.
Expiration
Use EXPIRE or EXPIREAT to schedule key removal based on time, which does not help when deletions are triggered by events.
Scenario Reconstruction
The business runs an online store where query results are cached in Redis as lists, keyed by the query parameters. When a product attribute (price, sales, etc.) changes, the cached query must be invalidated, otherwise the database receives a surge of requests.
Proposed Solution – Secondary Index
Instead of flushing the whole DB, maintain a many‑to‑many mapping between products and the query keys that depend on them. Store each product’s related query keys in a Redis SET (e.g., product:$id → set of query keys). When a product changes, iterate only over that set to delete or update the relevant cache entries.
LPUSH query:xxxxx:xxxxx
SADD product1 query:xxxxx:xxxxx
SADD product2 query:xxxxx:xxxxx
SADD product3 query:xxxxx:xxxxx
...
SADD productN query:xxxxx:xxxxxThese commands can be pipelined for efficiency.
Redis Secondary Index Example
To illustrate secondary indexes, the article shows a user‑age lookup. Three users are stored as hashes, and a sorted set user.age.index records each user’s age as the score.
HMSET user:1 id 1 username antirez ctime 1444809424 age 38
HMSET user:2 id 2 username maria ctime 1444808132 age 42
HMSET user:3 id 3 username jballard ctime 1443246218 age 33After adding the ages to the sorted set:
ZADD user.age.index 38 1
ZADD user.age.index 42 2
ZADD user.age.index 33 3Finding users aged 30‑39 becomes a single ZRANGEBYSCORE call, returning the matching user IDs, which can then be fetched with HGET .
Conclusion
Using secondary indexes (sets, sorted sets, etc.) provides a scalable way to invalidate only the necessary cache entries in Redis, avoiding the heavy‑handed FLUSHDB approach while keeping the service responsive.
NetEase Game Operations Platform
The NetEase Game Automated Operations Platform delivers stable services for thousands of NetEase titles, focusing on efficient ops workflows, intelligent monitoring, and virtualization.
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.