java使用lua脚本操作 redis_Jedis与Lua脚本结合

eg

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

script参数是一段Lua脚本程序,它会被运行在Redis服务器上下文中,这段脚本不必(也不应该)定义为一个Lua函数。

numkeys参数用于指定键名参数的个数。

键名参数 key [key ...] 从EVAL的第三个参数开始算起,表示在脚本中所用到的那些Redis键(key),这些键名参数可以在 Lua中通过全局变量KEYS数组,用1为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。

在命令的最后,那些不是键名参数的附加参数 arg [arg ...] ,可以在Lua中通过全局变量ARGV数组访问,访问的形式和KEYS变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)

如:

eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 username age jack 20

10426501.html

10426501.html

432f2979c9c267ad9a7f9977fac8a6fa.png

一般java运行lua脚本,采用的也是类似上述表达式,后面描述

(2)对于一段长的lua脚本,可以将脚本放在一个文件中,通过如下命令执行lua脚本

$ redis-cli --eval path/to/redis.lua KEYS[1] KEYS[2] , ARGV[1] ARGV[2] ...

--eval,告诉redis-cli读取并运行后面的lua脚本

path/to/redis.lua,是lua脚本的位置

KEYS[1] KEYS[2],是要操作的键,可以指定多个,在lua脚本中通过KEYS[1], KEYS[2]获取

ARGV[1] ARGV[2],参数,在lua脚本中通过ARGV[1], ARGV[2]获取。

注意: KEYS和ARGV中间的 ',' 两边的空格,不能省略。

看下面例子:

在如下文件夹中以一个lua脚本    jedisCallLuaTest.lua

6b205cb5ed39706f67d6e43d205048f3.png

local key=KEYS[1]local args=ARGV

//说明:设置一个key = userName,value=Jack,20s过期时间return redis.call("setex",key,unpack(args))

64658824d7b4b3fb53b848a61937a120.png

去客户端获取:

10426501.html

669c94218b2137ee9691d8d6085fefba.png

过期了。。。。

EVALSHA命令

将脚本 script添加到脚本缓存中,但并不立即执行这个脚本。

语法如下:

redis 127.0.0.1:6379>EVALSHA sha1 numkeys key [key ...]arg [arg ...]

参数说明:

sha1: 通过 SCRIPT LOAD 生成的 sha1 校验码。

numkeys: 用于指定键名参数的个数。

key [key ...]: 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。

arg [arg ...]: 附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。

eg:

f41bf9f3c52e4c3379c5f5c945b070b8.png

整合Jedis + lua

(1)Jedis的使用

创建Jedis对象,主要是用于单个redis

public classRedisClient {private static JedisPool    jedisPool    = null;private static String        addr        = "127.0.0.1";private static int            port        = 6379;static{try{

JedisPoolConfig config= newJedisPoolConfig();//连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true

config.setBlockWhenExhausted(true);//设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最 大空闲连接数)

config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");//是否启用pool的jmx管理功能, 默认true

config.setJmxEnabled(true);//MBean ObjectName = new//ObjectName("org.apache.commons.pool2:type=GenericObjectPool,name="//+ "pool" + i); 默认为"pool", JMX不熟,具体不知道是干啥的...默认就好.

config.setJmxNamePrefix("pool");//是否启用后进先出, 默认true

config.setLifo(true);//最大空闲连接数, 默认8个

config.setMaxIdle(8);//最大连接数, 默认8个

config.setMaxTotal(8);//获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,//默认-1

config.setMaxWaitMillis(-1);//逐出连接的最小空闲时间 默认1800000毫秒(30分钟)

config.setMinEvictableIdleTimeMillis(1800000);//最小空闲连接数, 默认0

config.setMinIdle(0);//每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3

config.setNumTestsPerEvictionRun(3);//对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数//时直接逐出,不再根据MinEvictableIdleTimeMillis判断 (默认逐出策略)

config.setSoftMinEvictableIdleTimeMillis(1800000);//在获取连接的时候检查有效性, 默认false

config.setTestOnBorrow(false);//在空闲时检查有效性, 默认false

config.setTestWhileIdle(false);//逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1

config.setTimeBetweenEvictionRunsMillis(-1);

jedisPool= new JedisPool(config, addr, port, 3000);

}catch(Exception e) {

e.printStackTrace();

}

}public synchronized staticJedis getJedis() {try{if (jedisPool != null) {

Jedis resource=jedisPool.getResource();returnresource;

}else{return null;

}

}catch(Exception e) {

e.printStackTrace();return null;

}

}public static void close(finalJedis jedis) {if (jedis != null) {

jedis.close();

}

}/*---------------------测试---------------------------*/public static voidmain(java.lang.String[] args) {

Jedis jedis=RedisClient.getJedis();//do something

RedisClient.testCallLua(jedis);

RedisClient.close(jedis);

}public static voidtestCallLua(Jedis jedis){

String luaStr= "return {KEYS[1],KEYS[1],ARGV[1],ARGV[2]}";

Object result= jedis.eval(luaStr, Lists.newArrayList("userName","age"), Lists.newArrayList("Jack","20"));

System.out.println(result);

}

}

运行结果:

[userName, userName, Jack, 20]

同理将工程中的lua文件加载成String,作为参数运行也是可行的。

14f8fe92375a4fd137d3742cff7247dc.png

java: 该段代码图个方便,引用了guava.jar包

/*** 调用lua脚本

*@paramjedis*/public static voidtestCallLuaFile(Jedis jedis){

String luaStr= null;//带反斜杠,路径为classPath,不带反斜杠,路径为类的同一目录

Reader r = new InputStreamReader(RedisClient.class.getResourceAsStream("/jedisCallLuaTest.lua"));try{

luaStr=CharStreams.toString(r);

Object result= jedis.eval(luaStr, Lists.newArrayList("userName"), Lists.newArrayList("20","Tom"));

System.out.println(result);

}catch(IOException e) {

e.printStackTrace();

}

}

注意:getResourceAsStream()这可是好帮手,用到将文件内容加载成String,一定要想到他。CharStreams是guava.jar中的对象。

Reader转String还有如下两种伎俩:(发散。。。。)

@Testpublic void apcheIo() throwsIOException{

String luaStr=null;//带反斜杠,路径为classPath,不带反斜杠,路径为类的同一目录

Reader r= new InputStreamReader(Reader2StrDemo.class.getResourceAsStream("/jedisCallLuaTest.lua"));

luaStr=org.apache.commons.io.IOUtils.toString(r);

System.out.println(luaStr);

}

@Testpublic void java8() throwsIOException{

String luaStr=null;

String path= "F:\\xxxx\\ideaProjects\\java8-pro\\resource\\jedisCallLuaTest.lua";

luaStr=Files.lines(Paths.get(path),Charset.defaultCharset()).collect(Collectors.joining());

System.out.println(luaStr);

}

运行结果:

41c049808f93424bbed97ab4225ac6e9.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值