Interactive Viewing Experience for the World Cup Using Redis

On the evening of June 14, the 2018 FIFA World Cup kicked off in Moscow, Russia. Tens of millions of people in China watched the opening game using live broadcasting services such as Youku, CBox, and Migu Video.

According to a report released by Alibaba Cloud, the first wave of traffic peaks appeared in the 44th minute after the opening of the game. The peak traffic reached 1.5 times of the peak traffic from the 2018 Spring Festival Gala. Because of this, the FIFA World Cup has become the largest online live broadcast in history.

During the game, it is estimated that 70% of the live broadcast traffic in China went through Alibaba Cloud. Source in Chinese:

Interactive Viewing Experience

Although these integrated apps sound simple, hosting it in such a massive scale is no easy task. You need to take into consideration several aspects, such as business architecture, application scenarios, high availability construction, and flexible resizing. Let’s take a look at how Redis has made all these possible.

Business Architecture

The above picture is an enterprise’s live broadcast solution, which mainly uses elastic computing, CDN, smart dynamic encoding technology, video AI, narrowband HD 2.0, and Redis to fully guarantee a high-definition experience while saving bandwidth. This solution optimizes resources and costs, and brings a smooth and rich interactive experience to the users.

In this article, we will not discuss how the video is recorded and broadcast. Instead, we will be focusing on the important roles and applications scenarios, as well as the use of Redis in enriching the live broadcast experience.

Application Scenarios

Application scenarios of Redis include:

  1. Session cache
  2. Full Page Cache (FPC)
  3. Mobile phone verification code
  4. Access frequency limit/blacklist/whitelist
  5. Message queueing
  6. Merchandise inventory management
  7. GEO function added with LBS (location-based service) development

In actual use, you need to choose the correct data type according to your own business scenario.

Live Chat

Such a chat room can be implemented using Hash, for example: {userID:contents}

User IDContent11101000Broke

Redis can also be used to filter out spammers in the chat room. Of course, this is usually done by a spam filter in addition to Redis. For example, to limit the number of comments by a user within a minute:

Method 1: Implement through sorted set.

Record the user comments on the day, use timestamp as score, and then use the Zset commands RANGEBYSCORE, ZADD, and ZRANGEBYSCORE.

RANGEBYSCORE userID:10000:operation:comment 61307510405600 +inf //Get the operation records within 1 minute
Redis> ZADD userID:10000:operation:comment 61307510402300 "This is a comment" //score is timestamp (integer) 1
Redis> ZRANGEBYSCORE userID:10000:operation:comment 61307510405600 +inf //Get the operation records within 1 minute

Method 2: Use Redis + Lua to acchieve access frequency control

# KEYS[1] indicates the limited number, passed in by the caller
local key1 ,key2 = 'access:limit' ,'access:expire'
if'EXISTS' ,key2) > 0 then
return'DECR' ,key1) ;
else'SET' ,key2 ,1)'EXPIRE' ,key2 ,60)'SET' ,key1 ,KEYS[1])
return KEYS[1]

Game Status Live Update

The latest game schedules can be implemented with Redis’s List data structure or sorted set data structure, in conjunction with the expiration time. The latest scores, rankings, and other match information, can be easily implemented using this method as well.

Message Notifications (Number of Unread Messages)

Likes (Number of Likes)


INCR active16

GET active16


HSET active:active16 likes 0

HINCRBY active:active16 likes 1

HGETALL active:active16

Red Envelope Inventory Management

The original red envelope is called a big red envelope, and the split red envelopes are called small red envelopes.

  1. Small red envelopes are pre-generated and inserted into the database. The user IDs corresponding to the red envelopes are null.
  2. Each big red envelope corresponds to two Redis queues, one is for the unconsumed red envelopes, and the other is for the consumed red envelopes. At the beginning, all small red envelopes are put into the unconsumed red envelope queue. The unconsumed red envelope queue is a Json string, the activeID is the game number, the money is the red envelope amount, and the product is the number of products. For example: {activeId:’16', money:’300'} or {activeID:’16',product:’50'}
  3. Use a map in Redis to filter users who have already snatched a red envelope.
  4. When a user snatches the red envelope, first determine whether or not the user has already snatched a red envelope. If not, then take a small red envelope from the unconsumed red packet queue, then push it to the other queue, and finally put the user ID into the deduplicated map.
  5. Use a single thread to batch take the red envelopes from the consumed queue, and then batch update the user IDs of the red envelopes in the database.

Although the above process is straightforward, how can we avoid users from fooling the system? For example in Step 4, if a user taps twice quickly, or opens two browsers to simultaneously snatch red envelopes, is it possible for the user to snatch two red envelopes?

In order to solve this problem, the Lua script is adopted, so that the whole process of Step 4 is performed atomically.

The following is a Lua script executed on Redis:

-- Function: Try to get the red envelope, if it succeeds, return the Json string; if not, return null
-- Parameters: red envelope queue name, consumed queue name , deduplicated map name, user ID
-- Return value: nil or Json string, including user ID: userId, red envelope ID: id, red envelope amount: money
-- If the user has already snatched a red envelope, return nil
if'hexists', KEYS[3], KEYS[4]) ~= 0 then
return nil
-- take a small red envelope
local hongBao ='rpop', KEYS[1]);
if hongBao then
local x = cjson.decode(hongBao);
-- add user ID information
x['userId'] = KEYS[4];
local re = cjson.encode(x);
-- put the user ID to the deduplicated set'hset', KEYS[3], KEYS[4], KEYS[4]);
-- put the red envelope to the consumed queue'lpush', KEYS[2], re);
return re;
return nil

Message Push

The pop-up message in the above picture is not necessarily a Redis implementation but an illustration of what Redis is capable of.

There is no persistence mechanism for such message notification implemented by the pub/sub mechanism, which is a disposable model. Producers don’t need to care about how many subscribers they have, or subscriber’s detailed information. Online client (consumers) is generally visible, just like a TV program. You can obtain the update notification as long as you are online.

High Availability and Elastic Scaling

As mentioned earlier in the article, using public cloud is the best solution for video platforms such as Youku, CBox, and Migu Video. Public cloud helps ot ensure business stability and reduce costs.

Let us now look at the specific implementation of HA and elastic scaling for this application.

High Availability: Remote Data Disaster Recovery and Multiple Active Standbys

With remote data disaster recovery and multiple active standbys, once a failure occurs, you can quickly take over the service remotely to ensure that user experience is not affected. In addition, many of the widely distributed services require users to remotely access across regions. If the access latency is high at this time, the user experience will be directly affected. Multiple active standbys on the cloud provided by ApsaraDB for Redis can also help users eliminate latency when remotely accessing across regions.

Elasticity: Resource Scaling, Read/Write Splitting


You can learn more about Redis on Alibaba Cloud by visiting the ApsaraDB for Redis product page.

About the Author:


Follow me to keep abreast with the latest technology news, industry insights, and developer trends.