Spike
1. Current limit
Fixed window algorithm: the time node cannot be updated dynamically, that is, set key expire 10s (1-11 seconds, 2-12 seconds) is not handled well
Sliding window algorithm: zset member id score 10 solves the time node problem score is the timestamp, which can dynamically obtain the total number of visits within the time (currentTime-score) to determine whether the target is up to date
Leaky bucket algorithm: there seems to be a similar implementation in redis
Token bucket algorithm: Guava RateLimiter
2. Downgrade (also called fuse)
spring cloud sentinel
3. Cache
3.1 Cache consistency problem
A. Update Db first, then delete redis
Two questions:
a. Successfully updated Db, but failed to delete cache. Lead to dirty data in redis (can be solved with the help of rocketmq to constantly retry)
b.1) The cache just expires
(2) Request A to query the database and get an old value
(3) Request B to write the new value to the database
(4) Request B to delete the cache
(5) Request A to write the old value found into the cache (according to the time-consuming situation, the probability can be calculated to be relatively low)
B delete the cache first, then update Db
(1) A thread deletes the cache, writes db and updates it to data2
(2)b thread query found that the cache does not exist
(3) The b thread synchronizes the latest data of the current db da ta1 to redis
(4) A thread writes data data2 to DB. Dirty data occurs
3.2 Solution
A. Delayed double deletion
Delete the cache first, then update the DB, and then delete the cache asynchronously (through the rocketmq asynchronous retry mechanism to ensure that the deletion is successful)
B. Subscription binLog mechanism
Ali open source canal
3.3 Application spike realization
Current limit: zset sliding window current limit
Downgrade: spring cloud sentinel+open Feign circuit breaker
Cache:
Delayed double deletion strategy
1. Inventory deduction
When submitting an order
When paying
Inventory is deducted in advance when the order is submitted, and the timeout response: the timed task rotation training database does not pay for the order, and the overtime order returns the inventory
2. Hotspot data cache
Delayed double deletion strategy
3. Inventory to prevent oversold issues
Optimistic locking mechanism update
update stock
sale = sale + 1,
version = version + 1,
WHERE id = #{id,jdbcType=INTEGER}
AND version = #{version,jdbcType=INTEGER}
或者
update stock
sale = sale + 1
WHERE id = id
AND sale={#sale}
Pessimistic lock mechanism
Add a transaction to the update table in the Service layer, so that when each thread updates the request, it will first lock this row of the table (pessimistic lock), and then release the lock after updating the inventory. But this is too slow, 1000 threads can't wait.
beginTranse(开启事务)
try{
//quantity为请求减掉的库存数量
$dbca->query('update s_store set amount = amount - quantity where amount>=quantity and postID = 12345');
}catch($e Exception){
rollBack(回滚)
}
commit(提交事务)
specific plan
- When the system is initialized, the inventory quantity of the product is loaded into the Redis cache;
- When receiving the spike request, pre-decrease the inventory in Redis. When the inventory in Redis is insufficient (inventory <0, you can set a flag in the memory boolean = already sold out, you don't need to request redis to increase network overhead. , In the distributed case, get the corresponding notification through zookeeper), directly return to the failure of the spike, otherwise continue to step 3;
- Put the request into the asynchronous queue, and return to the queue;
- The server asynchronous queue will dequeue the request. Successfully dequeued requests can generate a spike order, reduce database inventory (failure will roll back, and the inventory data in redis will be restored, plus 1), and return the spike order details.
- After the background order is successfully created, you can send a spike successful notification to the user through websocket. The front-end judges whether the spike is successful or not. If the spike is successful, it will enter the spike order details, otherwise the spike will fail.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。