【发布时间】:2017-08-06 10:12:16
【问题描述】:
我正在使用 Jedis 通过 Spring Data 访问 Redis。
<bean
id="jedisPoolConfig"
class="redis.clients.jedis.JedisPoolConfig"
p:maxTotal="100"
p:maxIdle="10"
p:maxWaitMillis="5000"
/>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.server.host}" p:port="${redis.server.port}"
p:password="${redis.server.password}"
p:use-pool="${redis.server.usepool}"
p:pool-config-ref="jedisPoolConfig"/>
<bean id="genericJackson2JsonRedisSerializer" class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
<bean id="stringSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<!-- redis template definition -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory"> <property name="keySerializer" ref="stringSerializer"/>
<property name="hashKeySerializer" ref="stringSerializer"/>
<property name="hashValueSerializer" ref="genericJackson2JsonRedisSerializer"/>
</bean>
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="jedisConnectionFactory" />
想要执行BRPOPLPUSH,我在
OPTION_1 -> getRedisTemplate().boundListOps("Key").*
OPTION_2 -> getRedisTemplate().opsForList().rightPopAndLeftPush("sourceKey", "destinationKey") ---> No blocking ?
取而代之的是,
OPTION_3 -> getRedisTemplate().getConnectionFactory().getConnection().bRPopLPush(timeout, srcKey, dstKey)
问题_0:这是唯一的选择吗?为什么上面两个api都没有?
Answer_0:不,只要在boundListOps、opsForList 中用left/rightPop(timeout, unit) 提及时间单位,它就会阻塞调用。 0秒的时间单位永远阻塞。
问题_1:为什么会有这么多变种..?或者可能何时使用boundListOps、opsForList 和getConnection?
Partial_Answer_1:看起来如果多个操作要作用于单个键然后boundListOps,因为它绑定到单个键,并且在重复动作中无需提及,其中如opsForList,每个操作键都必须提到。
来自boundListOps的文档:
返回对绑定到给定的列表值执行的操作 键。
请注意,boundListOps 仍然通过将注册的密钥传递给它来固有地使用 opsForList。
好的,我什么时候应该直接使用getConnectionFactory().getConnection()?
问题_2:如果我使用getConnectionFactory().getConnection(),我是否需要在finally(){} 下关闭()这个连接? (因为这是目前拥有blocking RPopLPush 支持的那个)。
从代码中boundListOps 本质上是使用 opsForList,它的所有动作都是用 finally 执行的,如下所示,带有释放连接,因此被问到。
RedisTemplate.java
public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
RedisConnectionFactory factory = getConnectionFactory();
RedisConnection conn = null;
try {
conn = RedisConnectionUtils.getConnection(factory);
...
...
// TODO: any other connection processing?
return postProcessResult(result, connToUse, existingConnection);
} finally {
RedisConnectionUtils.releaseConnection(conn, factory);
}
问题_3:为什么getRedisTemplate().boundListOps("key").rightPush(new HashMap()); 接受Map 而不是像String/Object 这样的值,虽然"key" 已经被提及...?
Answer_3:这是我的问题,我已经这样声明了。
public RedisTemplate<String, Map<String, Object>> getRedisTemplate() {
return redisTemplate;
}
在获取从 RedisTemplate 引用 V 的 DefaultBoundListOperations 时,传递相同的 RedisTemplate 对象。
public BoundListOperations<K, V> boundListOps(K key) {
return new DefaultBoundListOperations<K, V>(key, this);
}
class DefaultBoundListOperations<K, V> extends DefaultBoundKeyOperations<K> implements BoundListOperations<K, V> {
public DefaultBoundListOperations(K key, RedisOperations<K, V> operations) {
super(key, operations); //RedisOperations<K, V> is converted to BoundListOperations<K, V> here
this.ops = operations.opsForList();
}
}
问题_4:为什么getConnection().bRPopLPush 接受srcKey, dstKey 作为byte[] 而不是String ..?
抱歉有很多问题,都是因为我在 spring data 或教程中找不到合适的 java doc 来解释用法。
【问题讨论】:
标签: redis jedis spring-data-redis