redis - Spring Data 对 Redis BRPOPLPUSH 的支持

标签 redis jedis spring-data-redis

我正在使用 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:为什么会有这么多变体..?或者什么时候使用 boundListOpsopsForListgetConnection

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()); 改为接受 MapString/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/

相关文章:

redis - 如何在redis中存储排序的对象集?

spring - 集成基于 Spring 的 Java 应用程序和 Clojure 库

c# - 在 StackExchange.Redis 中通过键模式获取值

docker - Apache Ignite 缓存操作失败

java - RediscacheManager 实例,Spring data redis 版本高于 2.0x

spring - 是否可以使用RedisRepositories和KeyValueRepositories?

redis sentinel 没有将 +sdown 升级为 +odown

spring - 多对多关系的 Redis 数据建模

spring-boot - spring-data-redis,空列表属性值变为空

reactive - 将 Spring Data 的 ReactiveCrudRepository 应用于 Redis