Redis的安裝和(Spring Data)使用

一、Redis基礎

1. 概念

redis是一款高性能的NOSQL系列的非關係型數據庫

1.1 什麼是NOSQL

​ NoSQL(NoSQL = Not Only SQL),意即“不僅僅是SQL”,是一項全新的數據庫理念,泛指非關係型的數據庫。
​ 隨着互聯網web2.0網站的興起,傳統的關係數據庫在應付web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站已經顯得力不從心,暴露了很多難以克服的問題,而非關係型的數據庫則由於其本身的特點得到了非常迅速的發展。NoSQL數據庫的產生就是爲了解決大規模數據集合多重數據種類帶來的挑戰,尤其是大數據應用難題。

1.1.1 NOSQL和與SQL

​ 優點:
​ 1)成本:nosql數據庫簡單易部署,基本都是開源軟件,不需要像使用oracle那樣花費大量成本購買使用,相比關係型數據庫價格便宜。
​ 2)查詢速度:nosql數據庫將數據存儲於緩存之中,關係型數據庫將數據存儲在硬盤中,自然查詢速度遠不及nosql數據庫。
​ 3)存儲數據的格式:nosql的存儲格式是key,value形式、文檔形式、圖片形式等等,所以可以存儲基礎類型以及對象或者是集合等各種格式,而數據庫則只支持基礎類型。
​ 4)擴展性:關係型數據庫有類似join這樣的多表查詢機制的限制導致擴展很艱難。

​ 缺點:
​ 1)維護的工具和資料有限,因爲nosql是屬於新的技術,不能和關係型數據庫10幾年的技術同日而語。
​ 2)不提供對sql的支持,如果不支持sql這樣的工業標準,將產生一定用戶的學習和使用成本。
​ 3)不提供關係型數據庫對事務的處理。

1.1.2. NOSQL優勢:

​ 1)性能NOSQL是基於鍵值對的,可以想象成表中的主鍵和值的對應關係,而且不需要經過SQL層的解析,所以性能非常高。
​ 2)可擴展性同樣也是因爲基於鍵值對,數據之間沒有耦合性,所以非常容易水平擴展。

1.1.3. SQL優勢:

​ 1)複雜查詢可以用SQL語句方便的在一個表以及多個表之間做非常複雜的數據查詢。
​ 2)事務支持使得對於安全性能很高的數據訪問要求得以實現。對於這兩類數據庫,對方的優勢就是自己的弱勢,反之亦然。

1.1.4. 總結

關係型數據庫與NoSQL數據庫並非對立而是互補的關係,即通常情況下使用關係型數據庫,在適合使用NoSQL的時候使用NoSQL數據庫,讓NoSQL數據庫對關係型數據庫的不足進行彌補。一般會將數據存儲在關係型數據庫中,在nosql數據庫中備份存儲關係型數據庫的數據

1.2 主流的NOSQL產品

​ • 鍵值(Key-Value)存儲數據庫
​ 相關產品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
​ 典型應用: 內容緩存,主要用於處理大量數據的高訪問負載。
​ 數據模型: 一系列鍵值對
​ 優勢: 快速查詢
​ 劣勢: 存儲的數據缺少結構化
​ • 列存儲數據庫
​ 相關產品:Cassandra, HBase, Riak
​ 典型應用:分佈式的文件系統
​ 數據模型:以列簇式存儲,將同一列數據存在一起
​ 優勢:查找速度快,可擴展性強,更容易進行分佈式擴展
​ 劣勢:功能相對侷限
​ • 文檔型數據庫
​ 相關產品:CouchDB、MongoDB
​ 典型應用:Web應用(與Key-Value類似,Value是結構化的)
​ 數據模型: 一系列鍵值對
​ 優勢:數據結構要求不嚴格
​ 劣勢: 查詢性能不高,而且缺乏統一的查詢語法
​ • 圖形(Graph)數據庫
​ 相關數據庫:Neo4J、InfoGrid、Infinite Graph
​ 典型應用:社交網絡
​ 數據模型:圖結構
​ 優勢:利用圖結構相關算法。
​ 劣勢:需要對整個圖做計算才能得出結果,不容易做分佈式的集羣方案。

1.3 什麼是Redis

	Redis是用C語言開發的一個開源的高性能鍵值對(key-value)數據庫,官方提供測試數據,50個併發執行100000個請求,讀的速度是110000次/s,寫的速度是81000次/s ,
	且Redis通過提供多種鍵值數據類型來適應不同場景下的存儲需求,目前爲止Redis支持的鍵值數據類型如下:
		1) 字符串類型 string
		2) 哈希類型 hash
		3) 列表類型 list
		4) 集合類型 set
		5) 有序集合類型 sortedset
	1.3.1 redis的應用場景
		•	緩存(數據查詢、短連接、新聞內容、商品內容等等)
		•	聊天室的在線好友列表
		•	任務隊列。(秒殺、搶購、12306等等)
		•	應用排行榜
		•	網站訪問統計
		•	數據過期處理(可以精確到毫秒
		•	分佈式集羣架構中的session分離

2.下載安裝

官網:https://redis.io

2. 中文網:http://www.redis.net.cn/
 3. 解壓直接可以使用:
    * redis.windows.conf:配置文件
    * redis-cli.exe:redis的客戶端
    * redis-server.exe:redis服務器端

然後啓動發現個一個問題:

system error caught. error code=0x000005af, message=VirtualAllocEx failed.: unknown error

經查閱相關質料發現是因爲沒有設置redis的最大內存所導致
redis.windows.conf配置文件中加入:

maxmemory 268435456
maxheap 314572800

3.redis的數據結構:

  • redis存儲的是:key,value格式的數據,其中key都是字符串,value有5種不同的數據結構
    • value的數據結構:
      1. 字符串類型 string
      2. 哈希類型 hash : map格式
      3. 列表類型 list : linkedlist格式。支持重複元素
      4. 集合類型 set : 不允許重複元素
      5. 有序集合類型 sortedset:不允許重複元素,且元素有順序

字符串類型 string

  • 最大大小 :512MB
  1. 存儲: set key value

  2. 獲取: get key

  3. 刪除: del key

批量設置、獲取

mset key val key val
mget key key

字符串長度

strlen key

時效設置

setex key seconds val
psetex key milliseconds val

增減

incr key    //+1
incrby key  num
decr key  //-1
decrby key  num
incrbyfloat key num

哈希類型 hash

  • hash類型下的value只能存儲字符串,不允許存儲其他數據類型,不存在嵌套現象。
  • 每個hash可以存儲232 - 1個鍵值對
  • hash類型十分貼近對象的數據存儲形式,並且可以靈活添加刪除對象屬性。但hash設計初衷不是爲了存儲大量對象而設計的,切記不可濫用,更不可以將hash作爲對象列表使用
  • hgetall操作可以獲取全部屬性,如果內部field過多 ,遍歷整體數據效率就很會低,用多少拿多少
  1. 存儲: hset key field value
  2. 獲取:
    • hget key field: 獲取指定的field對應的值
    • hgetall key:獲取所有的field和value
  3. 批量操作
    • hmget
    • hmset
  4. 刪除: hdel key field
  5. 哈希表長度: hlen key
  6. 存在: hexists key field

列表類型 list

最多232 - 1個元素
在這裏插入圖片描述
可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)

  1. 添加:

    1. lpush key value: 將元素加入列表左表

    2. rpush key value:將元素加入列表右邊

      127.0.0.1:6379> lpush myList a
      (integer) 1
      127.0.0.1:6379> lpush myList b
      (integer) 2
      127.0.0.1:6379> rpush myList c
      (integer) 3

  2. 獲取:

    • lrange key start end :範圍獲取
      127.0.0.1:6379> lrange myList 0 -1
      1. “b”
      2. “a”
      3. “c”
  3. 刪除:

    • lpop key: 刪除列表最左邊的元素,並將元素返回
    • rpop key: 刪除列表最右邊的元素,並將元素返回

集合類型 set

不允許重複元素

  1. 存儲:sadd key value
    127.0.0.1:6379> sadd myset a
    (integer) 1
    127.0.0.1:6379> sadd myset a
    (integer) 0
    2. 獲取:smembers key:獲取set集合中所有元素
    127.0.0.1:6379> smembers myset
    1. “a”
    1. 刪除:srem key value:刪除set集合中的某個元素
      127.0.0.1:6379> srem myset a
      (integer) 1

有序集合 sortedset

不允許重複元素,且元素有順序.每個元素都會關聯一個double類型的分數。redis正是通過分數來爲集合中的成員進行從小到大的排序。

  1. 存儲:zadd key score value

    127.0.0.1:6379> zadd mysort 60 zhangsan
    (integer) 1
    127.0.0.1:6379> zadd mysort 50 lisi
    (integer) 1
    127.0.0.1:6379> zadd mysort 80 wangwu
    (integer) 1
    
  2. 獲取:zrange key start end [withscores]

    127.0.0.1:6379> zrange mysort 0 -1
    1) "lisi"
    2) "zhangsan"
    3) "wangwu"
    
    127.0.0.1:6379> zrange mysort 0 -1 withscores
    1) "zhangsan"
    2) "60"
    3) "wangwu"
    4) "80"
    5) "lisi"
    6) "500"
    

3.刪除:zrem key value

127.0.0.1:6379> zrem mysort lisi
(integer) 1

通用命令

  1. keys * : 查詢所有的鍵
  2. type key : 獲取鍵對應的value的類型
  3. del key:刪除指定的key value

4.持久化

redis是一個內存數據庫,當redis服務器重啓,獲取電腦重啓,數據會丟失,我們可以將redis內存中的數據持久化保存到硬盤的文件中。

redis持久化機制:

  1. RDB:默認方式,不需要進行配置,默認就使用這種機制

    • 在一定的間隔時間中,檢測key的變化情況,然後持久化數據
    1. 編輯redis.windwos.conf文件

      #after 900 sec (15 min) if at least 1 key changed
      
      save 900 1
      
      #after 300 sec (5 min) if at least 10 keys changed
      
      save 300 10
      
      #after 60 sec if at least 10000 keys changed
      
      save 60 10000
      
    2. 重新啓動redis服務器,並指定配置文件名稱
      D\ …\資料\redis\windows-64\redis-2.8.9>redis-server.exe redis.windows.conf

  2. AOF:日誌記錄的方式,可以記錄每一條命令的操作。可以每一次命令操作後,持久化數據

    1. 編輯redis.windwos.conf文件
      appendonly no(關閉aof) --> appendonly yes (開啓aof)

      appendfsync always : 每一次操作都進行持久化

      appendfsync everysec : 每隔一秒進行一次持久化

      appendfsync no : 不進行持久化

Java客戶端 Jedis

Jedis: 一款java操作redis數據庫的工具.

使用步驟:

  1. 下載jedis的jar包

  2. 使用

    //1. 獲取連接
    Jedis jedis = new Jedis("localhost",6379);
    //2. 操作
    jedis.set("username","zhangsan");
     //3. 關閉連接
     jedis.close();
    

Jedis操作redis的數據結構

1) 字符串類型 string
set
get
 //1. 獲取連接
        Jedis jedis = new Jedis();//如果使用空參構造,默認值 "localhost",6379端口
        //2. 操作
        //存儲
        jedis.set("username","zhangsan");
        //獲取
        String username = jedis.get("username");
        System.out.println(username);

        //可以使用setex()方法存儲可以指定過期時間的 key value
        jedis.setex("activecode",20,"hehe");//將activecode:hehe鍵值對存入redis,並且20秒後自動刪除該鍵值對

        //3. 關閉連接
        jedis.close();
2) 哈希類型 hash : map格式
hset
hget
hgetAll
	    //1. 獲取連接
        Jedis jedis = new Jedis();//如果使用空參構造,默認值 "localhost",6379端口
        //2. 操作
        // 存儲hash
        jedis.hset("user","name","lisi");
        jedis.hset("user","age","23");
        jedis.hset("user","gender","female");

        // 獲取hash
        String name = jedis.hget("user", "name");
        System.out.println(name);
	        // 獲取hash的所有map中的數據
	        Map<String, String> user = jedis.hgetAll("user");
	
	        // keyset
	        Set<String> keySet = user.keySet();
	        for (String key : keySet) {
	            //獲取value
	            String value = user.get(key);
	            System.out.println(key + ":" + value);
	        }
	
	        //3. 關閉連接
	        jedis.close();
3) 列表類型 list

linkedlist格式。支持重複元素

lpush / rpush
lpop / rpop
lrange start end : 範圍獲取
			

//1. 獲取連接
Jedis jedis = new Jedis();//如果使用空參構造,默認值 "localhost",6379端口
//2. 操作
// list 存儲
jedis.lpush("mylist","a","b","c");//從左邊存
jedis.rpush("mylist","a","b","c");//從右邊存

// list 範圍獲取
List<String> mylist = jedis.lrange("mylist", 0, -1);
System.out.println(mylist);

// list 彈出
String element1 = jedis.lpop("mylist");//c
System.out.println(element1);

String element2 = jedis.rpop("mylist");//c
System.out.println(element2);

// list 範圍獲取
List<String> mylist2 = jedis.lrange("mylist", 0, -1);
System.out.println(mylist2);

//3. 關閉連接
jedis.close();
4) 集合類型 set : 不允許重複元素

​ sadd
​ smembers:獲取所有元素

	        //1. 獲取連接
	        Jedis jedis = new Jedis();//如果使用空參構造,默認值 "localhost",6379端口
	        //2. 操作
	        // set 存儲
	        jedis.sadd("myset","java","php","c++");
	
	        // set 獲取
	        Set<String> myset = jedis.smembers("myset");
	        System.out.println(myset);
	
	        //3. 關閉連接
	        jedis.close();
		5) 有序集合類型 sortedset:不允許重複元素,且元素有順序
			zadd
			zrange

			//1. 獲取連接
	        Jedis jedis = new Jedis();//如果使用空參構造,默認值 "localhost",6379端口
	        //2. 操作
	        // sortedset 存儲
	        jedis.zadd("mysortedset",3,"亞瑟");
	        jedis.zadd("mysortedset",30,"後裔");
	        jedis.zadd("mysortedset",55,"孫悟空");
	
	        // sortedset 獲取
	        Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1);
	
	        System.out.println(mysortedset);
	        //3. 關閉連接
	        jedis.close();

jedis連接池: JedisPool

使用:
  1. 創建JedisPool連接池對象

  2. 調用方法 getResource()方法獲取Jedis連接

    //0.創建一個配置對象
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(50);
    config.setMaxIdle(10);
    
    //1.創建Jedis連接池對象
    JedisPool jedisPool = new JedisPool(config,"localhost",6379);
    
    //2.獲取連接
    Jedis jedis = jedisPool.getResource();
    //3. 使用
    jedis.set("hehe","heihei");
    
    //4. 關閉 歸還到連接池中
    jedis.close();
    

連接池工具類

public class JedisPoolUtils {

    private static JedisPool jedisPool;

    static{
        //讀取配置文件
        InputStream is = 	JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
        //創建Properties對象
        Properties pro = new Properties();
        //關聯文件
        try {
            pro.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //獲取數據,設置到JedisPoolConfig中
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
        config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));

        //初始化JedisPool
        jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));

	}

     /**
    	獲取連接方法
    */
    public static Jedis getJedis(){
   		 return jedisPool.getResource();
    }
}

案例:

案例需求:
	1. 提供index.html頁面,頁面中有一個省份 下拉列表
	2. 當 頁面加載完成後 發送ajax請求,加載所有省份


* 注意:使用redis緩存一些不經常發生變化的數據。
	* 數據庫的數據一旦發生改變,則需要更新緩存。
		* 數據庫的表執行 增刪改的相關操作,需要將redis緩存數據情況,再次存入
		* 在service對應的增刪改方法中,將redis數據刪除。

二、spring data Redis

官網:http://projects.spring.io/spring-data-redis/
Spring Data Redis,是Spring Data 家族的一部分。 對Jedis客戶端進行了封裝,與spring進行了整合。可以非常方便的來實現redis的配置和操作。

RedisTemplate基本操作

Spring Data Redis 提供了一個工具類:RedisTemplate。裏面封裝了對於Redis的五種數據結構的各種操作,包括:

  • redisTemplate.opsForValue() :操作字符串
  • redisTemplate.opsForHash() :操作hash
  • redisTemplate.opsForList():操作list
  • redisTemplate.opsForSet():操作set
  • redisTemplate.opsForZSet():操作zset

其它一些通用命令,如expire,可以通過redisTemplate.xx()來直接調用

5種結構:

  • String:等同於java中的,Map<String,String>
  • list:等同於java中的Map<String,List<String>>
  • set:等同於java中的Map<String,Set<String>>
  • sort_set:可排序的set
  • hash:等同於java中的:`Map<String,Map<String,String>>

StringRedisTemplate

RedisTemplate在創建時,可以指定其泛型類型:

  • K:代表key 的數據類型
  • V: 代表value的數據類型

注意:這裏的類型不是Redis中存儲的數據類型,而是Java中的數據類型,RedisTemplate會自動將Java類型轉爲Redis支持的數據類型:字符串、字節、二進制等等。

不過RedisTemplate默認會採用JDK自帶的序列化(Serialize)來對對象進行轉換。生成的數據十分龐大,因此一般我們都會指定key和value爲String類型,這樣就由我們自己把對象序列化爲json字符串來存儲即可。

因爲大部分情況下,我們都會使用key和value都爲String的RedisTemplate,因此Spring就默認提供了這樣一個實現:
在這裏插入圖片描述

spring data Redis案例

創建spring boot項目,寫好啓動器,引入Redis啓動器:

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

然後在配置文件中指定Redis地址:

spring:
  redis:
    host: 47.107.246.98 # 遠程服務器或者虛擬機地址

創建test

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class test {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void  test1(){
    //寫入redis
        redisTemplate.opsForValue().set("codeying","帥哥",3, TimeUnit.SECONDS);
//取出數據
        String val=(String) this.redisTemplate.opsForValue().get("hello");
        System.out.println(val);
    }
}

三、Linux(服務器)安裝redis

1.安裝

準備好redis的Linux版本,官網下載

  • 解壓
 tar -xvf redis-4.0.9.tar.gz
  • 編譯安裝(需要有C編譯器)
 mv redis-4.0.9 redis
 cd redis
 make && make install

2.配置

修改安裝目錄下的redis.conf文件

vim redis.conf

修改以下配置:

#bind 127.0.0.1 # 將這行代碼註釋,監聽所有的ip地址,外網可以訪問
protected-mode no # 把yes改成no,允許外網訪問
daemonize yes # 把no改成yes,後臺運行

3.啓動或停止

redis提供了服務端命令和客戶端命令:

  • redis-server 服務端命令,可以包含以下參數:
    start 啓動
    stop 停止
  • redis-cli 客戶端控制檯,包含參數:
    -h xxx 指定服務端地址,缺省值是127.0.0.1
    -p xxx 指定服務端端口,缺省值是6379

4.設置開機啓動

  1. 輸入命令,新建文件
vim /etc/init.d/redis

輸入下面內容:

#!/bin/sh
# chkconfig:   2345 90 10
# description:  Redis is a persistent key-value database
PATH=/usr/local/bin:/sbin:/usr/bin:/bin

REDISPORT=6379
EXEC=/usr/local/bin/redis-server
REDIS_CLI=/usr/local/bin/redis-cli

PIDFILE=/var/run/redis.pid

CONF="/usr/local/leyou/redis/redis.conf"

case "$1" in  
    start)  
        if [ -f $PIDFILE ]  
        then  
                echo "$PIDFILE exists, process is already running or crashed"  
        else  
                echo "Starting Redis server..."  
                $EXEC $CONF  
        fi  
        if [ "$?"="0" ]   
        then  
              echo "Redis is running..."  
        fi  
        ;;  
    stop)  
        if [ ! -f $PIDFILE ]  
        then  
                echo "$PIDFILE does not exist, process is not running"  
        else  
                PID=$(cat $PIDFILE)  
                echo "Stopping ..."  
                $REDIS_CLI -p $REDISPORT SHUTDOWN  
                while [ -x ${PIDFILE} ]  
               do  
                    echo "Waiting for Redis to shutdown ..."  
                    sleep 1  
                done  
                echo "Redis stopped"  
        fi  
        ;;  
   restart|force-reload)  
        ${0} stop  
        ${0} start  
        ;;  
  *)  
    echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2  
        exit 1  
esac

然後保存退出

注意:以下信息需要根據安裝目錄進行調整:

EXEC=/usr/local/bin/redis-server # 執行腳本的地址

REDIS_CLI=/usr/local/bin/redis-cli # 客戶端執行腳本的地址

PIDFILE=/var/run/redis.pid # 進程id文件地址

CONF="/usr/local/src/redis-3.0.2/redis.conf" #配置文件地址

2)設置權限

chmod 755 /etc/init.d/redis

3)啓動測試

/etc/init.d/redis start

啓動成功會提示如下信息:

Starting Redis server...
Redis is running...

4)設置開機自啓動

chkconfig --add /etc/init.d/redis
chkconfig redis on

5.阿里雲服務器連接

我是安裝在遠程服務器上
進入設置
在這裏插入圖片描述
配置
在這裏插入圖片描述
添加redis使用的端口,設置爲可訪問
在這裏插入圖片描述

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