Python Redis如何执行Lua脚本

 更新时间:2024年02月09日 08:38:07   作者:XerCis CSDN认证博客专家  
这篇文章主要介绍了Python Redis如何执行Lua脚本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

问题描述

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

效果:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。 

相关文章

  • Caffeine实现类似redis的动态过期时间设置示例

    Caffeine实现类似redis的动态过期时间设置示例

    这篇文章主要为大家介绍了Caffeine实现类似redis的动态过期时间示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • redis数据结构之压缩列表

    redis数据结构之压缩列表

    这篇文章主要介绍了redis数据结构之压缩列表,压缩列表是列表list和hash数据结构的底层实现之一,是redis为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构,下面详细内容需要的小伙伴可以参考一下
    2022-03-03
  • 一文详解如何使用Redis实现分布式锁

    一文详解如何使用Redis实现分布式锁

    这篇文章主要介绍了一文详解如何使用Redis实现分布式锁,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • Redis7.2.x主从复制的实现示例

    Redis7.2.x主从复制的实现示例

    本文主要介绍了Redis7.2.x主从复制的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-06-06
  • 为何Redis使用跳表而非红黑树实现SortedSet

    为何Redis使用跳表而非红黑树实现SortedSet

    本篇文章主要介绍了为何Redis使用跳表而非红黑树实现SortedSet,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Redis Stat的安装指南

    Redis Stat的安装指南

    这篇文章主要介绍了Redis Stat的安装指南的相关资料,需要的朋友可以参考下
    2016-04-04
  • 在CentOS 7环境下安装Redis数据库详解

    在CentOS 7环境下安装Redis数据库详解

    Redis是一个开源的、基于BSD许可证的,基于内存的、键值存储NoSQL数据本篇文章主要介绍了在CentOS 7环境下安装Redis数据库详解,有兴趣的可以了解一下。
    2016-11-11
  • Web-ssrfme:redis 未授权访问攻击的问题解决

    Web-ssrfme:redis 未授权访问攻击的问题解决

    本文主要介绍了Web-ssrfme:redis 未授权访问攻击的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-04-04
  • 浅谈Redis跟MySQL的双写问题解决方案

    浅谈Redis跟MySQL的双写问题解决方案

    项目中有遇到这个问题,跟MySQL中的数据不一致,记录一下,本文主要介绍了Redis跟MySQL的双写问题解决方案,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Redis分布式锁如何设置超时时间

    Redis分布式锁如何设置超时时间

    这篇文章主要介绍了Redis分布式锁如何设置超时时间,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11

最新评论