Mastering High-Concurrency Flash Sale Systems: Architecture, Challenges, and Solutions
This article dissects the technical challenges of building a high‑concurrency flash‑sale (seckill) system—covering business analysis, traffic isolation, static page caching, CDN bandwidth, dynamic order URLs, request throttling, database sharding, optimistic locking, and anti‑cheat mechanisms—while presenting concrete architectural principles and code examples.
1. Seckill Business Analysis
Normal e‑commerce flow: query product → create order → deduct inventory → update order → pay → ship. Seckill characteristics: low price, massive promotion, instant sell‑out, scheduled launch, short duration, extremely high concurrent requests.
2. Seckill Technical Challenges
Assuming a single product with 10,000 concurrent users, the main challenges are:
Impact on existing services – The burst can cripple the whole site. Solution : Deploy the seckill system independently, even on a separate domain, to isolate traffic.
Application and database load under high concurrency – Users constantly refresh the page, causing heavy load on app servers and DB. Solution : Static‑ize the seckill product page so requests bypass the application layer.
Sudden increase in network and server bandwidth – A 200 KB page × 10 000 requests = 2 GB bandwidth, far beyond normal usage. Solution : Cache the page in a CDN and rent additional outbound bandwidth.
Direct order URL exposure – If the order URL is known before the start, users can bypass the seckill. Solution : Make the order URL dynamic by appending a server‑generated random token that is only valid after the start.
Controlling the "Buy" button state – The button must be grey before the start and lit after. Solution : Add a JavaScript file that flips a flag and injects the order URL with a random token; version the JS file to avoid CDN caching.
Only the first successful order should be sent to the order subsystem – Limit each server to a small number of order requests (e.g., 10 per server) and use cookies or load‑balancing algorithms to filter excess requests.
Pre‑order checks – If the global submitted order count exceeds the limit, return a "sale ended" page; otherwise forward to the order subsystem.
Timed product launch – Show the product before the start but disable the purchase button; protect the URL with a random token and synchronize clocks between front‑end and back‑end.
Inventory reduction strategy – Choose between "deduct on snapshot" and "deduct on payment"; the former ("deduct on snapshot") gives a better user experience.
Overselling problem – Concurrent updates can cause the sold quantity to exceed inventory. Solution : Use optimistic locking.
update auction_auctions set quantity = #inQuantity# where auction_id = #itemId# and quantity = #dbQuantity#Anti‑bot verification – Use a dedicated verification code (e.g., TV‑broadcast code, quiz) to block automated scripts.
3. Seckill Architecture Principles
Intercept requests as early as possible – Prevent the backend data layer from being overwhelmed by filtering traffic upstream.
Read‑heavy, write‑light pattern – Cache reads heavily; writes are rare, making the system ideal for caching solutions.
4. Seckill Architecture Design
The system is purpose‑built for flash sales and differs from ordinary e‑commerce. Users focus on quickly refreshing the product page and entering the order page at the exact start time, so the UI is kept minimal.
The purchase button is grey before the start and after the product is sold out; it becomes active only during the seckill window.
Order forms allow only a single quantity, default shipping address and payment method, and only the first successful order is forwarded to the order subsystem.
The process is divided into two phases: Preparation phase: Users wait for the seckill to start. Seckill phase: Users compete for the product.
4.1 Front‑end Layer Design
Display the seckill product page with a countdown timer. Considerations:
Static page size (≈200 KB) can become a bandwidth bottleneck; split static resources and store them in CDN nodes.
Client‑side clock may drift from server clock; synchronize periodically via a lightweight API that returns the current server time.
Browser‑side request throttling: disable the button after click, limit repeated submissions within X seconds.
4.2 Site‑layer Design
Request interception at the site layer can block casual users but sophisticated scripts can still bypass it. Strategies include:
Limit frequency per UID (e.g., one request per X seconds) and cache the response.
Limit frequency per item query similarly.
4.3 Service‑layer Design
To handle massive traffic, the service layer queues write requests and serves reads from cache.
User request distribution module – Use Nginx/Apache to distribute requests across machines.
User request pre‑processing module – Check if inventory remains; reject if sold out.
User request handling module – Wrap accepted requests into a transaction and submit to the database.
Database interface module – Single RPC interface for checking seckill status and remaining quantity.
Example of a pre‑processor using a concurrent queue:
package seckill;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.http.HttpRequest;
public class RequestQueue {
public static ConcurrentLinkedQueue<HttpRequest> queue = new ConcurrentLinkedQueue<>();
}
public class PreProcessor {
private static boolean reminds = true;
private static void forbidden() { /* Do something */ }
public static boolean checkReminds() {
// Remote RPC to check inventory
if (!RPC.checkReminds()) {
reminds = false;
}
return reminds;
}
public static void preProcess(HttpRequest request) {
if (checkReminds()) {
RequestQueue.queue.add(request);
} else {
forbidden();
}
}
}Database module uses an ArrayBlockingQueue to hold potentially successful requests:
package seckill;
import java.util.concurrent.ArrayBlockingQueue;
public class DB {
public static int count = 10;
public static ArrayBlockingQueue<BidInfo> bids = new ArrayBlockingQueue<>(10);
public static boolean checkReminds() { return true; }
public static void bid() {
BidInfo info = bids.poll();
while (count-- > 0) {
// insert into Bids table
// check total sold count; if reached, set reminds = false
info = bids.poll();
}
}
}
class BidInfo {
BidInfo(HttpRequest request) { /* Do something */ }
}4.4 Database Design
4.4.1 Core Concepts
Single database (single‑node) – Simple but limited scalability.
Sharding (horizontal partitioning) – Splits data across multiple databases; routing methods include range, hash, and router‑config service.
Grouping (replication) – Provides high availability via master‑slave replication.
Typical large‑scale internet architecture combines sharding and grouping.
4.4.2 Design Considerations
Ensure data availability through redundancy (multiple sites, services, and data copies).
Improve read performance with read‑only replicas or caches (Redis, Memcached).
Maintain consistency; use middleware or force‑read‑master strategies.
Enhance scalability; adopt hash‑based routing and support rapid expansion (e.g., 2‑node to 4‑node sharding without data migration).
5. Challenges of Massive Concurrency
5.1 Reasonable Interface Design
Static HTML is served via CDN; the bottleneck lies in the backend API. Use in‑memory stores (Redis) for ultra‑fast operations and avoid direct MySQL writes under extreme load.
5.2 Need for Speed
QPS (queries per second) is the key metric. Theoretical peak may be 100 k QPS, but real‑world response time increase reduces effective QPS, leading to request backlog and "avalanche" failures.
5.3 Restart and Overload Protection
When a system is overloaded, reject traffic at the entry point before restarting services. Warm‑up caches (Redis, Memcached) is essential.
6. Cheating: Attack and Defense
6.1 Multiple Requests from a Single Account
Limit each account to one concurrent request using Redis flags or a dedicated queue.
6.2 Multiple Accounts (Zombie Accounts)
Detect high request frequency from a single IP and present captchas or block the IP.
6.3 IP Rotation and Botnets
Advanced bots use rotating proxies; mitigation relies on raising participation thresholds or behavior‑based data mining.
7. Data Safety Under High Concurrency
7.1 Over‑selling Causes
Concurrent reads of remaining inventory can lead to multiple successful orders. Use pessimistic or optimistic locking.
7.2 Pessimistic Lock
Lock the row during update; however, high contention increases response time and may cause deadlocks.
7.3 FIFO Queue
Serialize requests in a FIFO queue; risk of memory exhaustion under massive bursts.
7.4 Optimistic Lock
Update with a version number; only succeed if version matches. Redis WATCH provides this capability.
8. Summary
The internet’s rapid growth creates ever‑more high‑concurrency scenarios. Flash‑sale (seckill) and抢购 are typical examples. Although concrete technical solutions vary, the challenges are similar, and the problem‑solving mindset is largely shared.
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.
ITFLY8 Architecture Home
ITFLY8 Architecture Home - focused on architecture knowledge sharing and exchange, covering project management and product design. Includes large-scale distributed website architecture (high performance, high availability, caching, message queues...), design patterns, architecture patterns, big data, project management (SCRUM, PMP, Prince2), product design, and more.
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.
