1. Caching
For hot data (frequently queried but rarely modified or deleted), Redis cache is the go-to choice. After all, its powerful QPS and strong stability are not matched by all similar tools.
Compared to memcached, Redis also offers a rich set of data types and provides persistence mechanisms like AOF and RDB — you can choose cold, hot, or lukewarm options as needed.
When applying this in practice, one thing to note: many people use Spring’s AOP to build automatic production and cleanup of Redis caches. The process might look like this:
- Before querying the database, check Redis. If the data exists in Redis, use it and skip the database query. If not, query the database and then insert the data into Redis.
- Before updating or deleting from the database, check if the data exists in Redis. If it does, delete it from Redis first, then update or delete from the database.
This approach works fine under low concurrency, but in high-concurrency scenarios, beware of the following:
To perform an update, you first delete the data from Redis. At that moment, another thread executes a query, finds the data missing from Redis, and immediately executes a SELECT query and inserts a row into Redis. Back to the update thread — this unfortunate thread has no idea that the cursed SELECT thread just committed a grave error! And so the incorrect data in Redis persists forever, until the next update or delete.
For the causes of dirty caches like the one above and their solutions, you can refer to an article by Chen Hao: Patterns for Cache Updates. From my personal perspective, except in flash sale scenarios, if your business reaches this level of concurrency, it can likely be avoided at the architectural level.
2. Counters
Applications such as click counting. Due to its single-threaded nature, Redis avoids concurrency issues, guarantees correctness, and delivers 100% millisecond-level performance! Awesome.
Command: INCRBY
After enjoying this, don’t forget persistence (save to database or Redis’ own persistence) — after all, Redis only stores data in memory!
3. Queues
Similar to message systems like ActiveMQ, RocketMQ, etc. Personally, I think it’s fine for simple use cases, but for scenarios requiring high data consistency, use professional systems like RocketMQ.
Since Redis returns the position of the added element in the queue, you can do things like determining which visitor number a user is.
Queues can not only convert concurrent requests into serial ones, but also function as a queue or stack.
4. Bit Operations (Big Data Processing)
Used in scenarios with hundreds of millions of records, such as check-ins for hundreds of millions of users, deduplication of login counts, user online status, etc.
Think about it: with Tencent’s 1 billion users, how would you query whether a specific user is online within a few milliseconds? Don’t tell me you’d create a key for each user and track them individually (you can calculate how terrifying the memory usage would be, and there are many similar needs — imagine how much that would cost Tencent…). The answer here is bit operations — using the setbit, getbit, and bitcount commands.
The principle: Redis internally builds a sufficiently long array, where each element can only be 0 or 1. The array index represents the user ID (must be numeric). So this array, hundreds of millions long, builds a memory system through indices and element values (0 and 1), enabling all the scenarios I mentioned above. The commands used are: setbit, getbit, bitcount.
5. Distributed Locks and Single-Thread Mechanism
- Validate duplicate frontend requests (can be freely extended to similar cases). Filter through Redis: hash the request IP, parameters, interface, etc., as the key stored in Redis (idempotent requests), set an expiration period, then when the next request comes in, check if this key exists in Redis to verify whether it’s a duplicate submission within a certain time window.
- Flash sale systems: leverage Redis’s single-threaded nature to prevent database “explosions.”
- Global incremental ID generation, similar to “flash sales.”
6. Latest Lists
For example, a news list page showing the latest news. If the total volume is very large, try to avoid queries like select a from A limit 10. Instead, use Redis’s LPUSH command to build a List and push items in sequentially. But what if the memory gets cleared? Simple — if the storage key can’t be found, query MySQL and initialize a List in Redis.
7. Leaderboards
Whoever has the highest score ranks at the top. Command: ZADD (sorted set).
Other Common Web Application Scenarios
- Displaying the latest item list on the homepage
Redis uses an in-memory cache, which is very fast. LPUSH inserts a content ID as a keyword at the head of the list. LTRIM limits the number of items in the list to a maximum of 5000. If the data volume users need to retrieve exceeds this cache capacity, only then should the request be sent to the database.
- Leaderboards and related problems
Leaderboards are sorted by score. The ZADD command directly implements this, ZREVRANGE retrieves the top 100 users by score, and ZRANK gets a user’s rank — very direct and easy to use.
- Sorting by user votes and time
This is like Reddit’s leaderboard, where scores change over time. Combined use of LPUSH and LTRIM adds articles to a list. A background task retrieves the list and recalculates the sort order, and ZADD populates the list in the new order. Lists enable very fast retrieval, even on heavily loaded sites.