原文:https://github.com/xetorthio/jedis/wiki/AdvancedUsage
事务
在Jedis中使用事务,需要在一个事务块中包装一系列的操作,非常像pipelining:
1 |
jedis.watch (key1, key2, ...); |
2 |
BinaryTransaction t = jedis.multi(); |
注意:当有一些方法有返回值,必须像下面这样做:
01 |
Transaction t = jedis.multi(); |
03 |
Response<String> result1 = t.get( "fool" ); |
05 |
t.zadd( "foo" , 1 , "barowitch" ); |
06 |
t.zadd( "foo" , 0 , "barinsky" ); |
07 |
t.zadd( "foo" , 0 , "barikoviev" ); |
08 |
Response<Set<String>> sose = t.zrange( "foo" , 0 , - 1 ); |
11 |
String foolbar = result1.get(); |
12 |
int soseSize = sose.get().size(); |
注意Response对象在t.exec()被调用前是不会包含结果的。不调用exec会发生异常。
注意2:Redis不允许在一个事务内使用事务的中间结果。以下代码是不会正常运行的:
2 |
Transaction t = jedis.multi(); |
3 |
if (t.get( "key1" ).equals( "something" ); |
4 |
t.set( "key2" , "value2" ). |
然而,有一些像setnx的命令。这些在事务是被支持的。很快就可以使用LUA脚本来自定义命令.
Pipelining
有时需要发送一堆不同的指令。有一个很好的方式去执行,并且比原始的调用方式性能要好,就是使用pipelining.使用这种方式发送指令不用等待响应,是在最后读取返回值,更快.
以下是如何使用它:
01 |
Pipeline p = jedis.pipelined(); |
03 |
p.zadd( "foo" , 1 , "barowitch" ); |
04 |
p.zadd( "foo" , 0 , "barinsky" ); |
05 |
p.zadd( "foo" , 0 , "barikoviev" ); |
06 |
Response<String> pipeString = p.get( "fool" ); |
07 |
Response<Set<String>> sose = p.zrange( "foo" , 0 , - 1 ); |
10 |
int soseSize = sose.get().size(); |
11 |
Set<String> setBack = sose.get(); |
发布/订阅
在Redis中去订阅一个通道,需要创建JedisPubSub并且调用订阅方法
01 |
class MyListener extends JedisPubSub { |
02 |
public void onMessage(String channel, String message) { |
05 |
public void onSubscribe(String channel, int subscribedChannels) { |
08 |
public void onUnsubscribe(String channel, int subscribedChannels) { |
11 |
public void onPSubscribe(String pattern, int subscribedChannels) { |
14 |
public void onPUnsubscribe(String pattern, int subscribedChannels) { |
17 |
public void onPMessage(String pattern, String channel, |
22 |
MyListener l = new MyListener(); |
24 |
jedis.subscribe(l, "foo" ); |
注意订阅是一个阻塞的操作。单个的JedisPubSub实例可以被有来订阅多个通道。可以在已存在的JedisPubSub实例上调用subscribe或者psubscribe去改变订阅.
Jedis分片
动机
在普通的Redis主/从方式,通常有一个主服务器负责"write"请求,多个从服务器负责"read"请求。这就意味着用户必须小心有效的处理从服务器的负载分配。此外,只是"read"请求被分配到多个从服务器上,但是"write"请求没有,因为很可能只有一个主服务器。对于Jedis分片可以实现"read""write"两方面扩展性。分片使用的技术是"一致性哈希",根据一些哈希算法分配一些key.一个节点被叫做"片".更进一步的优势是每个片只需要有总数据集的1/n的内存. (n是加入从服务器的数目).
缺点
因为每个片是单独的主服务器,分片有一些限制的功能:例如,不能使用事务,pipelining,发布/订阅。然而,通常这些不允许的操作是可行的,只要关心keys在一个相同的片。更进一步的缺点是当前标准实现,在运行中的ShardedJedis不能添加或者移除片。如果需要这个特性,需要重现实现ShardedJedis,允许在一个运行ShardedJedis动态的添加和移除片: yaourt - dynamic sharding implementation