当前位置: 代码网 > it编程>数据库>Redis > Python Redis如何执行Lua脚本

Python Redis如何执行Lua脚本

2024年05月18日 Redis 我要评论
问题描述python redis 执行 lua 脚本可实现原子性官方文档表示,redis 使用相同的 lua 解释器来运行所有命令,redis 保证脚本以原子方式执行:在执行脚本时不会执行其他脚本或

问题描述

python redis 执行 lua 脚本可实现原子性

官方文档表示,redis 使用相同的 lua 解释器来运行所有命令,redis 保证脚本以原子方式执行:

  • 在执行脚本时不会执行其他脚本或 redis 命令。
  • 这种语义类似于 multi / exec 的语义,从所有其他客户的角度来看,脚本的效果要么仍然不可见,要么已经完成。

解决方案

安装

pip install redis

代码

from redis import redis

redis = redis()
script = """
redis.call('setex', 'key', 100, 'value')
"""
redis.register_script(script)()  # 执行脚本

效果

传递参数

script 类调用函数原型:

def __call__(self, keys=[], args=[], client=none)
from redis import redis

redis = redis()
script = """
local key = keys[1]
local seconds = argv[1]
local value = argv[2]
redis.call('setex', key, seconds, value)
"""
cmd = redis.register_script(script)
cmd(keys=['key'], args=[100, 'value'])  # 执行脚本

效果同上

分布式锁

1.加锁并设过期时间 set lock_resource_name $uuid nx px $expire_time,同时启动守护线程为快要过期单还没执行完毕的客户端的锁续命;

2.客户端执行业务逻辑操作共享资源;

3.通过 lua 脚本释放锁,先 get 判断锁是否是自己加的,再执行 del

判断+删除

import time
from uuid import uuid4

from redis import redis

redis = redis()

# 判断是否自己创建的锁,是的话则释放
script = """
if redis.call('get', keys[1]) == argv[1] then
    return redis.call('del', keys[1])
else
    return 0
end
"""


def do_something():
    name = 'lock'  # 锁名,此处故意写死让别的进程进来占用
    uuid = str(uuid4())
    # 上锁
    if redis.set(name=name, value=uuid, nx=true, ex=25):  # 锁不存在才能上锁成功,过期时间应为业务时间的五倍,此处故意写小,模拟过期释放
        print('上锁')
        try:
            print('处理业务', uuid)
            time.sleep(10)
        except exception as e:
            print(e)
        finally:
            # 释放锁
            cmd = redis.register_script(script)
            res = cmd(keys=[name], args=[uuid])  # 执行脚本
            if res:
                print('锁已释放')
            else:
                print('不是自己的锁')
    else:
        print('锁已存在')


if __name__ == '__main__':
    do_something()

模拟过程:

  • 运行程序1
  • 手动迅速删掉这个锁
  • 运行程序2

效果:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。 

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com