redis 管道,一次性的把多条命令发送到服务器端,节省网络开销
管道没有考虑事务和一致性的问题,如果pipeline有10条命令,其中地2-4条没有成功,其他的命令也会提交,只是把结果返回回来。
public class RedisPipeLine {
public static void main(String[] args) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(20);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMinIdle(5);
JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.0.109",6379,3000,null);
Jedis jedis = null;
jedis = jedisPool.getResource();
Pipeline piple = jedis.pipelined();
for (int i = 0; i < 10; i++) {
piple.incr("helloworld");
piple.set("Allen"+i, Math.random()+"");
}
List list = piple.syncAndReturnAll();
System.out.println(list);
}
}
执行结果为:
[1, OK, 2, OK, 3, OK, 4, OK, 5, OK, 6, OK, 7, OK, 8, OK, 9, OK, 10, OK]
Process finished with exit code 0
在redis中查看执行的效果:
127.0.0.1:6379> keys Allen*
1) "Allen"
2) "Allen1"
3) "Allen3"
4) "Allen9"
5) "Allen8"
6) "Allen2"
7) "Allen5"
8) "Allen6"
9) "Allen4"
10) "Allen7"
11) "Allen0"
12) "Allen-Lingling"
127.0.0.1:6379> get Allen5
"0.11796745342678339"
127.0.0.1:6379>
Reids Lua 脚本,可以实现对批量命令的事务和原子操作
大量的使用lua脚本会影响redis的并行度。因为他把你写的script当作是一条命令执行,redis的命令执行单线程是顺序的。
分布式锁可以用lua脚本来实现。
Lua 脚本实例:
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"
127.0.0.1:6379>
在java中使用Lua脚本:
public class RedisLuaScript {
public static void main(String[] args) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(20);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMinIdle(5);
JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.0.109",6379,3000,null);
Jedis jedis = null;
jedis = jedisPool.getResource();
jedis.set("product_Stock","15");
String luaScript = "local count = redis.call('get',KEYS[1]) "+
"local a = tonumber(count) "+
"local b = tonumber(ARGV[1]) "+
"if a>= b then " +
"redis.call('set',KEYS[1],a-b) " +
// "bb==0" +
"return 1 " +
"end " +
"return 0 ";
Object obj = jedis.eval(luaScript, Arrays.asList("product_Stock"),Arrays.asList("10"));
System.out.println(obj);
}
}
执行结果:
1
Process finished with exit code 0
在reids中查看库存结果:
127.0.0.1:6379> get product_Stock
"5"
127.0.0.1:6379>
在script中加入解注释: "bb==0", 执行会报错,前面执行的减库存操作会回滚
Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: ERR Error compiling script (new function): user_script:1: '=' expected near '=='
at redis.clients.jedis.Protocol.processError(Protocol.java:132)
at redis.clients.jedis.Protocol.process(Protocol.java:166)
at redis.clients.jedis.Protocol.read(Protocol.java:220)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:318)
at redis.clients.jedis.Connection.getOne(Connection.java:296)
at redis.clients.jedis.Jedis.getEvalResult(Jedis.java:2845)
at redis.clients.jedis.Jedis.eval(Jedis.java:2779)
at redis.clients.jedis.Jedis.eval(Jedis.java:2831)
at allen.redis.RedisLuaScript.main(RedisLuaScript.java:33)
Process finished with exit code 1
在reids中查看库存结果:
127.0.0.1:6379> get product_Stock
"15"
127.0.0.1:6379>