注意:
Lua使用限制
Lua脚本放开限制,标准版-双节点、标准版-单节点支持用户直接调用
集群版本条件性支持:
a 所有key都应该由KEYS数组来传递,redis.call/pcall中调用的redis命令,key的位置必须是KEYS array(不能使用Lua变量替换KEYS),否则直接返回错误信息,”-ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array\r\n”。
b 所有key必须在1个slot上,否则返回错误信息,”-ERR eval/evalsha command keys must be in same slot\r\n”。
c 调用必须要带有key,否则直接返回错误信息, “-ERR for redis cluster, eval/evalsha number of keys can’t be negative or zero\r\n”
解决方案: 业务层保证key数组都落在一个solt中就可以关闭阿里云对lua脚本的限制!
java 结合 redis + lua 获取数据
实例演示为单机版
package bhz.redis01;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TestRedisAndLua {
private static Jedis jedis; //单实例[]
private static ShardedJedis shard; //分片[]
private static ShardedJedisPool pool; //池化[apache common - pool2]
@BeforeClass
public static void setUpBeforeClass() throws Exception {
//单个节点
jedis = new Jedis("192.168.1.115", 6379);
//分片
List<JedisShardInfo> shards = Arrays.asList(
new JedisShardInfo("192.168.1.115",6379));
shard = new ShardedJedis(shards);
//池化
GenericObjectPoolConfig goConfig = new GenericObjectPoolConfig();
goConfig.setMaxTotal(100);
goConfig.setMaxIdle(20);
goConfig.setMaxWaitMillis(-1);
goConfig.setTestOnBorrow(true);
pool = new ShardedJedisPool(goConfig, shards);
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
jedis.disconnect();
shard.disconnect();
pool.destroy();
}
/**
* <B>方法名称:</B>Redis使用Lua执行应用程序<BR>
* <B>概要说明:</B>
* 我们可以使用Redis+Lua的方式,实现一个完整的事务、保证事务的原子性。
* 如何使用Redis+Lua?
* 我们使用scriptLoad方法,把我们写好的lua脚本加载到Redis的内存中(注意是内存,每次重启则失效)。
* scriptLoad方法会返回一个索引Key,我们只需要通过这个索引Key就可以找到我们之前放到Redis里的脚本。
* 调用evalsha方法,传入索引key,以及操作键、参数值。进行返回 <BR>
*/
/**
* lua script:
* local t1 = redis.call('hgetall',KEYS[1]);
* if type(t1) == 'table' then
* return t1;
* end;
*/
public static final String SCRIPT =
"local t1 = redis.call('hgetall',KEYS[1]);" + "\n" +
"if type(t1) == 'table' then" + "\n" +
"return t1;" + "\n" +
"end;" + "\n" ;
@Test
public void testLua(){
String shakey = jedis.scriptLoad(SCRIPT);//加载脚本,获取sha索引
System.out.println("shakey: " + shakey);
//要获取的key值
List<String> keys = new ArrayList<>();
keys.add("myhash");
//传入的参数
List<String> args = new ArrayList<>();
// /usr/local/bin/redis-cli -h 192.168.1.115 -p 6379 --eval /usr/local/luadir/03.lua name age , baihezhuo
List<String> ret = (List<String>)jedis.evalsha(shakey, keys, args);
System.out.println(ret);
jedis.close();
}
}
版权声明:本文为nameIsHG原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。