国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Redis【實(shí)踐篇】之RedisTemplate基本操作

這篇具有很好參考價(jià)值的文章主要介紹了Redis【實(shí)踐篇】之RedisTemplate基本操作。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

Redis 從入門(mén)到精通【應(yīng)用篇】之RedisTemplate詳解


Redis【實(shí)踐篇】之RedisTemplate基本操作,Redis從入門(mén)到精通2023版,redis,數(shù)據(jù)庫(kù),緩存,java,后端

0. 前言

在SpringBoot中,可以使用RedisTemplate來(lái)操作Redis數(shù)據(jù)庫(kù)。RedisTemplate是Spring Data Redis提供的一個(gè)強(qiáng)大的Redis客戶(hù)端,它支持各種Redis數(shù)據(jù)結(jié)構(gòu),并提供了許多方便的方法來(lái)操作這些數(shù)據(jù)結(jié)構(gòu)。下面是一些RedisTemplate的用法示例:

1. RedisTemplate 方法

1. 設(shè)置RedisTemplate的序列化方式

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 設(shè)置key和value的序列化方式
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));

        // 設(shè)置hash key和value的序列化方式
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));

        return redisTemplate;
    }
}

在此示例中,創(chuàng)建了一個(gè)RedisTemplate對(duì)象,并設(shè)置了key和value的序列化方式為StringRedisSerializer和Jackson2JsonRedisSerializer。同時(shí),還設(shè)置了hash key和value的序列化方式。

2. RedisTemplate的基本操作

其實(shí)在項(xiàng)目中我們通常會(huì)將RedisTemplate 再封裝一層,作為一個(gè)Redis操作類(lèi)處理,相當(dāng)于提供了一層語(yǔ)法糖。

@Service
public class RedisService {

    // RedisTemplate是Spring提供的對(duì)Redis的操作模板類(lèi),使用泛型限定key和value的類(lèi)型為String和Object
    private final RedisTemplate<String, Object> redisTemplate;

    // 構(gòu)造函數(shù),注入RedisTemplate對(duì)象
    public RedisService(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    // 設(shè)置key-value鍵值對(duì)
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    // 根據(jù)key獲取value
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    // 根據(jù)key刪除鍵值對(duì)
    public void delete(String key) {
        redisTemplate.delete(key);
    }

    // 判斷key是否存在
    public boolean exists(String key) {
        return redisTemplate.hasKey(key);
    }

    // 將key對(duì)應(yīng)的value增加delta
    public long increment(String key, long delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }

    // 獲取hash結(jié)構(gòu)中所有鍵值對(duì)
    public Map<Object, Object> hashGetAll(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    // 向hash結(jié)構(gòu)中添加鍵值對(duì)
    public void hashPut(String key, Object hashKey, Object value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }

    // 根據(jù)hash結(jié)構(gòu)中的key獲取對(duì)應(yīng)的value
    public Object hashGet(String key, Object hashKey) {
        return redisTemplate.opsForHash().get(key, hashKey);
    }

    // 根據(jù)hash結(jié)構(gòu)中的key刪除對(duì)應(yīng)的hashKey
    public void hashDelete(String key, Object... hashKeys) {
        redisTemplate.opsForHash().delete(key, hashKeys);
    }

    // 判斷hash結(jié)構(gòu)中是否存在hashKey
    public boolean hashExists(String key, Object hashKey) {
        return redisTemplate.opsForHash().hasKey(key, hashKey);
    }

    // 獲取set結(jié)構(gòu)中所有元素
    public Set<Object> setGetAll(String key) {
        return redisTemplate.opsForSet().members(key);
    }

    // 向set結(jié)構(gòu)中添加元素
    public void setAdd(String key, Object... values) {
        redisTemplate.opsForSet().add(key, values);
    }

    // 判斷set結(jié)構(gòu)中是否存在某個(gè)元素
    public boolean setExists(String key, Object value) {
        return redisTemplate.opsForSet().isMember(key, value);
    }

    // 根據(jù)value刪除set結(jié)構(gòu)中的元素
    public void setDelete(String key, Object... values) {
        redisTemplate.opsForSet().remove(key, values);
    }

    // 獲取list結(jié)構(gòu)中所有元素
    public List<Object> listGetAll(String key) {
        return redisTemplate.opsForList().range(key, 0, -1);
    }

    // 向list結(jié)構(gòu)中左側(cè)插入元素
    public void listPush(String key, Object value) {
        redisTemplate.opsForList().leftPush(key, value);
    }

    // 從list結(jié)構(gòu)中左側(cè)彈出元素
    public Object listPop(String key) {
        return redisTemplate.opsForList().leftPop(key);
    }

    // 獲取list結(jié)構(gòu)中元素的數(shù)量
    public long listSize(String key) {
        return redisTemplate.opsForList().size(key);
    }
}

2. 源碼淺析

2.1. 構(gòu)造方法

RedisTemplate的構(gòu)造方法需要一個(gè)RedisConnectionFactory對(duì)象作為參數(shù),它通過(guò)這個(gè)對(duì)象來(lái)獲取Redis連接。RedisConnectionFactory 是 Spring Data Redis 提供的一個(gè)接口,用于創(chuàng)建和管理 Redis 連接。它是將 Redis 連接池(連接 Redis 數(shù)據(jù)庫(kù)的客戶(hù)端)與 Spring 應(yīng)用程序集成的關(guān)鍵。

public RedisTemplate() {
    RedisConnectionFactory redisConnectionFactory = RedisConnectionConfiguration.determineConnectionFactory(redisSentinelConfiguration, redisClusterConfiguration, connectionFactory, jedisConnectionFactory);
    setConnectionFactory(redisConnectionFactory);
    afterPropertiesSet();
}

2.2. 序列化方式

RedisTemplate支持各種數(shù)據(jù)類(lèi)型的序列化和反序列化,它提供了以下四種序列化方式:

  • keySerializer:key的序列化方式。
  • valueSerializer:value的序列化方式。
  • hashKeySerializer:hash key的序列化方式。
  • hashValueSerializer:hash value的序列化方式。

RedisTemplate默認(rèn)使用JdkSerializationRedisSerializer作為序列化方式,但是在實(shí)際使用中,通常需要根據(jù)實(shí)際情況選擇更加高效的序列化方式,如StringRedisSerializer、Jackson2JsonRedisSerializer等。

public void setKeySerializer(RedisSerializer<?> keySerializer) {
    Assert.notNull(keySerializer, "RedisSerializer must not be null!");
    this.keySerializer = keySerializer;
}

public void setValueSerializer(RedisSerializer<?> valueSerializer) {
    Assert.notNull(valueSerializer, "RedisSerializer must not be null!");
    this.valueSerializer = valueSerializer;
}

public void setHashKeySerializer(RedisSerializer<?> hashKeySerializer) {
    Assert.notNull(hashKeySerializer, "RedisSerializer must not be null!");
    this.hashKeySerializer = hashKeySerializer;
}

public void setHashValueSerializer(RedisSerializer<?> hashValueSerializer) {
    Assert.notNull(hashValueSerializer, "RedisSerializer must not be null!");
    this.hashValueSerializer = hashValueSerializer;
}

2.3. RedisTemplate的操作方法

RedisTemplate提供了各種操作方法,如opsForValue()、opsForList()、opsForSet()、opsForZSet()、opsForHash()等,它們返回的是具體數(shù)據(jù)結(jié)構(gòu)的操作對(duì)象,如ValueOperations、ListOperations、SetOperations、ZSetOperations、HashOperations等。這些操作對(duì)象提供了各種操作方法,如get()、set()、push()、pop()、add()、remove()、score()、range()、increment()等,它們對(duì)應(yīng)了Redis的各種操作。

public ValueOperations<K, V> opsForValue() {
    if (valueOps == null) {
        valueOps = new DefaultValueOperations<>(this);
    }
    return valueOps;
}

public ListOperations<K, V> opsForList() {
    if (listOps == null) {
        listOps = new DefaultListOperations<>(this);
    }
    return listOps;
}

public SetOperations<K, V> opsForSet() {
    if (setOps == null) {
        setOps = new DefaultSetOperations<>(this);
    }
    return setOps;
}

public ZSetOperations<K, V> opsForZSet() {
    if (zSetOps == null) {
        zSetOps = new DefaultZSetOperations<>(this);
    }
    return zSetOps;
}

public HashOperations<K, HK, HV> opsForHash() {
    if (hashOps == null) {
        hashOps = new DefaultHashOperations<>(this);
    }
    return hashOps;
}

2.4. RedisTemplate的事務(wù)

RedisTemplate支持事務(wù),它提供了multi()、exec()和discard()三個(gè)方法來(lái)實(shí)現(xiàn)事務(wù)。multi()方法用于開(kāi)啟事務(wù),exec()方法用于提交事務(wù),discard()方法用于回滾事務(wù)。

public void multi() {
    RedisConnectionUtils.bindConnection(getRequiredConnectionFactory(), true);
    try {
        RedisConnectionUtils.getRequiredConnection(getConnectionFactory()).multi();
    } catch (RuntimeException ex) {
        RedisConnectionUtils.unbindConnection(getRequiredConnectionFactory());
        throw ex;
    }
}

public List<Object> exec() {
    RedisConnectionUtils.unbindConnectionIfPossible(getConnectionFactory());
    return execute((RedisCallback<List<Object>>) connection -> {
        List<Object> results = connection.exec();
        return results != null ? results : Collections.emptyList();
    }, true);
}

public void discard() {
    RedisConnectionUtils.unbindConnectionIfPossible(getConnectionFactory());
    execute(RedisConnectionUtils::discard, true);
}

2.5. RedisTemplate的執(zhí)行方法

RedisTemplate提供了execute()方法來(lái)執(zhí)行Redis操作,它需要傳入一個(gè)RedisCallback對(duì)象作為參數(shù),RedisCallback是一個(gè)函數(shù)式接口,它定義了一個(gè)回調(diào)函數(shù),用于執(zhí)行具體的Redis操作。execute()方法會(huì)獲取一個(gè)Redis連接,執(zhí)行RedisCallback對(duì)象的回調(diào)函數(shù),并返回回調(diào)函數(shù)的結(jié)果。

public <T> T execute(RedisCallback<T> action, boolean exposeConnection) {
    Assert.notNull(action, "Callback object must not be null");

    RedisConnection conn = null;
    try {
        conn = getConnection(exposeConnection);
        boolean existingConnection = TransactionSynchronizationManager.hasResource(getConnectionFactory());
        RedisConnection connToUse = preProcessConnection(conn, existingConnection);
        T result = action.doInRedis(connToUse);
        return postProcessResult(result, conn, existingConnection);
    } catch (RuntimeException ex) {
        releaseConnection(conn, existingConnection);
        throw ex;
    } finally {
        if (!exposeConnection) {
            RedisConnectionUtils.releaseConnection(conn, getConnectionFactory(), false);
        }
    }
}

在execute()方法中,首先獲取Redis連接,然后調(diào)用preProcessConnection()方法進(jìn)行預(yù)處理,接著執(zhí)行RedisCallback對(duì)象的回調(diào)函數(shù),最后調(diào)用postProcessResult()方法進(jìn)行后處理,并返回結(jié)果。如果執(zhí)行過(guò)程中發(fā)生異常,會(huì)調(diào)用releaseConnection()方法釋放Redis連接。

2.6. RedisTemplate的回調(diào)方法

RedisTemplate的回調(diào)方法主要有以下三個(gè):

這里有三個(gè)方法:

  1. execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline):執(zhí)行Redis操作的核心方法。接受一個(gè)RedisCallback對(duì)象,該對(duì)象封裝了要在Redis上執(zhí)行的操作。還有兩個(gè)布爾類(lèi)型的參數(shù),一個(gè)表示是否暴露連接(exposeConnection),另一個(gè)表示是否啟用pipeline(pipeline)。如果啟用pipeline,將使用Redis連接對(duì)象的openPipeline()和closePipeline()方法執(zhí)行操作。

  2. execute(SessionCallback<T> session):執(zhí)行Redis事務(wù)的方法。接受一個(gè)SessionCallback對(duì)象,該對(duì)象封裝了在 Redis 事務(wù)中執(zhí)行的操作。該方法會(huì)綁定 Redis 連接并執(zhí)行 SessionCallback 對(duì)象的 execute() 方法,最后解除綁定。

  3. executePipelined(SessionCallback<?> session, @Nullable RedisSerializer<?> resultSerializer):執(zhí)行 Redis pipeline 的方法。接受一個(gè)SessionCallback對(duì)象,該對(duì)象封裝了要在 Redis pipeline 中執(zhí)行的操作,以及一個(gè)可選的 RedisSerializer 對(duì)象,用于反序列化結(jié)果。該方法會(huì)綁定 Redis 連接并執(zhí)行 SessionCallback 對(duì)象的 execute() 方法,在執(zhí)行期間使用 Redis 連接對(duì)象的 openPipeline() 和 closePipeline() 方法開(kāi)啟和關(guān)閉 Redis pipeline。

常用場(chǎng)景:第一個(gè)方法執(zhí)行單個(gè)Redis操作,第二個(gè)方法執(zhí)行Redis事務(wù),第三個(gè)方法執(zhí)行Redis
pipeline。此外,第二個(gè)方法是為了執(zhí)行多個(gè) Redis 操作而設(shè)計(jì)的,而第一個(gè)方法和第三個(gè)方法只執(zhí)行單個(gè) Redis 操作。第三個(gè)方法需要額外的參數(shù),用于反序列化 Redis pipeline 的結(jié)果。


    @Nullable
    public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
        Assert.isTrue(this.initialized, "template not initialized; call afterPropertiesSet() before using it");
        Assert.notNull(action, "Callback object must not be null");
        RedisConnectionFactory factory = this.getRequiredConnectionFactory();
        RedisConnection conn = RedisConnectionUtils.getConnection(factory, this.enableTransactionSupport);

        Object var11;
        try {
            boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);
            RedisConnection connToUse = this.preProcessConnection(conn, existingConnection);
            boolean pipelineStatus = connToUse.isPipelined();
            if (pipeline && !pipelineStatus) {
                connToUse.openPipeline();
            }

            RedisConnection connToExpose = exposeConnection ? connToUse : this.createRedisConnectionProxy(connToUse);
            T result = action.doInRedis(connToExpose);
            if (pipeline && !pipelineStatus) {
                connToUse.closePipeline();
            }

            var11 = this.postProcessResult(result, connToUse, existingConnection);
        } finally {
            RedisConnectionUtils.releaseConnection(conn, factory, this.enableTransactionSupport);
        }

        return var11;
    }

    public <T> T execute(SessionCallback<T> session) {
        Assert.isTrue(this.initialized, "template not initialized; call afterPropertiesSet() before using it");
        Assert.notNull(session, "Callback object must not be null");
        RedisConnectionFactory factory = this.getRequiredConnectionFactory();
        RedisConnectionUtils.bindConnection(factory, this.enableTransactionSupport);

        Object var3;
        try {
            var3 = session.execute(this);
        } finally {
            RedisConnectionUtils.unbindConnection(factory);
        }

        return var3;
    }

    public List<Object> executePipelined(SessionCallback<?> session) {
        return this.executePipelined(session, this.valueSerializer);
    }

    public List<Object> executePipelined(SessionCallback<?> session, @Nullable RedisSerializer<?> resultSerializer) {
        Assert.isTrue(this.initialized, "template not initialized; call afterPropertiesSet() before using it");
        Assert.notNull(session, "Callback object must not be null");
        RedisConnectionFactory factory = this.getRequiredConnectionFactory();
        RedisConnectionUtils.bindConnection(factory, this.enableTransactionSupport);

        List var4;
        try {
            var4 = (List)this.execute((connection) -> {
                connection.openPipeline();
                boolean pipelinedClosed = false;

                List var7;
                try {
                    Object result = this.executeSession(session);
                    if (result != null) {
                        throw new InvalidDataAccessApiUsageException("Callback cannot return a non-null value as it gets overwritten by the pipeline");
                    }

                    List<Object> closePipeline = connection.closePipeline();
                    pipelinedClosed = true;
                    var7 = this.deserializeMixedResults(closePipeline, resultSerializer, this.hashKeySerializer, this.hashValueSerializer);
                } finally {
                    if (!pipelinedClosed) {
                        connection.closePipeline();
                    }

                }

                return var7;
            });
        } finally {
            RedisConnectionUtils.unbindConnection(factory);
        }

        return var4;
    }

代碼示例

  1. 使用 execute(RedisCallback<T> action) 執(zhí)行 Redis 命令
 
// 使用 execute() 方法執(zhí)行 Redis 命令
String key = "myKey";
String value = redisTemplate.execute((RedisCallback<String>) connection -> {
    connection.set(redisTemplate.getStringSerializer().serialize(key), redisTemplate.getStringSerializer().serialize("Hello"));
    return redisTemplate.getStringSerializer().deserialize(connection.get(redisTemplate.getStringSerializer().serialize(key)));
});

// 輸出 Redis 命令執(zhí)行結(jié)果
System.out.println(value); // 輸出 "Hello"

在上面的示例中, 我們使用 execute(RedisCallback<T> action) 方法將 Redis 命令封裝在一個(gè) RedisCallback 對(duì)象中,并將其傳遞給 execute() 方法。該命令使用 set() 方法將一個(gè) key-value 對(duì)寫(xiě)入 Redis 中,然后使用 get() 方法從 Redis 中讀取該 key 對(duì)應(yīng)的值。

  1. 使用 execute(SessionCallback<T> session) 執(zhí)行 Redis 事務(wù)
// 使用 execute(SessionCallback<T> session) 方法執(zhí)行 Redis 事務(wù)
String key1 = "myKey1";
String key2 = "myKey2";
String value1 = "myValue1";
String value2 = "myValue2";
List<Object> results = redisTemplate.execute((SessionCallback<List<Object>>) session -> {
    session.multi();
    session.opsForValue().set(key1, value1);
    session.opsForValue().set(key2, value2);
    return session.exec();
});

// 輸出 Redis 事務(wù)的結(jié)果
System.out.println(results); // 輸出 "[true, true]"

使用 execute(SessionCallback<T> session) 方法將 Redis 事務(wù)封裝在一個(gè) SessionCallback<T> 對(duì)象中,并將其傳遞給 execute() 方法。該事務(wù)使用 multi() 方法開(kāi)啟事務(wù),在事務(wù)中使用 opsForValue() 對(duì)象的 set() 方法將兩個(gè) key-value 對(duì)寫(xiě)入 Redis 中,最后使用 exec() 方法提交事務(wù)。事務(wù)執(zhí)行完成后,我們可以通過(guò) execute() 方法返回的結(jié)果列表查看每個(gè) Redis 命令的執(zhí)行結(jié)果。在上面的示例中,我們可以看到結(jié)果列表為 [true, true],表示兩個(gè) Redis 命令都成功執(zhí)行。

  1. 使用 executePipelined(SessionCallback<?> session) 執(zhí)行 Redis pipeline
 

// 使用 executePipelined(SessionCallback<?> session) 方法執(zhí)行 Redis pipeline
String key1 = "myKey1";
String key2 = "myKey2";
List<Object> results = redisTemplate.executePipelined((SessionCallback<List<Object>>) session -> {
    session.opsForValue().get(key1);
    session.opsForValue().get(key2);
    return null;
});

// 輸出 Redis pipeline 的結(jié)果
System.out.println(results); // 輸出 "[Hello1, Hello2]"

使用 executePipelined(SessionCallback<?> session) 方法將 Redis pipeline 封裝在一個(gè) SessionCallback<?> 對(duì)象中,并將其傳遞給 executePipelined() 方法。該 pipeline 使用 opsForValue() 對(duì)象的 get() 方法獲取兩個(gè) key 的值,并返回一個(gè)結(jié)果列表。在執(zhí)行期間,該方法將使用 Redis 連接對(duì)象的 openPipeline()closePipeline() 方法開(kāi)啟和關(guān)閉 Redis pipeline,以便可以批量執(zhí)行多個(gè)命令。

3.總結(jié)

看完這些基本上行只是學(xué)會(huì)了增刪查看和批量操作。也就是只學(xué)會(huì)了RedisTemplate 的皮毛。其實(shí)在項(xiàng)目中還有更多的復(fù)雜需求,需要重新實(shí)現(xiàn)。

比如以下這些問(wèn)題,也是很常見(jiàn)的,需要我們處理實(shí)際的問(wèn)題。我大概做一個(gè)簡(jiǎn)答,后面將詳細(xì)輸出示例

3.1. 項(xiàng)目中如何使用 RedisTemplate 支持多個(gè) Redis 數(shù)據(jù)庫(kù)?

可以通過(guò)配置 RedisConnectionFactory 來(lái)支持多個(gè) Redis 數(shù)據(jù)庫(kù),其中可以使用 JedisConnectionFactory 或 LettuceConnectionFactory 來(lái)創(chuàng)建不同的 RedisConnectionFactory 實(shí)例。詳細(xì)教程可以參考我的其他博客《SpringBoot 項(xiàng)目配置多數(shù)據(jù)源》

3.2. 如何使用 RedisTemplate 支持 Redis 集群?

可以使用 RedisTemplate 的 ClusterRedisConnectionFactory 來(lái)支持 Redis 集群,通過(guò)配置 Redis 集群中的多個(gè)節(jié)點(diǎn)來(lái)實(shí)現(xiàn)高可用性和負(fù)載均衡。詳細(xì)教程參考我的其他博客《SpringBoot 項(xiàng)目配置 Redis 集群》

3.3. 如何使用 RedisTemplate 實(shí)現(xiàn) Redis 事務(wù)的樂(lè)觀鎖?

可以使用 RedisTemplate 的 watch() 方法和 multi() 方法來(lái)實(shí)現(xiàn) Redis 事務(wù)的樂(lè)觀鎖,通過(guò)在事務(wù)開(kāi)始前使用 watch() 方法監(jiān)視 Redis 中的某個(gè) key,然后在事務(wù)中使用 multi() 方法執(zhí)行多個(gè) Redis 命令,并使用 exec() 方法提交事務(wù),如果在事務(wù)執(zhí)行期間,被監(jiān)視的 key 被修改,則事務(wù)會(huì)失敗,從而實(shí)現(xiàn)樂(lè)觀鎖。
詳細(xì)教程可以參考我的其他博客《SpringBoot 項(xiàng)目配置 Redis 集群》

3.4. 如何使用 RedisTemplate 實(shí)現(xiàn) Redis 的分布式鎖重入?

可以使用 RedisTemplate 的 ThreadLocal 方式來(lái)實(shí)現(xiàn) Redis 的分布式鎖重入,即在每個(gè)線程中保存一個(gè) Redis 分布式鎖的狀態(tài),并在需要重入時(shí),檢查當(dāng)前線程是否已經(jīng)獲取了分布式鎖。

3.5. 如何使用 RedisTemplate 實(shí)現(xiàn) Redis 的分布式事務(wù)?

可以使用 RedisTemplate 的 execute(SessionCallback session) 方法來(lái)實(shí)現(xiàn) Redis 的分布式事務(wù),其中 SessionCallback 接口可以用來(lái)執(zhí)行多個(gè) Redis 命令,并保證這些命令以原子方式執(zhí)行。

3.6. 如何使用 RedisTemplate 實(shí)現(xiàn) Redis 的分布式限速?

可以使用 RedisTemplate 的 incr() 方法和 expire() 方法來(lái)實(shí)現(xiàn) Redis 的分布式限速,通過(guò)在 Redis 中設(shè)置一個(gè)計(jì)數(shù)器和過(guò)期時(shí)間來(lái)實(shí)現(xiàn)分布式限速。

3.7. 如何使用 RedisTemplate 實(shí)現(xiàn) Redis 的分布式鎖可重入性?

可以使用 RedisTemplate 的 ReentrantRedisLock 類(lèi)來(lái)實(shí)現(xiàn) Redis 的分布式鎖可重入性,該類(lèi)可以在 Redis 中保存一個(gè)計(jì)數(shù)器來(lái)記錄鎖的重入次數(shù),并在釋放鎖時(shí),檢查當(dāng)前線程是否已經(jīng)完全釋放了鎖,從而實(shí)現(xiàn)分布式鎖的可重入性。

3.8. 如何使用 RedisTemplate 實(shí)現(xiàn) Redis 的分布式信號(hào)量?

可以使用 RedisTemplate 的 RedisSemaphore 類(lèi)來(lái)實(shí)現(xiàn) Redis 的分布式信號(hào)量,該類(lèi)可以在 Redis 中保存一個(gè)計(jì)數(shù)器來(lái)記錄當(dāng)前已經(jīng)獲得信號(hào)量的數(shù)量,并在釋放信號(hào)量時(shí),將計(jì)數(shù)器減一。

3.9. 如何使用 RedisTemplate 實(shí)現(xiàn) Redis 的分布式緩存穿透?

可以使用 RedisTemplate 的緩存注解(例如 @Cacheable、@CachePut、@CacheEvict)和布隆過(guò)濾器來(lái)實(shí)現(xiàn) Redis 的分布式緩存穿透,其中布隆過(guò)濾器可以用來(lái)過(guò)濾掉不存在的 key,從而避免緩存穿透的問(wèn)題。

3.10. 如何使用 RedisTemplate 實(shí)現(xiàn) Redis 的分布式緩存擊穿?

可以使用 RedisTemplate 的緩存注解(例如 @Cacheable、@CachePut、@CacheEvict)和 Redis 分布式鎖來(lái)實(shí)現(xiàn) Redis 的分布式緩存擊穿,其中 Redis 分布式鎖可以用來(lái)防止緩存擊穿,即在緩存不存在的情況下,使用 Redis 分布式鎖來(lái)避免多個(gè)線程同時(shí)訪問(wèn)數(shù)據(jù)庫(kù)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-602371.html

4. Redis從入門(mén)到精通系列文章

  • 《Redis【應(yīng)用篇】之RedisTemplate基本操作》
  • 《Redis 從入門(mén)到精通【實(shí)踐篇】之SpringBoot配置Redis多數(shù)據(jù)源》
  • 《Redis 從入門(mén)到精通【進(jìn)階篇】之三分鐘了解Redis HyperLogLog 數(shù)據(jù)結(jié)構(gòu)》
  • 《Redis 從入門(mén)到精通【進(jìn)階篇】之三分鐘了解Redis地理位置數(shù)據(jù)結(jié)構(gòu)GeoHash》
  • 《Redis 從入門(mén)到精通【進(jìn)階篇】之高可用哨兵機(jī)制(Redis Sentinel)詳解》
  • 《Redis 從入門(mén)到精通【進(jìn)階篇】之redis主從復(fù)制詳解》
  • 《Redis 從入門(mén)到精通【進(jìn)階篇】之Redis事務(wù)詳解》
  • 《Redis從入門(mén)到精通【進(jìn)階篇】之對(duì)象機(jī)制詳解》
  • 《Redis從入門(mén)到精通【進(jìn)階篇】之消息傳遞發(fā)布訂閱模式詳解》
  • 《Redis從入門(mén)到精通【進(jìn)階篇】之持久化 AOF詳解》
  • 《Redis從入門(mén)到精通【進(jìn)階篇】之持久化RDB詳解》
  • 《Redis從入門(mén)到精通【高階篇】之底層數(shù)據(jù)結(jié)構(gòu)字典(Dictionary)詳解》
  • 《Redis從入門(mén)到精通【高階篇】之底層數(shù)據(jù)結(jié)構(gòu)快表QuickList詳解》
  • 《Redis從入門(mén)到精通【高階篇】之底層數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單動(dòng)態(tài)字符串(SDS)詳解》
  • 《Redis從入門(mén)到精通【高階篇】之底層數(shù)據(jù)結(jié)構(gòu)壓縮列表(ZipList)詳解》
  • 《Redis從入門(mén)到精通【進(jìn)階篇】之?dāng)?shù)據(jù)類(lèi)型Stream詳解和使用示例》
    Redis【實(shí)踐篇】之RedisTemplate基本操作,Redis從入門(mén)到精通2023版,redis,數(shù)據(jù)庫(kù),緩存,java,后端大家好,我是冰點(diǎn),今天的Redis【實(shí)踐篇】之RedisTemplate基本操作詳解,全部?jī)?nèi)容就是這些。如果你有疑問(wèn)或見(jiàn)解可以在評(píng)論區(qū)留言。

到了這里,關(guān)于Redis【實(shí)踐篇】之RedisTemplate基本操作的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【實(shí)踐篇】推薦算法PaaS化探索與實(shí)踐

    作者:京東零售 崔寧 目前,推薦算法部支持了主站、企業(yè)業(yè)務(wù)、全渠道等20+業(yè)務(wù)線的900+推薦場(chǎng)景,通過(guò)梳理大促運(yùn)營(yíng)、各垂直業(yè)務(wù)線推薦場(chǎng)景的共性需求,對(duì)現(xiàn)有推薦算法能力進(jìn)行沉淀和積累,并通過(guò)算法PaaS化打造通用化的推薦能力,提升各業(yè)務(wù)場(chǎng)景推薦賦能效率,高效賦

    2024年02月15日
    瀏覽(29)
  • 【實(shí)踐篇】基于CAS的單點(diǎn)登錄實(shí)踐之路

    作者:京東物流?趙勇萍 上個(gè)月我負(fù)責(zé)的系統(tǒng)SSO升級(jí),對(duì)接京東ERP系統(tǒng),這也讓我想起了之前我做過(guò)一個(gè)單點(diǎn)登錄的項(xiàng)目。想來(lái)單點(diǎn)登錄有很多實(shí)現(xiàn)方案,不過(guò)最主流的還是基于CAS的方案,所以我也就分享一下我的CAS實(shí)踐之路。 單點(diǎn)登錄的英文名叫做:Single Sign On(簡(jiǎn)稱(chēng)SSO)

    2023年04月13日
    瀏覽(20)
  • 「ML 實(shí)踐篇」模型訓(xùn)練

    「ML 實(shí)踐篇」模型訓(xùn)練

    在訓(xùn)練不同機(jī)器學(xué)習(xí)算法模型時(shí),遇到的各類(lèi)訓(xùn)練算法大多對(duì)用戶(hù)都是一個(gè)黑匣子,而理解它們實(shí)際怎么工作,對(duì)用戶(hù)是很有幫助的; 快速定位到合適的模型與正確的訓(xùn)練算法,找到一套適當(dāng)?shù)某瑓?shù)等; 更高效的執(zhí)行錯(cuò)誤調(diào)試、錯(cuò)誤分析等; 有助于理解、構(gòu)建和訓(xùn)練神經(jīng)

    2023年04月16日
    瀏覽(25)
  • 【MySql】11- 實(shí)踐篇(九)

    【MySql】11- 實(shí)踐篇(九)

    主機(jī)內(nèi)存只有 100G,現(xiàn)在要對(duì)一個(gè) 200G 的大表做全表掃描,會(huì)不會(huì)把數(shù)據(jù)庫(kù)主機(jī)的內(nèi)存用光了? 1.1 全表掃描對(duì) server 層的影響 現(xiàn)在要對(duì)一個(gè) 200G 的 InnoDB 表 db1. t,執(zhí)行一個(gè)全表掃描。當(dāng)然,你要把掃描結(jié)果保存在客戶(hù)端,會(huì)使用類(lèi)似這樣的命令: InnoDB 的數(shù)據(jù)是保存在主鍵索

    2024年02月06日
    瀏覽(23)
  • 安卓與串口通信-實(shí)踐篇

    安卓與串口通信-實(shí)踐篇

    在上一篇文章中我們講解了關(guān)于串口的基礎(chǔ)知識(shí),沒(méi)有看過(guò)的同學(xué)推薦先看一下,否則你可能會(huì)不太理解這篇文章所述的某些內(nèi)容。 這篇文章我們將講解安卓端的串口通信實(shí)踐,即如何使用串口通信實(shí)現(xiàn)安卓設(shè)備與其他設(shè)備例如PLC主板之間數(shù)據(jù)交互。 需要注意的是正如上一

    2024年02月16日
    瀏覽(29)
  • 程序員職業(yè)規(guī)劃-實(shí)踐篇

    程序員職業(yè)規(guī)劃-實(shí)踐篇

    你是否認(rèn)真思考過(guò)3-5年、10年: 你想成為什么樣的人 ? 作為一名技術(shù)人,我們應(yīng)認(rèn)真規(guī)劃自己的職業(yè)發(fā)展,不再焦慮、為自己加速~ 一塊留言來(lái)聊聊吧~ 你該去什么樣的公司、做什么樣的事情、拿多少錢(qián),都取決于一個(gè)問(wèn)題: 你想成為什么樣的人 ? 你是否認(rèn)真思考過(guò)3-5年、

    2024年02月05日
    瀏覽(28)
  • 【實(shí)踐篇】推薦算法PaaS化探索與實(shí)踐 | 京東云技術(shù)團(tuán)隊(duì)

    【實(shí)踐篇】推薦算法PaaS化探索與實(shí)踐 | 京東云技術(shù)團(tuán)隊(duì)

    作者:京東零售 崔寧 目前,推薦算法部支持了主站、企業(yè)業(yè)務(wù)、全渠道等20+業(yè)務(wù)線的900+推薦場(chǎng)景,通過(guò)梳理大促運(yùn)營(yíng)、各垂直業(yè)務(wù)線推薦場(chǎng)景的共性需求,對(duì)現(xiàn)有推薦算法能力進(jìn)行沉淀和積累,并通過(guò)算法PaaS化打造通用化的推薦能力,提升各業(yè)務(wù)場(chǎng)景推薦賦能效率,高效賦

    2024年02月15日
    瀏覽(26)
  • 「ML 實(shí)踐篇」分類(lèi)系統(tǒng):圖片數(shù)字識(shí)別

    「ML 實(shí)踐篇」分類(lèi)系統(tǒng):圖片數(shù)字識(shí)別

    目的 :使用 MNIST 數(shù)據(jù)集,建立數(shù)字圖像識(shí)別模型,識(shí)別任意圖像中的數(shù)字; MNIST ,一組由美國(guó)高中生和人口調(diào)查局員工手寫(xiě)的 70000 個(gè)數(shù)字圖片;每張圖片都用其代表的數(shù)字標(biāo)記;因廣泛被應(yīng)用于機(jī)器學(xué)習(xí)入門(mén),被稱(chēng)作機(jī)器學(xué)習(xí)領(lǐng)域的 Hello World ;也可用于測(cè)試新分類(lèi)算法的

    2023年04月08日
    瀏覽(28)
  • 微服務(wù)實(shí)戰(zhàn)系列之ZooKeeper(實(shí)踐篇)

    微服務(wù)實(shí)戰(zhàn)系列之ZooKeeper(實(shí)踐篇)

    關(guān)于 ZooKeeper ,博主已完整的通過(guò)庖丁解牛式的 “解法” ,完成了概述。我想掌握了這些基礎(chǔ)原理和概念后,工作的問(wèn)題自然迎刃而解,甚至offer也可能手到擒來(lái),真實(shí)一舉兩得,美極了。 為了更有直觀的體驗(yàn),強(qiáng)化概念,博主特別獻(xiàn)上一篇實(shí)踐文章。理論聯(lián)系實(shí)踐,才能學(xué)

    2024年01月21日
    瀏覽(32)
  • 【實(shí)踐篇】領(lǐng)域驅(qū)動(dòng)設(shè)計(jì):DDD工程參考架構(gòu)

    不同團(tuán)隊(duì)落地DDD所采取的應(yīng)用架構(gòu)風(fēng)格可能不同,并沒(méi)有統(tǒng)一的、標(biāo)準(zhǔn)的DDD工程架構(gòu)。有些團(tuán)隊(duì)可能遵循經(jīng)典的DDD四層架構(gòu),或改進(jìn)的DDD四層架構(gòu),有些團(tuán)隊(duì)可能綜合考慮分層架構(gòu)、整潔架構(gòu)、六邊形架構(gòu)等多種架構(gòu)風(fēng)格,有些在實(shí)踐中可能引入CQRS解決讀模型與寫(xiě)模型的差異

    2024年02月05日
    瀏覽(26)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包