SpringBoot+Redis

       在項目中對數據的訪問往往都是直接訪問數據庫的方式,但如果對數據的訪問量很大或者訪問很頻繁的話,將會對數據庫來很大的壓力,甚至造成數據庫崩潰。爲了解決這類問題redis數據庫脫穎而出,redis數據庫出現時是以非關係數據庫的光環展示在廣大程序猿的面前的,後來redis的迭代版本支持了緩存數據、登錄session狀態(分佈式session共享)等。所以又被作爲內存緩存的形式應用到大型企業級項目中。

1、Redis簡單介紹

Redis 是完全開源免費的,遵守BSD協議,是一個高性能的key-value非關係性數據庫(NoSql)。
Redis 與其他 key - value 緩存產品有以下三個特點:

  1. Redis支持數據的持久化,可以將內存中的數據保存在磁盤中,重啓的時候可以再次加載進行使用。
  2. Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
  3. Redis支持數據的備份,即master-slave模式的數據備份。

1.1 數據結構介紹

        Redis可以存儲鍵與5種不同數據結構類型之間的映射,這5種數據結構類型分別爲String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。

結構類型 結構存儲的值 讀寫能力
String 可以是字符串、整數或者浮點數 對整個字符串或者字符串的其中一部分執行操作;對象和浮點數執行自增(increment)或者自減(decrement) 
List 一個鏈表,鏈表上的每個節點都包含了一個字符串 從鏈表的兩端推入或者彈出元素;根據偏移量對鏈表進行修剪(trim);讀取單個或者多個元素;根據值來查找或者移除元素 
Set 包含字符串的無序收集器(unorderedcollection),並且被包含的每個字符串都是獨一無二的、各不相同  添加、獲取、移除單個元素;檢查一個元素是否存在於某個集合中;計算交集、並集、差集;從集合裏賣弄隨機獲取元素 
Hash 包含鍵值對的無序散列表 添加、獲取、移除單個鍵值對;獲取所有鍵值對 
Zset 字符串成員(member)與浮點數分值(score)之間的有序映射,元素的排列順序由分值的大小決定 添加、獲取、刪除單個元素;根據分值範圍(range)或者成員來獲取元素 

1.2 Redis 優勢

1.3 Redis與其他key-value存儲有什麼不同?

        Redis有着更爲複雜的數據結構並且提供對他們的原子性操作,這是一個不同於其他數據庫的進化路徑。Redis的數據類型都是基於基本數據結構的同時對程序員透明,無需進行額外的抽象。
        Redis運行在內存中但是可以持久化到磁盤,所以在對不同數據集進行高速讀寫時需要權衡內存,因爲數據量不能大於硬件內存。在內存數據庫方面的另一個優點是,相比在磁盤上相同的複雜的數據結構,在內存中操作起來非常簡單,這樣Redis可以做很多內部複雜性很強的事情。同時,在磁盤格式方面他們是緊湊的以追加的方式產生的,因爲他們並不需要進行隨機訪問。

2、安裝Redis

        根據不同的需求下載對應版本,這裏以 mac 版本安裝配置爲例。

 

  • 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  • 豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。
  • 原子 – Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支持事務,即原子性,通過MULTI和EXEC指令包起來。
  • 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性。
     

使用Homebrew安裝redis可以減少大量的安裝和配置的工作量。 
安裝命令

brew install redis

安裝完成後的提示信息

To have launchd start redis at login: 
ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgents 
Then to load redis now: 
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.redis.plist 
Or, if you don’t want/need launchctl, you can just run: 
redis-server /usr/local/etc/redis.conf

開機啓動redis命令

$ ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgents

使用launchctl啓動redis server

$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.redis.plist

使用配置文件啓動redis server

$ redis-server /usr/local/etc/redis.conf

停止redis server的自啓動

$ launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.redis.plist

redis 配置文件的位置

/usr/local/etc/redis.conf

卸載redis和它的文件

$ brew uninstall redis

$ rm ~/Library/LaunchAgents/homebrew.mxcl.redis.plist

測試redis server是否啓動

$ redis-cli ping

 3、SpringBoot中使用Redis

3.1 pom.xml 引入redis 開啓緩存

      <!--  cache -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <!--  redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

3.2 application.properties 配置文件

# Redis數據庫索引(默認爲0)
spring.redis.database=0
# Redis服務器地址
spring.redis.host=localhost
# Redis服務器連接端口
spring.redis.port=6379
# Redis服務器連接密碼(默認爲空)
spring.redis.password=
# 連接池最大連接數(使用負值表示沒有限制)
spring.redis.pool.max-active=8
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
# 連接池中的最大空閒連接
spring.redis.pool.max-idle=8
# 連接池中的最小空閒連接
spring.redis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.timeout=0

3.3 RedisService

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2017/12/1.
 */
@Service
public class RedisService {

    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 寫入緩存
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 寫入緩存設置時效時間
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 批量刪除對應的value
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    /**
     * 批量刪除key
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0)
            redisTemplate.delete(keys);
    }
    /**
     * 刪除對應的value
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }
    /**
     * 判斷緩存中是否有對應的value
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }
    /**
     * 讀取緩存
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }
    /**
     * 哈希 添加
     * @param key
     * @param hashKey
     * @param value
     */
    public void hmSet(String key, Object hashKey, Object value){
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key,hashKey,value);
    }

    /**
     * 哈希獲取數據
     * @param key
     * @param hashKey
     * @return
     */
    public Object hmGet(String key, Object hashKey){
        HashOperations<String, Object, Object>  hash = redisTemplate.opsForHash();
        return hash.get(key,hashKey);
    }

    /**
     * 列表添加
     * @param k
     * @param v
     */
    public void lPush(String k,Object v){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k,v);
    }

    /**
     * 列表獲取
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> lRange(String k, long l, long l1){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k,l,l1);
    }

    /**
     * 集合添加
     * @param key
     * @param value
     */
    public void add(String key,Object value){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key,value);
    }

    /**
     * 集合獲取
     * @param key
     * @return
     */
    public Set<Object> setMembers(String key){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }

    /**
     * 有序集合添加
     * @param key
     * @param value
     * @param scoure
     */
    public void zAdd(String key,Object value,double scoure){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key,value,scoure);
    }

    /**
     * 有序集合獲取
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> rangeByScore(String key,double scoure,double scoure1){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }
}

3.4 測試用的Controller

import com.example.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {


    @Autowired
    private RedisService redisService ;


    @RequestMapping(value = "/test",method = RequestMethod.POST)
    public void demoTest(){
        redisService.set("1","value22222");
    }

}

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章