Design and Technical Solutions for a High‑Concurrency Flash Sale System
This article examines the challenges of building a flash‑sale (秒杀) system—such as overselling, high concurrency, request throttling, and database strain—and presents a comprehensive backend design using separate databases, dynamic URLs, static pages, Redis clustering, Nginx, token‑bucket rate limiting, asynchronous order processing, and service degradation strategies.
Preface
Flash‑sale systems (e.g., on JD, Taobao, Xiaomi) attract massive traffic in a very short time. This article explores how the backend of such a system can be implemented, what problems need to be considered, and how to design an effective solution.
1: Issues to Consider
1.1 Overselling
When inventory is limited (e.g., 100 items) but 200 orders are placed, overselling severely damages business interests; preventing overselling is the top priority.
1.2 High Concurrency
Flash sales last only a few minutes, generating a huge burst of requests. The backend must avoid cache breakdown, database overload, and other failures caused by extreme concurrency.
1.3 Interface Abuse
Automated tools can send hundreds of requests per second to the sale interface. The system must filter out repeated or invalid requests.
1.4 Flash‑sale URL Exposure
Ordinary users see a simple page with a disabled button before the start time. Skilled users can discover the underlying URL via browser tools and trigger the sale early; the design must mitigate this risk.
1.5 Database Isolation
Running the flash‑sale service on the same database as other business logic can cause cascading failures. A dedicated database isolates the impact of crashes or overloads.
1.6 Massive Request Volume
Even with caching, a single Redis instance may handle only ~40k QPS, while a flash sale can generate hundreds of thousands of requests per second, leading to cache breakdown and DB overload.
2: Design and Technical Solutions
2.1 Flash‑sale Database Design
A separate database with two tables— flash_sale_order and flash_sale_goods —stores orders and product information, preventing interference with other services.
2.2 Dynamic Flash‑sale URL
The sale URL is generated dynamically using an MD5 hash of random characters, making it impossible to guess before the start time.
2.3 Page Staticization
Product details, parameters, transaction records, and reviews are rendered into a static HTML page, eliminating backend and database calls for read‑only requests.
2.4 Redis Cluster
Because flash sales are read‑heavy, a Redis cluster (e.g., Sentinel mode) improves performance and availability.
2.5 Nginx Front‑end
Nginx handles millions of concurrent connections and forwards traffic to a Tomcat cluster, greatly increasing concurrency capacity.
2.6 SQL Simplification
Instead of a separate SELECT and UPDATE for stock deduction, a single UPDATE with optimistic‑lock versioning prevents overselling:
update miaosha_goods set stock = stock - 1 where goods_id = #{goods_id} and version = #{version} and stock > 0;2.7 Redis Pre‑decrement
Before the sale starts, stock is set in Redis (e.g., redis.set(goodsId, 100)). Each successful order atomically decrements the Redis value; if the stock falls below zero, the request is rejected. Lua scripts ensure atomicity for cancel‑and‑restore scenarios.
2.8 Interface Rate Limiting
Various rate‑limiting strategies are applied:
Frontend limiting : disable the sale button for a short period after a click.
Per‑user repeat request limit : reject requests from the same user within a configurable time window using Redis key expiration.
Token‑bucket algorithm : Guava's RateLimiter generates tokens at a fixed rate; only requests that acquire a token are processed.
public class TestRateLimiter {
public static void main(String[] args) {
// 1 token per second
final RateLimiter rateLimiter = RateLimiter.create(1);
for (int i = 0; i < 10; i++) {
double waitTime = rateLimiter.acquire();
System.out.println("Task " + i + " waited " + waitTime + " seconds");
}
System.out.println("Done");
}
}Try‑acquire with timeout : if a token cannot be obtained within a short timeout, the request is dropped.
public class TestRateLimiter2 {
public static void main(String[] args) {
final RateLimiter rateLimiter = RateLimiter.create(1);
for (int i = 0; i < 10; i++) {
boolean isValid = rateLimiter.tryAcquire(0.5, TimeUnit.SECONDS);
if (!isValid) continue;
System.out.println("Task " + i + " executed");
}
System.out.println("Finished");
}
}2.9 Asynchronous Order Processing
After passing rate limiting and stock checks, orders are placed onto a message queue (e.g., RabbitMQ). Consumers process orders asynchronously, decoupling the request path and providing retry or compensation mechanisms.
2.10 Service Degradation
If a service becomes unavailable, a fallback (e.g., via Hystrix circuit breaker) returns a friendly message instead of a hard error, ensuring a graceful degradation.
3: Summary
The presented architecture—isolated databases, dynamic URLs, static pages, Redis cluster, Nginx, token‑bucket limiting, asynchronous queuing, and graceful degradation—can handle tens of thousands of concurrent requests. For larger scales (hundreds of millions), further techniques such as database sharding, Kafka queues, and larger Redis clusters would be required.
By thoughtfully addressing high‑concurrency challenges, developers can build robust flash‑sale systems that protect inventory integrity and provide a smooth user experience.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.
