redis系列文章目录

  • 使用spring-data-redis实现incr自增
  • Redis 利用Hash存储节约内存
  • Redis学习笔记(九)redis实现时时直播列表缓存,支持分页[热点数据存储]
  • Redis学习笔记(八)redis之lua脚本学习
  • Redis学习笔记(七)jedis超时重试机制注意事项
  • Redis学习笔记(六)redis实现分布式锁
  • Redis学习笔记(五)jedis(JedisCluster)操作Redis集群 redis-cluster
  • redis学习笔记(四)缓存与数据库一致性问题
  • redis学习笔记(三)数据淘汰策略
  • redis学习笔记(二)JedisCluster + redis 3.2.5集群
  • redis学习笔记(一)redis3.2.5集群安装与测试

在实际工作过程中,可以使用lua脚本来解决一些需要保证原子性的问题,而且lua脚本可以缓存在redis服务器上,势必会增加性能。
不过lua也会有很多限制,在使用的时候要注意。

demo

/*** lua脚本*/@Testpublic void script() throws InterruptedException {/** 其中 "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 是被求值的 Lua 脚本,数字 2 指定了键名参数的数量,* key1 和 key2 是键名参数,分别使用 KEYS[1] 和 KEYS[2] 访问,而最后的 first 和 second 则是附加参数,可以通过 ARGV[1] 和 ARGV[2] 访问它们。** 注意,这里一些操作不适用于redis-cluster,主要还是因为不同的key被分配到了不同的slot中*/Object eval = jedisCluster.eval("return {KEYS[1],ARGV[1],ARGV[2]}", 1, "lua", "key1", "dd");System.out.println(eval);//脚本里使用的所有键都应该由 KEYS 数组来传递://因为:所有的 Redis 命令,在执行之前都会被分析,籍此来确定命令会对哪些键进行操作。因此,对于 EVAL 命令来说,必须使用正确的形式来传递键,才能确保分析工作正确地执行System.out.println(jedisCluster.eval("return redis.call('set', KEYS[1], ARGV[1])", 1, "luaTest", "cv"));System.out.println(jedisCluster.get("luaTest"));//注意这里需要指定KEY,因为这里lua脚本也是和slot挂钩的String scriptLoad = jedisCluster.scriptLoad("return redis.call('get', KEYS[1])", "luaTest");//加载脚本System.out.println(scriptLoad);//返回的SHA1校验和,后续可以直接使用这个进行操作。System.out.println(jedisCluster.scriptExists(scriptLoad, "luaTest"));//检查是否存在System.out.println(jedisCluster.evalsha(scriptLoad, 1, "luaTest"));//执行lua脚本System.out.println(jedisCluster.scriptFlush("luaTest".getBytes()));//删除KEY as  上的所有lua脚本System.out.println(jedisCluster.scriptExists(scriptLoad, "luaTest"));System.out.println(jedisCluster.evalsha(scriptLoad, 1, "luaTest"));//脚本已经删除,返回错误:NOSCRIPT No matching script. Please use EVAL.}/*** redis中的lua脚本做了很多限制,防止随机性的发生。比如lua脚本中返回的总是有序的集合。* 详情见 http://doc.redisfans.com/script/eval.html - 纯函数脚本*/@Testpublic void scriptFuc() throws InterruptedException {String key = "luaTest";System.out.println(jedisCluster.del(key));System.out.println(jedisCluster.sadd(key, "10","3","7","40","6"));System.out.println(jedisCluster.smembers(key));//这里怎么返回的值是有序的?  [3, 6, 7, 10, 40]System.out.println(jedisCluster.eval("return redis.call('smembers', KEYS[1])", 1, key));//根据字母序排序  [10, 3, 40, 6, 7]}

spring boot 中使用LUA脚本

前提:首先要引入 spring-boot-starter-data-redis依赖,使用redisTemplate. 该配置项不在本文讲述,只讲述lua脚本的使用。

编写lua脚本

该脚本功能:先检查redis中某个key的值是否与期望的值V1一致,如果一致则将其修改为新的值V2并返回true,否则返回false。其实就是CAS。

lua:

local current = redis.call('GET', KEYS[1])
if current == ARGV[1]then redis.call('SET', KEYS[1], ARGV[2])return true
end
return false

注意,lua脚本中的变量都要是local 的,不可以是全局变量。否则会报错。详见 http://doc.redisfans.com/script/eval.html#id6

使用DefaultRedisScript加载lua脚本

我们应该在应用上下文中配置一个DefaultRedisScript 的单例,避免在每个脚本执行的时候重复创建脚本的SHA1.

@Beanpublic DefaultRedisScript<Boolean> redisScript() {DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/checkandset.lua")));redisScript.setResultType(Boolean.class);return redisScript;}

java代码中引用

@AutowiredDefaultRedisScript<Boolean> redisScript;/*** 测试redis  lua** @return*/@RequestMapping(value = "testredislua", method = {RequestMethod.GET})@ResponseBodypublic Object testredislua() {String key = "testredislua";redisTemplate.delete(key);redisTemplate.opsForValue().set(key, "hahaha");String s = redisTemplate.opsForValue().get(key);log.info(s);redisTemplate.execute(redisScript, Collections.singletonList(key), "hahaha", "3333");s = redisTemplate.opsForValue().get(key);log.info(s);return null;}

具体关于lua脚本的内容请移步至 redis命令参考–Script脚本

Redis学习笔记(八)redis之lua脚本学习相关推荐

  1. Redis 学习笔记八:集群模式

    Redis 学习笔记八:集群模式 作者:Grey 原文地址: 博客园:Redis 学习笔记八:集群模式 CSDN:Redis 学习笔记八:集群模式 前面提到的Redis 学习笔记七:主从复制和哨兵只能 ...

  2. Redis运维和开发学习笔记(3)redis搭建集群

    Redis运维和开发学习笔记(3)redis搭建集群 文章目录 Redis运维和开发学习笔记(3)redis搭建集群 Redis集群搭建 Redis集群搭建 cp /etc/redis.d/redis ...

  3. Redis运维和开发学习笔记(4) Redis参数意义

    Redis运维和开发学习笔记(4) Redis参数意义 文章目录 Redis运维和开发学习笔记(4) Redis参数意义 参数意义 参数意义 Client连接 问题 id=567800790 addr ...

  4. Redis运维和开发学习笔记(2) redis持久化

    Redis运维和开发学习笔记(2) redis持久化 文章目录 Redis运维和开发学习笔记(2) redis持久化 持久化 持久化方式一:RDB 触发~~的三种~~方式 1. save命令 2. b ...

  5. Polyworks脚本开发学习笔记(八)-组合运用命令批量改名

    Polyworks脚本开发学习笔记(八)-组合运用命令批量改名 需求解析 以下是使用包边比较点创建的一组包边点(即Gap点)和曲面点-包边点(即Flush点),这种命名方式不太常规,改为Gap和Flu ...

  6. StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用

    StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用 原文: StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用 Connec ...

  7. ZooKeeper学习笔记(八):ZooKeeper集群写数据原理

    写数据原理 写流程直接请求发送给Leader节点 这里假设集群中有三个zookeeper服务端 ACK (Acknowledge character)即是确认字符,在数据通信中,接收站发给发送站的一种 ...

  8. MongoDB 学习笔记八 复制、分片、备份与恢复、监控

    MongoDB 学习笔记八 复制.分片.备份与恢复.监控 MongoDB复制(副本集) 什么是复制? MongoDB 复制原理 MongoDB 副本集设置 副本集添加成员 MongoDB 分片 分片 ...

  9. ReactJS学习笔记八:动画

    ReactJS学习笔记八:动画 分类: react学习笔记 javascript2015-07-06 20:27 321人阅读 评论(0) 收藏 举报 react动画 目录(?)[+] 这里只讨论Re ...

最新文章

  1. Office2019完美配置mathtype7.4
  2. [转] 全面了解Windows任务管理器
  3. 五、linux总线中设备和驱动注册流程详解
  4. pprof 的原理与实现
  5. linux关于权限的案例,16. Linux权限管理案例1 - 警察与土匪
  6. AndroidStudio_使用gradle编译代码_打包apk_以及各种打包配置---Android原生开发工作笔记79
  7. Java并行编程–从并行任务集获取反馈
  8. PyCharm:Error running xxx: Cannot run program D:\Python27\python.exe
  9. 解码隆基模式:光伏企业的百亿成长之路
  10. 将Ubuntu的引导写入自己所在分区——变色龙引导Linux,Windows,Mac OS(苹果系统)攻略之一
  11. Day241242.单点登录方案【Jwt令牌、sessionredis、CAS认证服务器】 -springsecurity-jwt-oauth2
  12. 上海创蓝253董事长_从世界记忆大师到互联网百强企业CEO:创蓝253钛牛哥的传奇之路...
  13. 硬件使用74hc138的C语言程序,【Arduino教程】第三十一讲:74HC138实验
  14. kinectfusion解析_KinectFusion介绍
  15. 操作系统的fock和mmap
  16. [Javascript 高级程序设计]学习心得记录3 根据对象数组的属性进行排序
  17. 简述因特网标准制定的几个阶段?
  18. 网站建设服务办理增值电信业务经营许可证
  19. 计算机学家名言 英语,科学家英语名言
  20. MATLAB票据识别

热门文章

  1. python百度地图poi_百度地图POI的边界GEOJSON数据采集
  2. 自定义USB BULK设计(一)——固件程序,LPC2378
  3. R语言使用colSums函数对矩阵或者数据框数据的列求和、使用rbind函数行列和向量附加到原始矩阵数据尾部
  4. 2020年中国动漫产业研究报告
  5. 深入学习java源码之 Arrays.sort()与Arrays.parallelPrefix()
  6. 逻辑编排在优酷可视化搭建中的实践之上
  7. Qt开发的上位机 硬件:固高八轴运动控制卡,海康威视相机,金橙子板卡,喷码机
  8. 基于OSG讲解一下LOD
  9. FC-AE协议应用环境及特点详谈
  10. 即时配送:巨头们新十年的主战场