How to design a red envelope grabbing system



Hello, I’m Billy. I went to the interview some time ago and was asked how to design a red envelope robbing system. Because I wasn’t ready at that time, I didn’t return very well. After these days of research, including looking for information, I’ll share with you today how to design a red envelope robbing system. I hope it will be helpful to you. It mainly shows the design of the red envelope system. The red envelope algorithm is not the focus, so there is no implementation of double mean method. The scheme described below has been implemented, and the code is ingithub, welcome to the discussion.

requirement analysis

In the common red envelope system, the user specifies the amount and total number of red envelopes to complete the creation of red envelopes, and then distributes the red envelopes to the target user through an entrance. After seeing the red envelopes, the user clicks the red envelopes and obtains the red envelopes randomly. Finally, the user can view the red envelopes he has grabbed. The whole business process is not complex. The difficulty is that the behavior of grabbing red envelopes may have high concurrency. Therefore, the optimization of system design mainly focuses on the behavior of grabbing red envelopes.

Because viewing red envelopes is too simple, it is not discussed in this article. Then there are only system use cases leftHair, grabTwo.

  1. Send red envelopes: users set the total amount and quantity of red envelopes
  2. Grab red envelopes: users get a certain amount randomly from the total red envelopes

There’s nothing to say. I believe everyone’s wechat red envelopes have been robbed. I understand it when I think about it. It seems that the business is very simple, but there is still a little trouble. First of all, you must ensure high availability for grabbing red envelopes, otherwise users will be very angry. Secondly, we must ensure the consistency of system data, and do not over send, otherwise the users who grab the red envelope will not receive money, and the users will be very angry. Finally, the system may have high concurrency.

OK, the detailed design will be carried out directly after the analysis. So there are only two interfaces:

  1. Hand out red envelopes
  2. Grab a red envelope

Table structure design

The table creation statement is directly given here:

Red envelope activity table:

CREATE TABLE `t_ redpack_ activity` (

Red envelope form:

CREATE TABLE `t_ redpack` (


CREATE TABLE `t_ redpack_ detail` (

The activity table is how many red envelopes you sent and the remaining amount needs to be maintained. The details list is the red envelope details snatched by the user. The red envelope table is each specific red envelope information. Why three tables? In fact, if there is no red envelope table, it is OK. But our planPre allocated red envelopesYou need to use a table to record the information of red envelopes, so this table is available during design.

OK, after analyzing the table structure, the scheme is almost 7788. Please continue to look at the following scheme, from simple to complex.

Implementation based on distributed lock

The implementation based on distributed lock is the simplest and rudimentary. The whole red envelope grabbing interfaceactivityIdAskeyLock to ensure that the same batch of red envelope robbery is executed serially. The implementation of distributed locks isspring-integration-redisProvided by the project, the core class isRedisLockRegistry。 Lock throughRedisofluaScript implementation, and implements blocking local reentry.

Implementation based on optimistic lock

The second way is to add optimistic lock version control to the red envelope activity table. When multiple threads update the same activity table at the same time, only one clien will succeed. For other failed clients, cycle retry and set a maximum number of cycles. This scheme can handle concurrent cases, but there is a great conflict. Because only one person will succeed at a time, other clients need to retry. Even if they retry, only one person can succeed at a time, so the TPS is very low. When the number of failed retries set is less than the number of red packets issued, it may lead to that someone does not grab the red packet at last, and there are actually remaining red packets.

Implementation based on pessimistic lock

As the red envelope activity table increases, optimistic locks conflict greatly, so pessimistic locks can be considered:select * from t_redpack_activity where id = #{id} for updateNote that pessimistic locks must be used in transactions. At this point, all red envelope grabbing behavior becomes serial. In this case, the efficiency of pessimistic lock is much higher than that of optimistic lock.

Pre allocation of red packets, based on the implementation of optimistic lock

It can be seen that if we add the dimension of the concept of music lock to the red envelope details, the conflict will be reduced. Because the red envelope details were created after the user grabbed them, it is now necessary to pre allocate red envelopes, that is, n red envelopes are generated when creating red envelope activities, and the availability / unavailability is controlled by status. In this way, when multiple clients grab red packets, they will obtain all available red packet details under the activity, return one of them randomly, and then update it. If the update is successful, it means that the user has grabbed the red packet, and if it fails, it means that there is a conflict, so they can try again circularly. In this way, the conflict is reduced.

Implementation of redis based queue

Similar to the previous scheme, however, when users issue red envelopes, a corresponding number of red envelopes will be created and added to the redis queue. It will pop up when grabbing the red envelope.RedisThe queue meets our requirements very well. There will be no duplicate elements every time they pop up. They will be destroyed when they are used up. Defect: once the red packet is ejected from the queue during red packet grabbing, the system crashes. After recovery, the red packet details in the queue have been lost and need to be compensated manually.

Asynchronous receipt based on redis queue

The scheme does not persist to the database after the package is savedRedis, and then return success. Through another threadUserRedpackPersistConsumer, pull the persistent information for warehousing. It should be noted that the pulling action at this time is normalpopWill still appearcrash pointTherefore, considering the availability, it is used hereRedisofBRPOPLPUSHOperation, pop up the element and add it to another queue for backup to ensure that it can be automatically restored through the backup queue after it crashes here. Crash recovery threadCrashRecoveryThreadCheck whether the persistence is successful in the DB by pulling the backup information regularly. If it is successful, clear this element. Otherwise, compensate and clear this element. If an exception occurs during the operation of the database, an error log is recordedredpack.persist.log, this log uses a separate file and format to facilitate compensation (generally not triggered).

Post language

Of course, a robust system may have to consider all aspects. If the red envelope itself is a case with a large amount of data, a multi copy scheme needs to be made. This paper just demonstrates the advantages and disadvantages of various schemes for reference only. In addition, ifRedisHigh availability is required.

Author: pleuvoir

Source: Nuggets

This work adoptsCC agreement, reprint must indicate the author and the link to this article

Recommended Today

Explanation of websocket heartbeat reconnection

Recently, websocket has been used in the development of applet. The applet provides corresponding native API, which is different from H5 API. Therefore, some mature class libraries of popular H5 are difficult to use, and the native API has some defects, so it implements a set of heartbeat reconnection mechanism by itself. First, let’s briefly […]