lua语法可以再https://www.runoob.com/lua/lua-tutorial.html 这个网站上先学习,讲的还是挺清楚的,由于项目开发中用到的比较少,所以并没有深入学习,知识学了基本的用法。
EVAL语法
eval script numkeys key [key ...] arg [arg ...]
script 是lua脚本
numkeys 表示key的数量, 后面可以跟多个key以及value
redis.call函数的返回值就是redis命令的执行结果,使用return将执行结果返回,如果不写return则默认返回nil。
# 设置key为name ,value 为wang
127.0.0.1:6379> eval "return redis.call('set',KEYS[1],ARGV[1])" 1 name wang
OK
# 设置多个值
127.0.0.1:6379> eval "return redis.call('mset',KEYS[1],ARGV[1],KEYS[2],ARGV[2])" 2 name sex zhangsan man
OK
#获取多个值
127.0.0.1:6379> eval "return redis.call('mget',KEYS[1],KEYS[2])" 2 name sex
1) "zhangsan"
2) "man"
运行a.lua文件
新建a.lua文件,文件内容如下:
local mytable ={};
mytable[1] = "aa";
mytable["now"]=KEYS[1];
return mytable["now"];
运行a.lua文件并输出结果
[root@instance-qv8bbpvs redis]# ./redis-cli -p 6379 -a 123456 --eval ./a.lua 21
jedis中使用
直接写个实例来的清晰。jedis有一个方法是eval(),可以执行lua脚本。这里举一个抢红包例子来说明
初始化红包的方法,将初始化的红包存到redis的list中
public void initHb(String key, int num, int money) {
String[] arr = new String[num];
int temp = money;
for (int i = 0; i < num; i++) {
if (i == num -1) {
arr[i] = String.valueOf(temp);
break;
}
Random random = new Random();
int r = random.nextInt(temp*2/3 );
temp = temp - r;
arr[i] = String.valueOf(r);
}
System.out.println(key +"发的红包是:"+ JSON.toJSONString(arr));
jedisUtils.lpush(key, arr);
}
抢红包的方法
public void eval(String userId, String moneyListKey) {
String setKey = moneyListKey + "bn";
String userMeney = moneyListKey + "um";
A aa = new A();
aa.setUserId(userId);
aa.setMoneyListKey(moneyListKey);
String json = JSON.toJSONString(aa);
String a = "if redis.call('SISMEMBER',KEYS[1],KEYS[2]) ==1 then\n" +
"return nil\n" +
"else\n" +
"local hongbao=redis.call('rpop',KEYS[3]);\n" +
"if hongbao then\n" +
"redis.call('sadd',KEYS[1],KEYS[2]);\n" +
"local x = cjson.decode(KEYS[5]);\n" +
"x['money'] = hongbao;\n" +
"local re = cjson.encode(x);\n" +
"redis.call('lpush','KEYS[4]',re);\n" +
"return re\n" +
"end\n" +
"end\n" +
"return nil\n";
Object eval = jedisUtils.eval(a, 5, setKey, userId, moneyListKey, userMeney, json);
if ( eval!= null) {
A a1 = JSON.parseObject(JSON.parse(String.valueOf(eval)).toString(), A.class);
System.out.println(a1.getUserId()+ "抢到了"+ a1.getMoneyListKey() + "的红包" + a1.getMoney() + "元");
}
}
模拟抢红包
List<String> moneyKey = new ArrayList<>();
for (int i = 0; i < 5; i++) {
redEnvelopeService.initHb("张三"+ i,10,20);
moneyKey.add("张三"+ i);
}
for(int i = 0 ; i < 20 ; i ++){
Thread thread = new Thread(){
public void run(){
for (int j = 0; j < 100; j++) {
Random random = new Random();
int r = random.nextInt(5 );
int r2 = random.nextInt(20 );
redEnvelopeService.eval("李四"+ r2, moneyKey.get(r));
}
}
};
thread.start();
}
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
}
运行结果是
张三0发的红包是:["1","6","5","1","3","0","1","0","0","3"]
张三1发的红包是:["10","1","3","2","1","0","0","0","1","2"]
张三2发的红包是:["6","6","4","0","0","1","0","1","0","2"]
张三3发的红包是:["11","4","1","1","0","1","0","0","0","2"]
张三4发的红包是:["2","7","2","5","1","0","0","1","0","2"]
李四17抢到了张三0的红包1元
李四13抢到了张三2的红包6元
李四15抢到了张三4的红包2元
李四11抢到了张三2的红包1元
李四6抢到了张三4的红包0元
李四11抢到了张三4的红包7元
李四3抢到了张三4的红包2元
李四5抢到了张三1的红包1元
李四5抢到了张三2的红包0元
李四19抢到了张三0的红包6元
李四14抢到了张三4的红包5元
李四7抢到了张三4的红包1元
李四14抢到了张三2的红包0元
李四3抢到了张三2的红包4元
李四9抢到了张三3的红包11元
李四12抢到了张三1的红包10元
李四1抢到了张三2的红包6元
李四10抢到了张三1的红包3元
李四2抢到了张三3的红包1元
李四12抢到了张三0的红包1元
李四18抢到了张三2的红包1元
李四15抢到了张三2的红包2元
李四12抢到了张三2的红包0元
李四4抢到了张三1的红包0元
李四18抢到了张三0的红包3元
李四2抢到了张三2的红包0元
李四13抢到了张三1的红包2元
李四8抢到了张三3的红包1元
李四7抢到了张三1的红包1元
李四8抢到了张三0的红包5元
李四11抢到了张三3的红包4元
李四3抢到了张三3的红包0元
李四7抢到了张三3的红包1元
李四7抢到了张三0的红包0元
李四2抢到了张三4的红包0元
李四5抢到了张三4的红包0元
李四13抢到了张三3的红包0元
李四11抢到了张三0的红包1元
李四19抢到了张三4的红包1元
李四16抢到了张三0的红包0元
李四3抢到了张三1的红包0元
李四10抢到了张三4的红包2元
李四0抢到了张三1的红包0元
李四1抢到了张三0的红包3元
李四17抢到了张三3的红包0元
李四18抢到了张三3的红包0元
李四16抢到了张三1的红包1元
李四13抢到了张三0的红包0元
李四18抢到了张三1的红包2元
李四5抢到了张三3的红包2元