redis的事务和lua

事务使用MULTIEXECDISCARDWATCH 等命令。很多情况下我们需要一次执行不止一个命令,而且需要其同时成功或者失败。redis对事务的支持也是源自于这部分需求,即支持一次性按顺序执行多个命令的能力,并保证其原子性。

在redis的官网上洋洋洒洒的大概提供了200多个命令(都是原子性的),貌似看起来很多,但是这些都是别人预先给你定义好的,但你却不能按照自己的意图进行定制,所以是不是感觉自己还是有一种被束缚的感觉,有这个感觉就对了。。。\color{green}{实际lua就是把很多命令和操作封装成了一个命令而且是原子性的}

Lua脚本是在事务的基础上,如果我们需要在服务端一次性的执行更复杂的操作(包含一些逻辑判断),则lua就可以派上用场了。它和200多个命令一样都是原子性的。所以说这极大的扩展了redis。要想学好Redis,必会Lua Script。。。感觉这个很像是mysql的存储过程。


使用Lua脚本的好处:

  • 减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络时延。
  • 原子操作。redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无需使用事务。
  • 复用。客户端发送的脚本会永久存在redis中,这样,其他客户端可以复用这一脚本而不需要使用代码完成相同的逻辑。



redis中lua介绍:

  • 使用eval来调用lua

EVAL script numkeys key [key ...] arg [arg ...]

首先大家一定要知道eval的语法格式,其中:

<1> script: lua脚本,如果是文本路径,需要加file_get_contens()来获取

<2> numkeys: key的个数

<3> key: redis中各种数据结构的替代符号

<4> arg: 你的自定义参数

在redis cli 模式下。该命令表示key的个数为2,即username和age,相应的username也就是KEY[1],age也就是key[2]。key参数后面的也就是arg参数了,也就是jack和20,相应的jack也就是ARGV[1],20也就是ARGV[2]。

127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 username age jack 20
1) "username"
2) "age"
3) "jack"
4) "20"

在php中同样也是使用eval来调用的(predis扩展)

Redis::eval(file_get_contents(storage_path("app/lock.lua")), 1, "1lock", "121313");
  • 使用call来调用redis的方法
    比如上面的文本lock.lua内容如下
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end
  • 一个简单例子
    批量写入集合
public function mSadd()
{
    $lua = <<<LUA
local _key = KEYS[1]
local _ttl = tonumber(ARGV[1])
local _values = ARGV
for idx, v in ipairs(_values) do
    if (idx > 1) then
        redis.call('SADD', _key, v)
    end
end

if (_ttl > 0) then
    local tl = redis.call('TTL', _key)
    if (tl == -1) then
        redis.call('EXPIREAT', _key, _ttl)
    end
end
return true
LUA;
    $orderNo = [1233243,434434311,4353543434];
    $expireAt = '1665478454';
    $redisKey = 'order:01409103';
    $params = array_unique(array_filter($orderNo));
    array_unshift($params, $expireAt);
    array_unshift($params, $redisKey);
    $redis = \Lta\Redis::getConn();
     //* @param string $script
     //* @param array  $args
     //* @param int    $numKeys
    $res = $redis->eval($lua, $params, 1);
    return boolval($res);
}

lua的简单用户大致如上,使用eval调用脚本,使用call来调用redis已有的方法。具体的lua脚本用法参考官网

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,265评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,078评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,852评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,408评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,445评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,772评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,921评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,688评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,130评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,467评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,617评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,276评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,882评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,740评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,967评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,315评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,486评论 2 348

推荐阅读更多精彩内容

  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,763评论 0 38
  • Redis Lua 这个技术,我之前就在关注,今天有空,我把项目中基于Redis实现的ID生成器改成用lua脚本实...
    土豆肉丝盖浇饭阅读 42,416评论 5 20
  • [TOC] 相关命令 EVAL SCRIPT_LOAD EVALSHA(执行之前要求执行过EVAL或者SCRIPT...
    志华_C阅读 5,671评论 0 4
  • 无所事事的一天,据说今天是世界读书日,是不是今天读点书就是过节了呢?每看完一本书,就觉得自己其实要去看的学的东西还...
    兮兮0225阅读 152评论 0 0
  • 1、早上20分钟听新东方音频 2、阅读牛津树:In the trolley、I see、The trampolin...
    ruiminlau阅读 347评论 0 0