当前位置:网站首页>Design a red envelope grabbing system
Design a red envelope grabbing system
2022-07-06 23:34:00 【OoZzzy】
List of articles
- 1. Demand analysis
- 2. Table structure design
- 3. Implementation based on distributed lock
- 4. Implementation based on optimistic lock
- 5. Implementation based on pessimistic lock
- 6. Pre allocate red packets , Implementation based on optimistic lock
- 7. be based on Redis Implementation of queues
- 8. be based on Redis queue , Asynchronous storage
1. Demand analysis
Common red envelope systems , Amount specified by the user 、 The total number of red packets is used to complete the creation of red packets , Then the red packet is distributed to the target user through a certain portal , After the user sees the red envelope , Click red envelope , Get red packets randomly , Last , Users can view the red packets they have grabbed . The whole business process is not complicated , The difficulty lies in Grab a red envelope This behavior may have High concurrency . therefore , The optimization point of system design mainly focuses on Grab a red envelope In this behavior .
- Hand out red envelopes : The user sets the total amount of red packets 、 Total quantity
- Grab a red envelope : The user gets a certain amount randomly from the total red packet
High availability must be ensured for red packets , Otherwise, users will be very angry . secondly , The consistency of system data must be ensured, and no over issuance is allowed , Otherwise, users who get red packets will not receive money , Users will be angry . And finally , The system may have high concurrency .
2. Table structure design
Red envelope activity table
CREATE TABLE `t_redpack_activity`
(
`id` bigint(20) NOT NULL COMMENT ' Primary key ',
`total_amount` decimal(10, 2) NOT NULL DEFAULT '0.00' COMMENT ' Total sum ',
`surplus_amount` decimal(10, 2) NOT NULL DEFAULT '0.00' COMMENT ' The remaining amount ',
`total` bigint(20) NOT NULL DEFAULT '0' COMMENT ' Total number of red packets ',
`surplus_total` bigint(20) NOT NULL DEFAULT '0' COMMENT ' Total remaining red packets ',
`user_id` bigint(20) NOT NULL DEFAULT '0' COMMENT ' The user id ',
`version` bigint(20) NOT NULL DEFAULT '0' COMMENT ' Version number ',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8;
Red envelope table
CREATE TABLE `t_redpack`
(
`id` bigint(20) NOT NULL COMMENT ' Primary key ',
`activity_id` bigint(20) NOT NULL DEFAULT 0 COMMENT ' Red envelope activity ID',
`amount` decimal(10, 2) NOT NULL DEFAULT '0.00' COMMENT ' amount of money ',
`status` TINYINT(4) NOT NULL DEFAULT 0 COMMENT ' Red envelope status 1 You can use 2 Unavailable ',
`version` bigint(20) NOT NULL DEFAULT '0' COMMENT ' Version number ',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8;
A detailed list
CREATE TABLE `t_redpack_detail`
(
`id` bigint(20) NOT NULL COMMENT ' Primary key ',
`amount` decimal(10, 2) NOT NULL DEFAULT '0.00' COMMENT ' amount of money ',
`user_id` bigint(20) NOT NULL DEFAULT '0' COMMENT ' The user id ',
`redpack_id` bigint(20) NOT NULL DEFAULT '0' COMMENT ' Red envelope number ',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ' Creation time ',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ' Update time ',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8;
Activity list , Is how many red envelopes you sent , And the remaining amount needs to be maintained . The schedule is the red packet details that the user grabs . The red packet table is the information of each specific red packet . Why do you need three tables ? In fact, if there is no red envelope table, it is OK . However, our scheme needs to use a table to record the information of red packets in advance , That's why the table was designed .
3. Implementation based on distributed lock

The implementation based on distributed lock is the simplest and crudest , The whole red packet interface is used to activityId As key To lock , Ensure that the same batch of red packet robbing is executed serially . The implementation of distributed locks is implemented by spring-integration-redis The project provides , The core class is RedisLockRegistry. Lock through Redis Of lua Script implementation , And it realizes blocking local reentrant .
4. Implementation based on optimistic lock

The second way , Add optimistic lock version control to the red packet activity table , When multiple threads update the same activity table at the same time , only one clien You will be successful . Other failures client Cycle retry , Set a maximum number of cycles . This scheme can realize the processing in the case of concurrency , But the conflict is great . Because only one person will succeed at a time , other client Need to try again , Even if you try again, only one person can succeed at a time , therefore TPS Very low . When the set number of failed retries is less than the number of red packets issued , It may lead to someone not grabbing the red envelope in the end , In fact, there are still red envelopes left .
5. Implementation based on pessimistic lock

Due to the increase of red packet activity table, optimistic lock conflicts are very large , So consider using pessimistic locks :select * from t_redpack_activity where id = #{id} for update, Note that pessimistic locks must be used in transactions . here , All red packet grabbing becomes serial . In this case , Pessimistic locks are far more efficient than optimistic locks .
6. Pre allocate red packets , Implementation based on optimistic lock

You can see , If we add the dimension of Le Guan lock to the red packet details , Then the conflict will be reduced . Because the red packet details were created after the user grabbed them , Now you need to pre allocate red packets , That is, when you create a red packet activity, you will generate N Red envelopes , Control availability through status / Unavailable . such , When more than one client When you grab a red envelope , Get all available red packet details under this activity , Randomly return one of them and then update it , The successful update means that the user has grabbed the red packet , Failure is a sign of conflict , You can cycle through retry . such , Conflict is reduced .
7. be based on Redis Implementation of queues

Similar to the previous scheme , however , A corresponding number of red envelopes will be created when users issue red envelopes , And join in Redis In line . When grabbing a red envelope, it will pop up .Redis The queue fits our needs very well , There will be no duplicate elements in each pop-up , Destroy when used up . defects : When grabbing a red envelope, once it pops out of the queue , At this point the system crashes , After recovery, the details of red packets in this queue have been lost , Manual compensation is required .
8. be based on Redis queue , Asynchronous storage

In this scheme, you do not operate the database after you get the red packet , Instead, it saves persistent information to Redis in , Then return to success . Through another thread UserRedpackPersistConsumer, Pull the persistent information for warehousing . It should be noted that , In this case, if you use the normal pop There will still be crash point The problem of , So considering availability , Use here Redis Of BRPOPLPUSH operation , Pop up the element and add it to the backup queue , Ensure that the crash here can be automatically recovered through the backup queue . Crash recovery thread CrashRecoveryThread Pull backup information regularly , Go to DB Verify whether the persistence is successful , If successful, clear this element , Otherwise, compensate and clear this element . If an exception occurs during the operation of the database, the error log will be recorded redpack.persist.log, This log uses a separate file and format , Easy to compensate ( Generally not triggered ).
Redis High availability is required .
边栏推荐
- The method of reinstalling win10 system is as simple as that
- Leetcode problem solving - 889 Construct binary tree according to preorder and postorder traversal
- Per capita Swiss number series, Swiss number 4 generation JS reverse analysis
- 新手问个问题,我现在是单机部署的,提交了一个sql job运行正常,如果我重启了服务job就没了又得
- The problem that dockermysql cannot be accessed by the host machine is solved
- NFTScan 开发者平台推出 Pro API 商业化服务
- If the request URL contains jsessionid, the solution
- Realize colorful lines and shape your heart
- Efficient ETL Testing
- js對JSON數組的增删改查
猜你喜欢

Gradle知識概括

JS addition, deletion, modification and query of JSON array

Gpt-3 is a peer review online when it has been submitted for its own research

Children's pajamas (Australia) as/nzs 1249:2014 handling process

Ajout, suppression et modification d'un tableau json par JS

Can online reload system software be used safely? Test use experience to share with you

(shuttle) navigation return interception: willpopscope

mysql连接vscode成功了,但是报这个错

Experiment 4: installing packages from Gui

不要再说微服务可以解决一切问题了
随机推荐
Docker mysql5.7 how to set case insensitive
Detailed explanation of regular expression (regexp) in MySQL
Daily question brushing record (XV)
The programmer said, "I'm 36 years old, and I don't want to be rolled, let alone cut."
基于PaddlePaddle平台(EasyDL)设计的人脸识别课堂考勤系统
B 站弹幕 protobuf 协议还原分析
ArrayExpress数据库里的细胞只有两个txt是不是只能根据Line到ENA下载测序跑矩阵?
问下各位,有没有flink sql生成作业的文档啊或是案列啊知道flink cli可以建表和指定目
Restoration analysis of protobuf protocol of bullet screen in station B
How can Oracle CDC deserialize with jsondebeziumdeserializationschema
The same job has two sources, and the same link has different database accounts. Why is the database list found in the second link the first account
Per capita Swiss number series, Swiss number 4 generation JS reverse analysis
mysql连接vscode成功了,但是报这个错
请问async i/o可以由udf算子实现然后用sql api调用吗?目前好像只看到Datastre
B站大佬用我的世界搞出卷積神經網絡,LeCun轉發!爆肝6個月,播放破百萬
Can online reload system software be used safely? Test use experience to share with you
食品里的添加剂品种越多,越不安全吗?
Station B Big utilise mon monde pour faire un réseau neuronal convolutif, Le Cun Forward! Le foie a explosé pendant 6 mois, et un million de fois.
Coscon'22 community convening order is coming! Open the world, invite all communities to embrace open source and open a new world~
自动更新Selenium驱动chromedriver