1. Ticket-Craze-Redis
```
User places order
→ MySQL deducts inventory (UPDATE skus SET stock = stock - 1)
→ If successful → redirect to payment
→ Payment success → write order + order_items
→ Payment failure → MySQL adds inventory back
```
##### Core Requirement: Improve performance without overselling
### Step 1: Problem Emerges (High Concurrency Scenario)
10,000 people grab the same product → row lock queuing
MySQL CPU spikes, response slows, even overselling
At this point introduce: Pessimistic lock (MySQL SELECT ... FOR UPDATE)
Why needed: Prevent concurrent reads of the same inventory value
- Cost: Long lock wait time, low throughput
- Transition: This shows MySQL is not suitable for high concurrency scenarios, we need a faster solution
### Step 2: Introduce Redis (Solve High Concurrency & Lock Contention)
```
User places order
→ Redis deducts inventory (DECR)
→ If successful → initiate payment
→ Kafka / async or Node.js write back to MySQL
```
##### Why is Redis inventory deduction fast?
| Feature | Meaning | Benefit |
|---|---|---|
|**Memory storage**|All data in memory|Operation speed is hundreds of times faster than disk database|
|**Single-threaded model**|All commands execute sequentially|No multi-thread competition issues|
##### Atomicity: Why Use Lua Scripts?
Because sometimes we need to do two operations: check if inventory is sufficient, deduct inventory
If you write two Redis commands:
```
if redis.call("get", "stock:123") > 0 then redis.call("decr", "stock:123") return 1 else return 0 end
```
Under high concurrency this may cause problems:
Two people almost simultaneously execute the first line, both see "inventory > 0", both proceed to deduct, resulting in inventory being deducted to negative (overselling).
Redis allows you to write Lua scripts, so Redis will execute it all at once:
```
if redis.call("get", "stock:123") > 0 then
redis.call("decr", "stock:123")
return 1
else
return 0
end
```
- This entire logic is completed in one step inside Redis, others cannot interrupt.
- Why needed: Check + deduct must be atomic
> Redis doesn't replace MySQL, but adds a layer of _cache/rate limiting_
##### **New Problem:**
- What if Redis crashes? Data loss?
- How do multiple Redis nodes guarantee consistency?
### Step 3: What If Redis Crashes?
> Because Redis is an in-memory database, data may not have been written to disk yet.
Causes problem: Overselling
Redis has already deducted inventory (-1), but the async write to MySQL hasn't executed yet. Redis crashes and restarts, data is lost → At this point Redis and MySQL inventory are inconsistent!
```
- User places order → Redis `DECR stock:123`, inventory goes from 10 → 9
- Redis returns success, user enters "payment" flow ✅
- But at this point: MySQL hasn't been updated by async task yet
- Redis suddenly crashes (e.g., downtime, no persistence, RDB/AOF not written yet) 💥
- After Redis restarts, inventory returns to 10 (memory lost)
- Next user places order → Redis thinks inventory still has 10, allows purchase again
➡ Actual MySQL is still 10 → **Ultimately MySQL layer may have stock < 0 (overselling)**
```
At this point need to use:
- Master-slave sync (Master-Slave) -> crash problem
- Or distributed lock (e.g., RedLock) -> concurrent operation problem
to coordinate data consistency across these nodes.
| Solution | Description | Pros & Cons |
|---|---|---|
|**Master-Slave Sync (Master–Slave)**|Write operations only execute on master node, slave nodes only handle reads, implementing read-write separation.|✅ **Pros**: Simple architecture, improved read performance; ⚠️ **Cons**: Master-slave replication delay exists, master node failure may cause brief data loss or reading stale data.|
|**Distributed Lock (RedLock)**|Simultaneously acquire locks on multiple independent Redis nodes, only succeeds when majority of nodes succeed.|✅ **Pros**: High fault tolerance, prevents single point of failure; ⚠️ **Cons**: Complex implementation, performance degradation (multi-node communication), not suitable for extremely high-frequency flash sales.|
|**Redis Cluster**|Official sharding cluster solution, automatically distributes keys to different nodes, supports auto-routing and high availability.|✅ **Pros**: Excellent performance, strong scalability, automatic disaster recovery; ⚠️ **Cons**: Key routing constrained by hash slot, cross-key operations and transactions limited.|
|**Single Node Hotspot Protection**|Fix **hotspot products or keys** on a single Redis node for centralized processing, reducing distributed consistency issues.|✅ **Pros**: Simple logic, avoids hotspot key distribution imbalance; ⚠️ **Cons**: Hotspot node may still become bottleneck, needs rate limiting or local cache coordination.|
|**Sharding**|Split key space by hash or consistent hash strategy across multiple Redis instances, client or proxy layer responsible for routing.|✅ **Pros**: Horizontally scalable, distributes single node pressure, significantly improves throughput; ⚠️ **Cons**: Complex implementation and maintenance, cross-shard operations difficult, expansion/re-sharding requires data migration and may cause brief inconsistency.|
##### Master-Slave Overselling Due to Delay
```
Scenario: Overselling due to delay
User A places order
→ Master deducts inventory (stock: 1 → 0)
→ But Slave hasn't synced yet (still shows stock=1)
Meanwhile, User B queries inventory
→ Reads from Slave (because system does read-write separation)
→ Sees inventory still has 1, so also places order
User B's order request goes to Master
→ Master executes deduction again
→ At this point may become negative (overselling)
This is inventory inconsistency caused by master-slave replication delay.
```
##### How to Reduce Delay Risk
| Method | Approach | Cost |
| ------------------ | -------------------------------- | ------- |
| **Force read from master (no read-write separation)** | For critical business like flash sales, only read from master node data | Master node pressure increases |
| **Semi-synchronous replication (WAIT command)** | Master waits for at least N Slaves to confirm write before returning success | Performance degradation |
| **Hotspot data centralized on single machine** | Fix flash sale inventory on one Redis node for processing, no sharding | Reduces complexity |
| **Async consistency compensation** | Scheduled reconciliation, rollback oversold orders | Increases complex logic |
### Next Chapter
Ticket-Craze: Kafka - https://hackmd.io/@chaodotcom/BJCkJAikWl