SpringBoot 中使用Redis緩存

作者:xcbeyond
瘋狂源自夢(mèng)想,技術(shù)成就輝煌!微信公眾號(hào):《程序猿技術(shù)大咖》號(hào)主,專(zhuān)注后端開(kāi)發(fā)多年,擁有豐富的研發(fā)經(jīng)驗(yàn),樂(lè)于技術(shù)輸出、分享,現(xiàn)階段從事微服務(wù)架構(gòu)項(xiàng)目的研發(fā)工作,涉及架構(gòu)設(shè)計(jì)、技術(shù)選型、業(yè)務(wù)研發(fā)等工作。對(duì)于Java、微服務(wù)、數(shù)據(jù)庫(kù)、Docker有深入了解,并有大量的調(diào)優(yōu)經(jīng)驗(yàn)。

 在項(xiàng)目中對(duì)數(shù)據(jù)的訪問(wèn)往往都是直接訪問(wèn)數(shù)據(jù)庫(kù)的方式,但如果對(duì)數(shù)據(jù)的訪問(wèn)量很大或者訪問(wèn)很頻繁的話,將會(huì)對(duì)數(shù)據(jù)庫(kù)來(lái)很大的壓力,甚至造成數(shù)據(jù)庫(kù)崩潰。為了解決這類(lèi)問(wèn)題redis數(shù)據(jù)庫(kù)脫穎而出,redis數(shù)據(jù)庫(kù)出現(xiàn)時(shí)是以非關(guān)系數(shù)據(jù)庫(kù)的光環(huán)展示在廣大程序猿的面前的,后來(lái)redis的迭代版本支持了緩存數(shù)據(jù)、登錄session狀態(tài)(分布式session共享)等。所以又被作為內(nèi)存緩存的形式應(yīng)用到大型企業(yè)級(jí)項(xiàng)目中。

        本章節(jié)主要講述如何在SpringBoot項(xiàng)目中使用Redis。

1、Redis簡(jiǎn)單介紹
Redis 是完全開(kāi)源免費(fèi)的,遵守BSD協(xié)議,是一個(gè)高性能的key-value非關(guān)系性數(shù)據(jù)庫(kù)(NoSql)。
Redis 與其他 key - value 緩存產(chǎn)品有以下三個(gè)特點(diǎn):

Redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤(pán)中,重啟的時(shí)候可以再次加載進(jìn)行使用。
Redis不僅僅支持簡(jiǎn)單的key-value類(lèi)型的數(shù)據(jù),同時(shí)還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。
Redis支持?jǐn)?shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份。
1.1 數(shù)據(jù)結(jié)構(gòu)介紹
        Redis可以存儲(chǔ)鍵與5種不同數(shù)據(jù)結(jié)構(gòu)類(lèi)型之間的映射,這5種數(shù)據(jù)結(jié)構(gòu)類(lèi)型分別為String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。
 

 

2.2 Redis 優(yōu)勢(shì)
性能極高 – Redis能讀的速度是110000次/s,寫(xiě)的速度是81000次/s 。
豐富的數(shù)據(jù)類(lèi)型 – Redis支持二進(jìn)制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數(shù)據(jù)類(lèi)型操作。
原子 – Redis的所有操作都是原子性的,意思就是要么成功執(zhí)行要么失敗完全不執(zhí)行。單個(gè)操作是原子性的。多個(gè)操作也支持事務(wù),即原子性,通過(guò)MULTI和EXEC指令包起來(lái)。
豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過(guò)期等等特性。
2.3 Redis與其他key-value存儲(chǔ)有什么不同?
Redis有著更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)并且提供對(duì)他們的原子性操作,這是一個(gè)不同于其他數(shù)據(jù)庫(kù)的進(jìn)化路徑。Redis的數(shù)據(jù)類(lèi)型都是基于基本數(shù)據(jù)結(jié)構(gòu)的同時(shí)對(duì)程序員透明,無(wú)需進(jìn)行額外的抽象。
Redis運(yùn)行在內(nèi)存中但是可以持久化到磁盤(pán),所以在對(duì)不同數(shù)據(jù)集進(jìn)行高速讀寫(xiě)時(shí)需要權(quán)衡內(nèi)存,因?yàn)閿?shù)據(jù)量不能大于硬件內(nèi)存。在內(nèi)存數(shù)據(jù)庫(kù)方面的另一個(gè)優(yōu)點(diǎn)是,相比在磁盤(pán)上相同的復(fù)雜的數(shù)據(jù)結(jié)構(gòu),在內(nèi)存中操作起來(lái)非常簡(jiǎn)單,這樣Redis可以做很多內(nèi)部復(fù)雜性很強(qiáng)的事情。同時(shí),在磁盤(pán)格式方面他們是緊湊的以追加的方式產(chǎn)生的,因?yàn)樗麄儾⒉恍枰M(jìn)行隨機(jī)訪問(wèn)。
2、安裝Redis
       根據(jù)不同的需求下載Linux或Windows版本的,目前Redis官網(wǎng)只有Linux版本,但由于大多數(shù)開(kāi)發(fā)者還是基于windows平臺(tái)開(kāi)發(fā)的,所有GitHub上的技術(shù)牛人基于linux平臺(tái)下的Redis實(shí)現(xiàn)了windows版本,給windows開(kāi)發(fā)帶來(lái)了福音。

2.1 下載Windows版本Redis
      直接訪問(wèn)github網(wǎng)址:https://github.com/MSOpenTech/redis/releases,下載最新的windows X64版本的壓縮包,如下圖所示:
 

 下載第二個(gè).zip,免安裝,解壓就直接可以用,解壓后如下圖:

2.2 啟動(dòng)Redis
redis.windows.conf為redis配置文件,相關(guān)參數(shù)可以在這里配置,如:端口等,我這里使用默認(rèn)參數(shù),暫不修改,默認(rèn)端口為6379。雙擊redis-server.exe啟動(dòng),則出現(xiàn)如下圖所示,則啟動(dòng)成功。

3、SpringBoot中使用Redis
以之前構(gòu)建的項(xiàng)目為基準(zhǔn),使用Redis.

3.1 添加Redis依賴包
在項(xiàng)目的pom.xml中添加如下:

<!-- redis依賴包 -->
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.2 配置Redis數(shù)據(jù)庫(kù)連接
在application.properties中配置redis數(shù)據(jù)庫(kù)連接信息,如下:

#redis配置
#Redis服務(wù)器地址
spring.redis.host=127.0.0.1
#Redis服務(wù)器連接端口
spring.redis.port=6379
#Redis數(shù)據(jù)庫(kù)索引(默認(rèn)為0)
spring.redis.database=0  
#連接池最大連接數(shù)(使用負(fù)值表示沒(méi)有限制)
spring.redis.jedis.pool.max-active=50
#連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒(méi)有限制)
spring.redis.jedis.pool.max-wait=3000
#連接池中的最大空閑連接
spring.redis.jedis.pool.max-idle=20
#連接池中的最小空閑連接
spring.redis.jedis.pool.min-idle=2
#連接超時(shí)時(shí)間(毫秒)
spring.redis.timeout=5000
3.3 編寫(xiě)Redis操作工具類(lèi)
        將RedisTemplate實(shí)例包裝成一個(gè)工具類(lèi),便于對(duì)redis進(jìn)行數(shù)據(jù)操作。






com.xcbeyond.springboot.redis.RedisUtils.java

package com.xcbeyond.springboot.redis;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
 
/**
 * redis操作工具類(lèi).</br>
 * (基于RedisTemplate)
 * @author xcbeyond
 * 2018年7月19日下午2:56:24
 */
@Component
public class RedisUtils {
 
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
 
    /**
     * 讀取緩存
     * 
     * @param key
     * @return
     */
    public String get(final String key) {
        return redisTemplate.opsForValue().get(key);
    }
 
    /**
     * 寫(xiě)入緩存
     */
    public boolean set(final String key, String value) {
        boolean result = false;
        try {
            redisTemplate.opsForValue().set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
 
    /**
     * 更新緩存
     */
    public boolean getAndSet(final String key, String value) {
        boolean result = false;
        try {
            redisTemplate.opsForValue().getAndSet(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
 
    /**
     * 刪除緩存
     */
    public boolean delete(final String key) {
        boolean result = false;
        try {
            redisTemplate.delete(key);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}
3.4 測(cè)試
寫(xiě)一個(gè)測(cè)試用例類(lèi)來(lái)完成對(duì)redis的讀寫(xiě)。

/springboot/src/test/java/com/xcbeyond/springboot/redis/RedisTest.java

package com.xcbeyond.springboot.redis;
 
import javax.annotation.Resource;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
 * 
 * @author xcbeyond
 * 2018年7月19日下午3:08:04
 */
 
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class RedisTest {
    @Resource
    private RedisUtils redisUtils;
 
    /**
     * 插入緩存數(shù)據(jù)
     */
    @Test
    public void set() {
        redisUtils.set("redis_key", "redis_vale");
    }
    
    /**
     * 讀取緩存數(shù)據(jù)
     */
    @Test
    public void get() {
        String value = redisUtils.get("redis_key");
        System.out.println(value);
    }
 
}
執(zhí)行完測(cè)試方法set后,可以登錄到redis上查看數(shù)據(jù)是否插入成功。

(建議使用RedisDesktopManager可視化工具進(jìn)行查看)
 

4、總結(jié)
         本章節(jié)只是簡(jiǎn)單的介紹了下在SpringBoot中如何使用Redis,Redis的使用遠(yuǎn)遠(yuǎn)不止這些,根據(jù)實(shí)際項(xiàng)目需求將會(huì)變得更加復(fù)雜,其中事物等都是可以通過(guò)redis來(lái)處理的。

本章節(jié)代碼已提交至Github(https://github.com/xcbeyond/micro-service/tree/master/springboot),如有需要自行下載。