The short-term sales strategy is commonly used for promotion activities and brand marketing in the e-commerce industry. This strategy can help you increase the number of unique visitors and customer loyalty to your platform. An excellent business system can improve the stability of your platform and ensure the fairness of short-term sales promotions. This improves user experience and the reputation of your platform, and maximizes the benefits of short-term sales. This topic describes how to use the caching feature of ApsaraDB for Redis to build a highly concurrent business system for handling short-term sales.

Characteristics of short-term sales

A short-term sales activity is used to sell scarce or special commodities for specified quantities in a limited period of time. This attracts a large number of buyers. However, only a few buyers place orders during the promotion. A short-term sales activity increases the number of unique visitors and order requests by dozens or hundreds of times that in regular sales activities on your platform within a short period of time.

A short-term sales activity is divided into three phases:

  • Before the promotion: Buyers continuously refresh the commodity details page. As a result, the number of requests for this page spikes.
  • During the promotion: Buyers place orders. The number of order requests reaches a peak.
  • After the promotion: Some buyers that have placed orders continue to query the status of orders or cancel orders. Most buyers continue to refresh the commodity details page and wait for opportunities to place orders after other buyers cancel their orders.

In most cases, a database uses row-level locking to handle requests submitted by buyers. The database allows only requests that hold the lock to query inventory data and place orders. However, in these cases, the database is incapable of handling high concurrency. This may cause services to be blocked by a large number of requests, and cause the server to stop responding to the buyers.

Business system for handling short-term sales

During a short-term sales activity, the business system may receive a large amount of user traffic. However, only a few of the requests are valid. You can identify and block invalid requests in each phase in advance by using the hierarchy of the system architecture.

Use the browser cache and Content Delivery Network (CDN) to process user traffic that requests static content

Before a short-term sales activity, buyers continue to refresh the commodity details page. As a result, the number of requests for this page spikes. To solve this issue, you must present details of commodities for short-term sales and details of regular commodities on different web pages. Use static elements to present details of commodities for short-term sales. Static data is cached in the browser and on CDN nodes, except for the place-order function that requires interaction between the browser and server. This way, only a small fraction of the traffic that is caused by page refreshes before the promotion is redirected to the server.

Use a read/write splitting instance of ApsaraDB for Redis to cache content and block invalid requests

CDN is used to filter and block user traffic in phase 1. In phase 2, you can use a read/write splitting instance of ApsaraDB for Redis to block invalid requests. In phase 2, the business system retrieves data. The read/write splitting instance can handle more than 600,000 queries per second (QPS), which can meet the business demands.

Use the data control module to cache the data of commodities for short-term sales to the read/write splitting instance, and specify the flag that indicates whether the promotion activity begins:

"goodsId_count": 100 //The total number of commodities.
"goodsId_start": 0   //The flag that indicates whether the promotion activity begins.
"goodsId_access": 0  //The number of order requests that are accepted.
  1. Before the promotion activity begins, the value of the goodsId_start flag retrieved by the server cluster is 0, which indicates that the promotion activity does not start.
  2. After the data control module changes the value of the goodsId_start flag to 1, the promotion activity begins.
  3. The server cluster then caches the goodsId_start flag and accepts order requests. The cluster updates the number of accepted order requests in goodsId_access. The number of remaining commodities is calculated in the following method: goodsId_count - goodsId_access.
  4. After the number of placed orders reaches the value of goodsId_count, the business system blocks subsequent order requests. The number of remaining commodities is set to 0.

As a result, the business system accepts only a small fraction of the order requests. For high concurrency scenarios, a large amount of traffic is directed to the system. In this case, you can control the percentage of order requests that the system accepts.

Use a master-replica instance of ApsaraDB for Redis to cache inventory data and speed up the removal of the item from the inventory

After the business system receives an order request, the system checks the order information and removes the item from the inventory. To avoid retrieving data directly from the backend database, you can use a master-replica instance of ApsaraDB for Redis to remove the item from the inventory. The master-replica instance supports more than 100,000 QPS. ApsaraDB for Redis can help you optimize inventory queries, block invalid order requests, and increase the overall throughput of the business system to handle short-term sales.

You can use the data control module to cache the inventory to the ApsaraDB for Redis instance in advance. The instance stores the commodity data for promotion in a hash table.

"goodsId" : {
    "Total": 100
    "Booked": 100
}

To remove the item from the inventory, the short-term sales promotion server runs the following Lua script and connects to the ApsaraDB for Redis instance to obtain the order permission. The Lua script ensures the atomicity of multiple commands based on the Redis single-thread model.

local n = tonumber(ARGV[1])
if not n  or n == 0 then
    return 0       
end                
local vals = redis.call("HMGET", KEYS[1], "Total", "Booked");
local total = tonumber(vals[1])
local blocked = tonumber(vals[2])
if not total or not blocked then
    return 0       
end                
if blocked + n <= total then
    redis.call("HINCRBY", KEYS[1], "Booked", n)                                   
    return n;   
end                
return 0

Run the SCRIPT LOAD command to cache the Lua script to the ApsaraDB for Redis instance in advance, and then run the EVALSHA command to execute the script. This method requires less network bandwidth than directly running the EVAL command.

  1. Cache the Lua script to the ApsaraDB for Redis instance.
    SCRIPT LOAD "lua code"
    The following result is returned:
    "438dd755f3fe0d32771753eb57f075b18fed7716"
  2. Run the Lua script.
    EVALSHA 438dd755f3fe0d32771753eb57f075b18fed7716 1 goodsId 1 

If the ApsaraDB for Redis instance returns the value n as the number of commodities that buyers ordered, the items are successfully removed from the inventory.

Use a master-replica instance of ApsaraDB for Redis to asynchronously write order data to the database based on message queues

After the items are removed from the inventory, the short-term sales business system writes order data to the database. The system can directly perform operations in the database for a few commodities. If the number of commodities for promotion is more than 10,000 or 100,000, lock conflicts may occur and can cause performance bottlenecks in the database. Therefore, to avoid directly writing data to the database, the short-term sales system writes order data to message queues. Orders that are written to message queues are considered successfully placed orders.

  1. The ApsaraDB for Redis instance provides message queues in a list structure.
     orderList {
         [0] = {Order content} 
         [1] = {Order content}
         [2] = {Order content}
         ...
     }
  2. The short-term sales business system writes order content to the ApsaraDB for Redis instance.
    LPUSH orderList {Order content}
  3. The asynchronous order module sequentially retrieves order data from the ApsaraDB for Redis instance and writes order data to the database.
     BRPOP orderList 0

The ApsaraDB for Redis instance provides message queues and asynchronously writes order data to the database to complete the order process.

The data control module manages the synchronization of promotion data

At the start of the promotion, the short-term sales business system uses the read/write splitting instance of ApsaraDB for Redis to block invalid traffic and allows a fraction of valid traffic to continue the order process. After the promotion, the short-term sales business system has to process more traffic caused by order authentication failures and refund requests. Therefore, the data control module regularly computes data in the database, and synchronizes the data to the master-replica instance and then to the read/write splitting instance.