当前位置:网站首页>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 .
边栏推荐
- A few suggestions for making rust library more beautiful! Have you learned?
- B 站弹幕 protobuf 协议还原分析
- 请问oracle-cdc用JsonDebeziumDeserializationSchema反序列化
- Entropy information entropy cross entropy
- 自动更新Selenium驱动chromedriver
- Efficient ETL Testing
- Where does this "judge the operation type according to the op value and assemble SQL by yourself" mean? It means simply using Flink tab
- MySQL implementation of field segmentation from one line to multiple lines of example code
- Pdf batch splitting, merging, bookmark extraction, bookmark writing gadget
- MySQL中正则表达式(REGEXP)使用详解
猜你喜欢

Master binary tree in one article

亚朵三顾 IPO

人均瑞数系列,瑞数 4 代 JS 逆向分析

每人每年最高500万经费!选人不选项目,专注基础科研,科学家主导腾讯出资的「新基石」启动申报...

The programmer said, "I'm 36 years old, and I don't want to be rolled, let alone cut."

机器人材料整理中的套-假-大-空话

公链与私链在数据隐私和吞吐量上的竞争

达晨史上最大单笔投资,今天IPO了

AI表现越差,获得奖金越高?纽约大学博士拿出百万重金,悬赏让大模型表现差劲的任务...

AI金榜题名时,MLPerf榜单的份量究竟有多重?
随机推荐
这个『根据 op 值判断操作类型来自己组装 sql』是指在哪里实现?是指单纯用 Flink Tabl
AcWing 4300. Two operations (minimum number of BFS searches)
What can be done for traffic safety?
Coscon'22 community convening order is coming! Open the world, invite all communities to embrace open source and open a new world~
Gradle知识概括
Talking about the current malpractice and future development
mysql连接vscode成功了,但是报这个错
Koa2 addition, deletion, modification and query of JSON array
Should the jar package of MySQL CDC be placed in different places in the Flink running mode?
AcWing 4299. Delete point
COSCon'22 社区召集令来啦!Open the World,邀请所有社区一起拥抱开源,打开新世界~
使用MitmProxy离线缓存360度全景网页
Cloud native (32) | kubernetes introduction to platform storage system
氢创未来 产业加速 | 2022氢能专精特新创业大赛报名通道开启!
Nftscan Developer Platform launches Pro API commercial services
ArrayExpress数据库里的细胞只有两个txt是不是只能根据Line到ENA下载测序跑矩阵?
JS import excel & Export Excel
How does crmeb mall system help marketing?
【OFDM通信】基于深度学习的OFDM系统信号检测附matlab代码
同构+跨端,懂得小程序+kbone+finclip就够了!