Redis - Dive Deep
Here is some data structure in Redis
Data Structure
1. String
- Basic type (binary-safe), can store up to 512MB.
- Used for counters, caching, JSON, serialized objects.
SET key "value"
INCR counter
2. List
- Linked list
- Used for queues, message streams
LPUSH tasks "task1"
RPOP tasks
LRANGE tasks 0 -1
LINDEX tasks 2
RPOP tasks
3. Set
- Use for unique strings.
- Used for white list ID, unique users
SADD users "user1"
SISMEMBER users "user1"
4. Sorted Set (ZSet)
- Like Set but sorted by a score.
-
Used for leaderboard, ranking
ZADD leaderboard 100 "player1" ZRANGE leaderboard 0 -1 WITHSCORES
5. Hash
- Key-value object with redis key
-
Use for storing json
HSET user:1 name "Alice" age 25 HGETALL user:1
6. Bitmap
-
Use for tracking daily active user
SETBIT active_users:2025-02-01 5 1 GETBIT active_users:2025-02-01 5 BITCOUNT active_users:2025-02-01
7. Hyper loglog (for large set)
- Use case: Unique visitor
-
PF stands for “Probabilisitic Function”
PFADD unique_visitors "user1" PFCOUNT unique_visitors
8. Geospatial Index
-
Use case: latitude, longitude and query by Radius.
GEOADD places 105.84 21.03 "Hanoi" GEORADIUS places 105.84 21.03 10 km
9. Streams
-
Use case: log-based stream for Kafka lite ⇒ High traffic but we polling overtime and time.
XADD mystream * message "one" XADD mystream * message "two" XADD mystream * message "three" XRANGE mystream - +1763906094688-0 1763906094689-0 1763906094691-0 ----- 1763906094688-0 message one 1763906094689-0 message two 1763906094691-0 message three - You can delete but it harder because you need to find the timestamp key.
-
Create consumer group in Redis
XGROUP CREATE mystream group1 0-0XREADGROUP GROUP group1 consumer1 COUNT 1 STREAMS mystream >>= give only messages not yet delivered to any consumer in group- Using Consumer Groups + Acknowledgments (XACK): Redis ensures a message is delivered to only one consumer within a group ⇒ This ensures at least-once delivery, not exactly-once.
- Streams are immutable.
- Idea: Like kafka but consumer manual polling.
10. JSON (trí tuệ)
- Use case: used to store JSON
-
Syntax
$is a path to store json.JSON.SET user:1 $ '{"name":"Alice"}' JSON.SET user:1 $.profile '{"city":"Hanoi"}'{ "name": "Alice", "profile": { "city": "Hanoi" } }redis-server --loadmodule /path/to/rejson.so
11. Time series value
-
Using RedisTimeSeries Module.
TS.ADD temperature:room1 * 25.3 -
Query data in range
TS.RANGE temperature:room1 1670000000000 1670000005000 AGGREGATION avg 5000
Persistence Options
- RDB (Redis Database): Captures the dataset’s point-in-time snapshots at specified intervals.
- AOF (Append Only File): Logs every write operation received by the server, which, upon restart, can reapply to reconstruct the original dataset.
Transaction Redis
1. Transaction Comand
MULTI
SET key1 "value1"
INCR counter
LPUSH list "task"
EXEC
2. Optimistic Locking using WATCH
WATCH user:balance
val = GET user:balance
if val >= 100:
MULTI
DECRBY user:balance 100
EXEC
else:
UNWATCH
# Not enough balance
- ✔ If
balancehasn’t changed → transaction runs - ❌ If someone modified
balance→ transaction aborts (returns nil) → you retry
Note: Because single-thread, we do not need to use persimistic clock.
Pub/Sub System
PUBLISH channel_name "Hello World"
SUBSCRIBE channel_name
Cluster Mode
- Sharding keys in multiple nodes.
Architecture
- Single thread
- Non-blocking I/O multiplexing:
- Handle multiple connection with a single thread.
- Background process
- RDB and AOF
Use case
1. Session Store
-
Based on time to live to auto remove the session.
TTL mykey # Check remaining time PTTL mykey # In milliseconds
1️⃣ Lazy (Passive) Expiration
- If the key is expired → it deletes it immediately
- If not expired → return normally
SET key "value"
EXPIRE key 10
# After 10s...
GET key # Redis checks -> expired -> deletes -> returns NULL
2️⃣ Active Expiration – background cleanup
- Redis periodically runs an internal process (~10 times per second) to scan for expired keys and delete them.
2. Dynamic Rate Limiting:
# Allow max 5 requests per 10 seconds
INCR user:123:rate
EXPIRE user:123:rate 10
if INCR > limit → block
else allow
3. Graph in Redis
4. Full-text search in Redis
-
Fuzzy search: Searching for
"aple"would still return"apple".FT.CREATE products_idx ON HASH PREFIX 1 product: SCHEMA name TEXT description TEXT price NUMERICHSET product:1 name "Apple iPhone 14" description "A powerful smartphone" price 999 HSET product:2 name "Samsung Galaxy" description "Android flagship phone" price 899 HSET product:3 name "Apple Watch" description "Smart wearable device" price 399FT.SEARCH products_idx "iphone" FT.SEARCH products_idx "apple smartphone"FT.SEARCH products_idx "apple" FILTER price 400 1000 FT.SEARCH products_idx "apple" FILTER price 400 1000 FT.SEARCH products_idx "aple~" # finds "apple" FT.SEARCH products_idx "%aple%" FUZZY FT.SEARCH idx "hello =>[KNN 3 @embedding $vec AS score]" PARAMS 2 vec $BINARY_VECTOR SORTBY score
5. Distributed lock in Redis
-
Do not special CLI → (key, random_value)
SET lock:key "unique_value" NX EX 10- NX: not exist.
- EX: expire time.
6. Redis AI
- FT: Full-text search
HSET doc:1 content "Hello world" \
embedding "\x00\x01\x02...binary vector bytes"
FT.SEARCH my_index "*=>[KNN 3 @embedding $vec AS score]" \
PARAMS 2 vec "\x00\x01\x02..." \
SORTBY score \
RETURN 2 content score
Redis for AI
| Redis Feature | AI Use Case |
|---|---|
VECTOR SEARCH |
Embeddings lookup |
FT.SEARCH |
Hybrid full-text + semantic search |
JSON |
Store LLM chat state |
STREAMS |
Async AI inference queue |
CACHE |
Response caching |
Time series (TS.*) |
Track quality / spikes |
Redlock |
Distributed locking for training |
| Pub/Sub | Live updates |
Notes: Using KNN for query semantic search in vector database.