`
on__the__way
  • 浏览: 24017 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Redis事务和脚本功能

 
阅读更多

     Redis事务是指将一些命令打包,一次性按顺序执行多个命令的机制,不会出现并发的情况,将命令都执行完以后才会执行其他命令。在一定程度上满足ACID特性。

    1、Redis事务原理

    事务由命令MULTI开始,使执行命令的客户端切换到事务状态,之后当执行EXEC、DISCARD、WATCH、MULTI以外的命令均会将命令放在一个先进先出的队列中。当向客户端发送EXEC命令时,服务器将会遍历事务队列按顺序执行其中的指令。并将返回结果在执行完毕后一起返回。

    由于事务的命令提交是一个过程,在事务命令提交过程中即在EXEC执行之前,存在事务执行的命令被修改的可能,若对事务中的某些key修改敏感,可以使用WATCH命令监听某些key,如果在事务执行之前监听的key被修改,则该事物拒绝执行。其实现原理是在Redis中保存了一个监听key的字典,key为监听的键而value是监听该键的数据库客户端。当key被修改后Redis会查看该字典该key是否被客户端监听,若正在被监听则会打开value对应的客户端的REDIS_DIRTY_CAS标识,当执行EXEC命令时会检测该标识是否打开,打开则拒绝执行该事务。

    注意,WATCH命令的作用只是当被监控键被修改后阻止之后的一个事务执行,而不能保证其他客户端是否修改,同时监听的有效期是EXEC之后,之后所有的监控被取消。

    ACID特性

    原子性,指的是数据库将食物中的多个操作当做一个整体来执行,服务器要么全部执行,要么全不执行。Redis事务具有原子性,但Redis不具有回滚机制,及时某个命令出现错误也会继续执行后面的命令。

    一致性,指的是数据库在事务执行之前是一致的,那么在执行之后也是一致的,没有非法或无效的错误。Redis事务中有三类错误,一是命令不存在或命令格式不正确的错误,在入队时可发现,事务拒绝执行。对数据库键执行错误类型的操作是第二类错误,跳过错误执行继续执行。宕机是第三类错误,但数据仍能保证一致性。

    隔离性,指数据库中多个事务并发执行也互不影响,与顺序执行结果相同。Redis是单线程顺序执行事务,因此满足隔离性。

    持久性,指当执行以后永久保存到存储中。Redis的持久性由Redis的持久化机制来决定,无持久化则没有持久性,RDB机制需要条件触发也不满足,AOF机制当appendfsync为always是满足持久性,而为everysec时会出现数据丢失也不满足,为no时也不具有持久性。

   2、Lua脚本

   与Redis事务类似,Lua脚本功能是将Redis的命令打包成一个lua脚本,在服务器端原子的执行。与Redis的事务特性相比减少了网络开销,一次提交打包的命令;原子性执行避免出现Watch的竞态条件;同时可以被复用,存储以便之后继续使用。

    创建Redis的Lua环境

    调用lua_open创建原始lua环境,载入Lua函数库包括base、table、string、math、debug、struct等库,可以修改redis返回的数据。创建全局表格包括Redis.call和Redis.pcall、Redis.log等执行redis命令的函数。

    为保证相同的脚本在不同的机器上产生相同的结果,Redis要求Lua中运行的函数是无副作用的纯函数。主要涉及随机函数和排序函数。math的随机函数有副作用,Redis使用自己的随机函数,只要种子seed相同结果相同。同时像集合这种无序的类型内容相同但是添加顺序不同也会造成结果不同。因此对于顺序敏感的命令Redis会先做一次排序。

    创建错误处理辅助函数,在脚本中的变量应使用local生命避免污染环境,如果没有加local会报错。

    Redis会将创建的Lua环境在redisServer结构体中与Redis进行关联。

    执行Lua脚本

    Redis执行命令必须有客户端状态,这里为了执行Lua脚本通过伪客户端执行。执行步骤如下图

    Redis创建lua字典用来保存lua脚本,键是检验和值是Lua脚本。RVAL和SCRIPT LOAD载入的脚本都会被保存。EVAL会将脚本定义名为一个f_+校验和的函数,之后将脚本添加到字典中,最后将EVAL传入的键名和参数作为keys数组和ARGV数组作为全局变量传入lua环境,并设置钩子函数,执行脚本会进行垃圾回收。

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

    另一个执行lua脚本的命令是EVALSHA,用于之前已经在LUA环境中定义过的脚本,通过SHA1校验和调用。SCRIPT FLUSH用于清除服务器中所有lua脚本的信息,释放字典内容,重新创新新lua环境。SCRIPT EXISTS命令根据输入的检验和检查对应的脚本是否存在。SCRIPT LOAD与EVAL相同。SCRIPT KILL进行超时处理。

    EVALSHA sha1 numkeys key [key ...] arg [arg ...]

    Lua脚本的复制。

    EVAL、SCRIPT FLUSH、SCRIPT LOAD命令直接同步,在主从服务器都会被执行。EVALSHA命令根据校验和执行,但主从服务器可能保存的脚本情况不一,可能出现脚本找不到的情况。因此Redis在复制EVALSHA时会先通过reol_scriptcache_dict字典记录的所有lua脚本中查看是否有该校验和, 如果没有则转换我EVAL命令进行传播。当添加新的从服务器是,会清空reol_scriptcache_dict字典,来确保新的从服务器不会出现脚本找不到的错误。

    其他

    为了防止某个脚本执行时间过长导致Redis无法提供服务(比如陷入死循环),Redis提供了lua-time-limit参数限制脚本的最长运行时间,默认为5秒钟。当脚本运行时间超过这一限制后,Redis将开始接受其他命令但不会执行(以确保脚本的原子性,因为此时脚本并没有被终止),而是会返回“BUSY”错误。通过SHUTDOWN NOSAVE不进行持久化来操作

  • 大小: 22.6 KB
分享到:
评论

相关推荐

    Java学习资料-Spring Boot - 结合 Redis 使用 Lua脚本

    事务处理:使用 Lua 脚本可以实现事务处理,保证数据的一致性和完整性。 限流、熔断等控制:使用 Lua 脚本可以实现一些控制逻辑,例如限流、熔断等。 优点: 原子性操作:Lua 脚本可以保证一系列操作的原子性,避免...

    2023年Redis缓存面试题目汇总

    在什么情况下你会使用Redis事务? Redis事务的ACID性质是什么? Redis的Lua脚本有什么作用? 你如何理解Redis的发布/订阅功能? Redis的排行榜功能是如何实现的? Redis的缓存失效策略是什么? 在分布式环境下,如何...

    redis可视化工具、免费.中文

    Redis 事务 Redis 脚本 Redis 服务器 Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等...

    尚硅谷_Redis.docx

    在本课程中,你将了解Redis是什么、能干什么、如何用,了解NoSQL的使用场景和概念,快速掌握Redis的安装配置、五大数据类型、常用操作命令、Redis持久化、主从复制、事务控制以及用Jedis操作进行Java开发等知识。...

    redis window最新免安装版本

    Redis 具有内置复制、 Lua 脚本编写、 LRU 垃圾清理、事务处理和不同级别的磁盘持久性,并通过 Redis Sentinel 提供高可用性和使用 Redis Cluster 自动分区。 为了实现最佳性能,Redis 使用内存中的数据集。根据用例...

    尚硅谷Redis入门视频

    在本课程中,你将了解Redis是什么、能干什么、如何用,了解NoSQL的使用场景和概念,快速掌握Redis的安装配置、五大数据类型、常用操作命令、Redis持久化、主从复制、事务控制以及用Jedis操作进行Java开发等知识。...

    Java核心面试知识集-Redis面试题

    2.为什么redis事务不具备原子性 单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。 事务可以理解为一个打包的批量执行脚本,但批量指令并非...

    redis-3.0.1 和 RedisDesktopManager win-64 版本

    redis-3.0.1 和 RedisDesktopManager win-64 版本 ... Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence)

    Redis面试题.pdf

    请说明Redis事务的特点和使用方式。 9. Redis集群是如何实现高可用性和横向扩展的?请描述Redis集群的工作原理。 10. Redis如何处理并发访问和数据竞争问题?请谈谈Redis的并发控制机制。 11. Redis中的管道...

    redis6.0.9.rar

    Windows下可直接执行版本 Redis 是一个开源(BSD许可)的,内存中的数据结构... Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘

    redis开发的概要介绍与分析

    此外,还有一些Java的Redis客户端,如Redisson和Jedis等,它们提供了丰富的功能和API,使得在Java应用程序中使用Redis变得更加简单。这些客户端库通常支持Redis的各种功能,并提供了高效的序列化和反序列化机制。 ...

    redis面试题及答案(上).pdf

    redis面试题总结学习,Redis是开源的(BSD许可)内存数据结构存储,用作...Redis具有内置的复制,Lua脚本,LRU逐出,事务和不同级别的磁盘持久性,并通过以下方式提供高可用性Redis Sentinel和Redis Cluster自动分区。

    windows版redis4

    Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区...

    Redis实战 Redis入门到精通

    除此之外, 《Redis实战》还介绍了使用短结构、分片、事务、流水线、复制、Lua 脚本等手段来扩展和优化 Redis 的方法, 这些技术可以大幅地扩展系统的性能, 并尽可能地降低程序所需的内存数量。

    SSM框架+redis+druid事务控制+定时任务介绍+sql脚本+测试说明及请求路径

    SSM框架+redis+druid事务控制+定时任务介绍+sql脚本+测试说明及请求路径,内涵redis免安装文件,txt文档说明,我用的是myeclipse2014+tomcat8配置启动的

    redis-desktop-manager-2020.1.0.0.zip

    执行命令和脚本:可以执行 Redis 命令,如获取和设置键值,执行 Redis 事务等。还可以通过 Redis 的脚本语言 Lua 运行自定义脚本。 监控 Redis 服务器:可以查看 Redis 服务器的信息,如内存使用情况、连接信息、...

    Redis开发.docx

    想象一下,你可以使用Redis的丰富功能,如发布/订阅、事务、Lua脚本等,为你的应用增加更多的功能和灵活性。 Redis不仅可以用作缓存,还可以用作会话存储、消息队列、计数器等多种用途。无论是构建Web应用、实现...

    KeyDB源码分享 它是Redis的高性能分支,专注于多线程,内存效率和高吞吐量

    KeyDB是Redis的高性能分支,专注于多线程,内存效率和高吞吐量。...这包括脚本和事务的原子性保证。由于KeyDB与Redis开发保持同步,因此KeyDB是Redis功能的超集,从而使KeyDB取代了现有Redis部署。

    cpp-predixy一款高性能全特征redis代理支持redissentinel和rediscluster

    predixy是一款高性能、全特性的redis代理,性能之高超越所有其它同类...redis全特性支持,无论是redis cluster还是redis sentinel都不在话下,更不用说redis自身的阻塞式命令、多key命令、事务、发布订阅、脚本等。

    redis-3.0.7.tar

    Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区...

Global site tag (gtag.js) - Google Analytics