当前位置:网站首页>Red envelope rain: a wonderful encounter between redis and Lua
Red envelope rain: a wonderful encounter between redis and Lua
2022-06-27 10:23:00 【InfoQ】

1 Overall process

- The operating system is configured with the total amount of red envelope rain activities and the number of red envelopes , Calculate the amount of each red packet in advance and store it in Redis in ;
- Grab the red packet rain interface , The user clicks on the red packet falling on the screen , Initiate a request to grab a red envelope ;
- TCP After the gateway receives the request to grab the red packet , Call the question answering system to grab the red envelope dubbo service , The essence of red envelope service is to execute Lua Script , Pass the result through TCP The gateway returns to the front end ;
- If users get red envelopes , Asynchronous tasks will start from Redis in Get the red packet information , Call the balance system , Return the amount to the user account .
2 Red envelopes Redis Design
- Same activity , Users can only grab red envelopes once ;
- The number of red envelopes is limited , A red packet can only be snatched by one user .
- Operation pre allocation red packet list ;

{
// Red envelope number
redPacketId : '365628617880842241'
// Red envelope amount
amount : '12.21'
}
- User red packet collection record list ;

{
// Red envelope number
redPacketId : '365628617880842241'
// Red envelope amount
amount : '12.21',
// The user id
userId : '265628617882842248'
}
- The user's red envelope is weight proof Hash surface ;

- adopt hexist Command to judge red packet collection record weight prevention Hash Has the user in the table received a red envelope , If the user has not received a red envelope , The process continues ;
- From the operation pre allocation red packet list rpop Send out a red packet data ;
- Operation red envelope receiving record weight proof Hash surface , call HSET The command stores the user's claim record ;
- Receive the red envelope information lpush Enter the user's red packet collection record list .
- Execute multiple commands , Whether atomicity can be guaranteed , If a command fails , Whether you can roll back ;
- In the process of execution , High concurrency scenarios , Whether isolation can be maintained ;
- The next steps depend on the results of the previous steps .
3 How things work
- The transaction open , Use MULTI , This command marks that the client executing this command switches from the non transactional state to the transactional state ;
- Order to join the team ,MULTI After opening the transaction , Client commands are not immediately executed , Instead, it is put into a transaction queue ;
- Execute a transaction or discard . If you receive EXEC The order of , The commands in the transaction queue will be executed , If it is DISCARD The transaction is discarded .
redis> MULTI
OK
redis> SET msg "hello world"
QUEUED
redis> GET msg
QUEUED
redis> EXEC
1) OK
1) hello world


4 The transaction ACID
4.1 Atomicity
redis> MULTI
OK
redis> SET msg "other msg"
QUEUED
redis> wrongcommand ### Deliberately write wrong commands
(error) ERR unknown command 'wrongcommand'
redis> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
redis> GET msg
"hello world"
redis> MULTI
OK
redis> SET msg "other msg"
QUEUED
redis> SET mystring "I am a string"
QUEUED
redis> HMSET mystring name "test"
QUEUED
redis> SET msg "after"
QUEUED
redis> EXEC
1) OK
2) OK
3) (error) WRONGTYPE Operation against a key holding the wrong kind of value
4) OK
redis> GET msg
"after"
- The order to join the team is wrong , Will abandon the transaction execution , Guaranteed atomicity ;
- Normal when ordered to join the team , perform EXEC Error after command , There is no guarantee of atomicity ;
4.2 Isolation,
- Uncommitted read (read uncommitted)
- Submit to read (read committed)
- Repeatable (repeatable read)
- Serialization (serializable)
- EXEC Before the order is executed
- EXEC After the execution of the command
4.3 persistence
- No configuration RDB perhaps AOF , The durability of transactions cannot be guaranteed ;
- Used RDB Pattern , After a transaction is executed , Next time RDB Before the snapshot is executed , If an instance goes down , The persistence of transactions is also not guaranteed ;
- Used AOF Pattern ;AOF Three configuration options for mode no 、everysec There will be data loss .always It can ensure the persistence of transactions , But because of the poor performance , Generally, it is not recommended to use in production environment .
4.4 Uniformity
- Wikipedia
- perform EXEC Before the command , The operation command sent by the client is wrong , Transaction terminated , Data consistency ;
- perform EXEC After the command , The data types of the command and operation do not match , The wrong command will report an error , But the transaction will not be terminated by the wrong command , But will continue to carry out . The correct command is executed normally , The wrong command reports an error , From this point of view , Data can also be consistent ;
- In the course of executing a transaction ,Redis The service outage . Here we need to consider the persistence pattern of service configuration . No persistent memory mode : After the service is restarted , The database does not hold data , So the data is consistent ;RDB / AOF Pattern : After the service is restarted ,Redis adopt RDB / AOF File recovery data , The database will be restored to a consistent state .
- 《 Design data-intensive applications 》

- Guaranteed atomicity , Persistence and isolation , If none of these characteristics can be guaranteed , Then the consistency of transactions cannot be guaranteed ;
- The constraints of the database itself , For example, the string length cannot exceed the column limit or uniqueness constraint ;
- The business level also needs to be guaranteed .
4.5 summary
- Ensure isolation ;
- There is no guarantee of persistence ;
- With a certain degree of atomicity , But rollback is not supported ;
- There are differences in the concept of consistency , Suppose that the core of consistency is the semantics of constraints ,Redis The transaction can guarantee consistency .
5 Lua Script
5.1 brief introduction

- Reduce network overhead . Send multiple requests at a time in the form of scripts , Reduce network delay .
- Atomic manipulation .Redis The entire script is executed as a whole , The middle is not inserted by other commands .
- Reuse . The script sent by the client will be permanent Redis in , Other clients can reuse this script without having to use code to complete the same logic .
5.2 EVAL command
EVAL script numkeys key [key ...] arg [arg ...]
scriptIs the first parameter , by Lua 5.1 Script ;
- The second parameter
numkeysThere are several parameters for specifying subsequent parameters key;
key [key ...], It's the key to operate , You can specify multiple , stay Lua The script passesKEYS[1],KEYS[2]obtain ;
arg [arg ...], Parameters , stay Lua The script passesARGV[1],ARGV[2]obtain .
redis> eval "return ARGV[1]" 0 100
"100"
redis> eval "return {ARGV[1],ARGV[2]}" 0 100 101
1) "100"
2) "101"
redis> eval "return {KEYS[1],KEYS[2],ARGV[1]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"
redis.call()redis> set mystring 'hello world'
OK
redis> get mystring
"hello world"
redis> EVAL "return redis.call('GET',KEYS[1])" 1 mystring
"hello world"
redis> EVAL "return redis.call('GET','mystring')" 0
"hello world"
5.3 EVALSHA command

redis> EVALSHA sha1 numkeys key [key ...] arg [arg ...]
redis> SCRIPT LOAD "return 'hello world'"
"5332031c6b470dc5a0dd9b4bf2030dea6d65de91"
redis> EVALSHA 5332031c6b470dc5a0dd9b4bf2030dea6d65de91 0
"hello world"
5.4 Business VS Lua Script
- for fear of Redis Blocking ,Lua Script business logic should not be too complex and time consuming ;
- Check and test carefully Lua Script , Because execution Lua Scripts have some atomicity , Rollback is not supported .
6 Actual combat preparation

// load Lua Script
String scriptLoad(String luaScript);
// perform Lua Script
Object eval(String shardingkey,
String luaScript,
ReturnType returnType,
List<Object> keys,
Object... values);
// adopt sha1 Summary execution Lua Script
Object evalSha(String shardingkey,
String shaDigest,
List<Object> keys,
Object... values);
public int calcSlot(String key) {
if (key == null) {
return 0;
}
int start = key.indexOf('{');
if (start != -1) {
int end = key.indexOf('}');
key = key.substring(start+1, end);
}
int result = CRC16.crc16(key.getBytes()) % MAX_SLOT;
log.debug("slot {} for {}", result, key);
return result;
}
7 Grab the red envelope script
- The user successfully grabbed the red envelope
{
"code":"0",
// Red envelope amount
"amount":"7.1",
// Red envelope number
"redPacketId":"162339217730846210"
}
- The user has received
{
"code":"1"
}
- The user failed to grab the red envelope
{
"code":"-1"
}
-- KEY[1]: User's anti weight claim record
local userHashKey = KEYS[1];
-- KEY[2]: Operation pre allocation red packet list
local redPacketOperatingKey = KEYS[2];
-- KEY[3]: User's red envelope receiving record
local userAmountKey = KEYS[3];
-- KEY[4]: The user id
local userId = KEYS[4];
local result = {};
-- Judge whether the user has received
if redis.call('hexists', userHashKey, userId) == 1 then
result['code'] = '1';
return cjson.encode(result);
else
-- Get red packet data from pre allocated red packets
local redPacket = redis.call('rpop', redPacketOperatingKey);
if redPacket
then
local data = cjson.decode(redPacket);
-- Join users ID Information
data['userId'] = userId;
-- Put the user number in the de duplicated hash ,value Set as red packet number
redis.call('hset', userHashKey, userId, data['redPacketId']);
-- Users and red packets are placed in the consumed queue
redis.call('lpush', userAmountKey, cjson.encode(data));
-- The return value of successful assembly
result['redPacketId'] = data['redPacketId'];
result['code'] = '0';
result['amount'] = data['amount'];
return cjson.encode(result);
else
-- Failed to grab the red envelope
result['code'] = '-1';
return cjson.encode(result);
end
end
- To write junit The test case ;
- from Redis 3.2 Start , Built in Lua debugger( abbreviation
LDB), have access to Lua debugger Yes Lua Script debugging .
8 Asynchronous task
- RedisMessageConsumer :Consumer class, Configure listening queue name , And the corresponding consumption listener
String groupName = "userGroup";
String queueName = "userAmountQueue";
RedisMessageQueueBuilder buidler =
redisClient.getRedisMessageQueueBuilder();
RedisMessageConsumer consumer =
new RedisMessageConsumer(groupName, buidler);
consumer.subscribe(queueName, userAmountMessageListener);
consumer.start();
- RedisMessageListener :Consumer monitor, Write business consumption code
public class UserAmountMessageListener implements RedisMessageListener {
@Override
public RedisConsumeAction onMessage(RedisMessage redisMessage) {
try {
String message = (String) redisMessage.getData();
// TODO Call the user balance system
// Return to consumption success
return RedisConsumeAction.CommitMessage;
}catch (Exception e) {
logger.error("userAmountService invoke error:", e);
// Consumption failure , Perform retry operation
return RedisConsumeAction.ReconsumeLater;
}
}
}
9 Wrote last

边栏推荐
- The tutor invites you to continue your doctoral study with him. Will you agree immediately?
- 【TcaplusDB知识库】TcaplusDB新增机型介绍
- Use aspese slides to convert PPT to PDF
- R langage plotly visualisation: visualisation de plusieurs histogrammes normalisés d'ensembles de données et ajout d'une courbe de densité KDE à l'histogramme, réglage de différents histogrammes en ut
- JS client storage
- Concepts of concurrency, parallelism, asynchronism, synchronization, multithreading and mutual exclusion
- Tcp/ip explanation (version 2) notes / 3 link layer / 3.4 bridge and switch / 3.4.1 spanning tree protocol (STP)
- Test how students participate in codereview
- For a moment, the ban of the US e-cigarette giant has been postponed, and products can be sold in the US for the time being
- 以后发现漏洞,禁止告诉中国!
猜你喜欢

Comparison between new and old interfaces

通俗易懂理解朴素贝叶斯分类的拉普拉斯平滑

mysql数据库汉字模糊查询出现异常

The tutor invites you to continue your doctoral study with him. Will you agree immediately?

Feedforward feedback control system design (process control course design matlab/simulink)

If you find any loopholes later, don't tell China!

On anchors in object detection

Win10快捷键整理

Explain the imaging principle of various optical instruments in detail

Tcp/ip explanation (version 2) notes / 3 link layer / 3.4 bridge and switch / 3.4.1 spanning tree protocol (STP)
随机推荐
Feedforward feedback control system design (process control course design matlab/simulink)
C语言学习-Day_06
.NET 中的引用程序集
mysql数据库汉字模糊查询出现异常
Tcp/ip explanation (version 2) notes / 3 link layer / 3.4 bridge and switch / 3.4.1 spanning tree protocol (STP)
10 common website security attack means and defense methods
产品力对标海豹/Model 3,长安深蓝SL03预售17.98万起
多线程实现 重写run(),怎么注入使用mapper文件操作数据库
flutter 微信分享
Explain the imaging principle of various optical instruments in detail
【TcaplusDB知识库】TcaplusDB机器初始化和上架介绍
三层架构中,数据库的设计在哪一层实现,不是在数据存储层吗?
Queue, two-way queue, and its application
[从零开始学习FPGA编程-47]:视野篇 - 第三代半导体技术现状与发展趋势
JS client storage
前馈-反馈控制系统设计(过程控制课程设计matlab/simulink)
go-zero微服务实战系列(七、请求量这么高该如何优化)
C language learning day_ 04
Record in detail the implementation of yolact instance segmentation ncnn
Advantages and disadvantages of distributed file storage system