我正在使用 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
中用 left/rightPop(timeout, unit)
提到 timeunit,opsForList
它正在阻塞调用。时间单位为 0 秒,永远阻塞。
问题_1:为什么会有这么多变体..?或者什么时候使用 boundListOps
、opsForList
和 getConnection
?
Partial_Answer_1:看起来如果要对单个键执行多个操作则 boundListOps,因为它绑定(bind)到该单个键,并且无需在重复操作中提及它,如opsForList,必须提到每个操作键。
来自 boundListOps 的文档:
Returns the operations performed on list values bound to the given key.
请注意,boundListOps 仍然通过将已注册的 key 传递给它来固有地使用 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;
}
在获取 DefaultBoundListOperations 时传递相同的 RedisTemplate 对象,其中 V 从 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[]
而不是字符串
..?
很抱歉有很多问题,都是因为我没有在 spring 数据或教程中找到合适的 java 文档来解释用法。
最佳答案
关于问题4:首先需要注意的是Redis的键值can be any binary . Spring-data 模板将其抽象出来,让开发人员处理 Java 对象而不是字节数组。请参阅 spring-data reference 中的以下引述:
...The template offers a high-level abstraction for Redis interactions. While RedisConnection offers low level methods that accept and return binary values (byte arrays), the template takes care of serialization and connection management, freeing the user from dealing with such details.
似乎在使用 RedisConnection
时,Spring 不知道您的键或值是什么类型,并且它不会努力转换对象(例如,String
) 到 Redis 理解的二进制文件,因此,您需要将原始二进制文件传递给 Redis。
关于redis - Spring Data 对 Redis BRPOPLPUSH 的支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45530914/