Redis 概述與應用


Redis

1. Redis 介紹

  • Redis(Remote Dictionary Server)是用C語言開發的一個開源的高性能鍵值對數據庫。它的所有數據都是保存在 內存 中,這也就決定了其讀寫速度之快,是其它硬盤保存數據的系統所無法匹敵的。
  • 官方曾經給出過一組測試數據,50個併發執行 100000個請求:讀的速度是 110000次/s,寫的速度是 81000次/s
    在這裏插入圖片描述

2. Redis 安裝和使用

a. 下載

b. Windows 版安裝

c. 目錄

在這裏插入圖片描述

  • redis.windows.conf:配置文件
  • redis-cli.exe:Redis 的客戶端
  • redis-server.exe:Redis 服務器端

d. 啓動

  • 推薦使用命令行的方式
  • 在當前解壓後的目錄下 cmd 進入 dos 窗口
  • 先啓動 redis-server.exe redis.windows.conf
    在這裏插入圖片描述
  • 新建窗口,再啓動 redis-cli.exe
    在這裏插入圖片描述

3. Redis 客戶端圖形化工具

4. Redis 數據結構(重點)

  • Redis 採用的鍵值對存儲數據,鍵(key)的類型只能爲 字符串,值(value)支持五種數據類型:
    1. 字符串:String
    2. 哈希:HashMap
    3. 雙向鏈表:LinkedList,有序且能重複,可以左壓棧也可以右壓棧
    4. 無序集合:HashSet,無序且不能重複
    5. 有序集合:LinkedHashSet,有序且不能重複

5. Redis 命令操作(重點)

  • Redis 命令是用來操作 Redis 數據庫的,類似於操作 MySql 數據庫時的 SQL 語句。
  • 只需要學習 SQL 基本就可以操作關係型數據庫(1972 年誕生);但是 Redis 命令,在非關係型數據庫中,只能在 Redis 中使用(只有十幾年的發展經歷,所以沒有一定的開發規範)
  • Redis 的命令根據要操作的值(value)的數據結構的不同而不同,每種數據類型都有自己的操作命令。

a. String 字符串

  • 字符串類型是 Redis 中最爲基礎的數據存儲類型。
  • 在 Redis 中字符串類型的 Value 最多可以容納的數據長度是 512 MB(超過這個上限,可以改用 HBase)。
* 新增
		set key 'value'
		value 的值有空格需要加引號,沒有空格不需要加引號
* 查詢
		get key
* 刪除	
		del key
		成功則返回 1
* 新增並指定存活時間
		setex key 存活時間 'value'
		單位秒
* 查看存活時間
		ttl key  
* 主鍵自增器 
		incr key
		value 的值默認加 1
		需要 value 是整型

b. Hash 哈希

  • Hash 類型極其類似於 Java 中的 Map,值裏面可以存放一組組的鍵值對,該類型非常適合於存儲 Java 中對象的信息。
* 新增
		hset key hkey hvalue
* 查詢
		hget key hkey
		hgetall key
* 刪除
		hdel key hkey
		del key

在這裏插入圖片描述

c. List 鏈表

  • List 類型底層是一個雙向字符串鏈表。裏面的元素是有序的,可重複的,可以從鏈表的任何一端進行元素的增刪。
* 新增
		lpush key value 將元素壓入左側頂端
		rpush key value 將元素壓入右側頂端
		建議只用其中一種
* 查詢
		lrange key start end 從左向右查詢
		start 爲 0,end 爲 -1 是查詢所有
* 刪除
		lpop key 將左側頂端元素彈出
		rpop key 將右側頂端元素彈出

在這裏插入圖片描述

d. Set 集合(無序)

  • Set 類型底層是一張 hash 表。裏面的元素是無序的,不可重複的。
* 新增
		sadd key value
* 查詢
		smembers key
* 刪除
		srem key value 刪除指定元素
		del key 刪除整個 set 集合

e. ZSet 集合(有序)

  • Zset,也稱 sortedSet,在 Set 的基礎上,加入了有序功能,在添加元素的時候,允許指定一個分數,它會按照這個分數排序。
* 新增
		zadd key score value
* 查詢
		zrange key start end [withscores] 升序
		zrevrange key start end [withscores] 降序
		加上 withscores 會顯示分數,不加 withscores 只顯示元素
* 刪除
		zrem key value 刪除指定元素
		del key 刪除 zset 集合

f. 通用命令

* 模糊查詢鍵
		keys *
		* 是通配符,表示所有
* 刪除多個鍵
		del key [key] [key]
		返回的數就是被影響的 key 的數量
* 根據鍵判斷記錄是否存在
		exists key
		返回的值 0 是 false,1 是 true
* 根據鍵判斷值類型 
		type key
		很重要,時間久了可以用它來判斷並進行相應操作
* 選擇數據庫
		select 0~15
		默認是 0 庫,一般也使用 0 庫
* 清空當前數據庫
		flushdb
		慎重使用,開發中不允許使用
* 清空所有數據庫
		flushall
		慎重使用,開發中不允許使用

6. Redis 持久化(面試題)

  • Redis 的數據都是存在在內存之中的,那麼這樣一旦出現宕機,勢必會導致數據的丟失,這就需要持久化操作,也就是要將 Redis 在內存中的數據寫到硬盤上保存。
  • 注意,Redis 雖然有持久化操作,但是其全部數據依舊都在內存中存在,也就是說硬盤上的只是爲了安全和備份。
  • Redis 提供了兩種數據持久化的方式,分別是 RDB 和 AOF。

a. RDB(默認開啓)

  • 在 Redis 運行期間,根據指定時間節點對內存的數據進行快照拍攝,持久化到磁盤文件(默認文件 dump.rdb,亂碼)
  • 指定時間規則拍攝快照:在 redis.windows.conf 中指定
    save 900 1
    save 300 10
    save 60 10000
    在這裏插入圖片描述

b. AOF(默認關閉,需要手動開啓)

  • 在 Redis 運行期間,以日誌記錄的方式監聽 set 操作,持久化到磁盤文件(默認文件 appendonly.aof,每步操作可查看,Redis 重啓後逐步加載)
  • 開啓 AOF:修改 redis.windows.conf 中的 appendonly no 爲 appendonly yes
  • 日誌持久化機制
    • appendfsync always 每次執行 set 操作時都會持久化一次;
    • appendfsync everysec 每秒鐘持久化一次(默認,因爲 Redis 每秒讀寫速度很快,所以這種折中方案比第一種更合適);
    • appendfsync no 根據服務器環境,CPU 不忙的情況,持久化一次。

c. 小結

  • RDB:把 Redis 作爲緩存來用。
    • 優點:性能高
    • 缺點:可能會丟失部分數據
  • AOF:把 Redis 作爲獨立數據庫。
    • 優點:幾乎不會丟失數據
    • 確定:性能較差
  • 這二種持久化機制可以共存。

7. 應用場景

a. 緩存

在這裏插入圖片描述

b. 秒殺

在這裏插入圖片描述

c. 微博熱搜

在這裏插入圖片描述

d. 分佈式 Session

在這裏插入圖片描述

e. 驗證碼存儲

  • 通過將驗證碼放到 Redis 中,可以實現對其存貨時間的精準控制。
    在這裏插入圖片描述

Jedis

  • Redis 作爲一款優秀的緩存服務器存在,大多數語言都提供了連接 Redis 的驅動包,在 Java 中,比較出名的是 Jedis 和 Redisson,我們今天以 Jedis 爲例學習,看看如何是用程序操作 Redis。

1. Jedis 快速入門

  • 常用 API:
方法 解釋
new Jedis(host, port) 創建 Jedis 對象,參數 host 是 Redis 服務器地址,參數 port 是 Redis 服務端口
set(key,value) 設置字符串類型的數據
get(key) 獲得字符串類型的數據
hset(key,field,value) 設置哈希類型的數據
hget(key,field) 獲得哈希類型的數據
lpush(key,values) 設置列表類型的數據
lpop(key) 列表左面彈棧
rpop(key) 列表右面彈棧
del(key) 刪除指定的 key
  • 在測試 Jedis 代碼之前,一定要保證 Redis 環境正常運行。Windows 有時需要重啓 Server。

a. 導入相關座標

在這裏插入圖片描述

b. 編寫代碼

package com.regino.test;

import org.junit.Test;
import redis.clients.jedis.Jedis;

public class JedisTest {

    // 向Redis設置String類型的數據
    @Test
    public void test01() throws Exception {
        // 1.創建連接對象
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        // 2.調用set方法設置數據,cmd會將中文轉爲Unicode
        jedis.set("Regino", "你好");
        // 3.釋放資源,底層是Socket
        jedis.close();
    }

    // 查詢String類型數據
    @Test
    public void test02() throws Exception {
        // 1.創建連接對象
        Jedis jedis = new Jedis(); // 默認連接 127.0.0.1 主機 和 6379 端口
        // 2.調用get方法獲取
        String java = jedis.get("Regino");
        System.out.println(java);
        // 3.釋放資源
        jedis.close();
    }
}

在這裏插入圖片描述

2. Jedis 連接池

  • Jedis 連接資源的創建與銷燬是非常消耗性能的,所以我們不希望頻繁的創建和銷燬它。基於這樣的需求,就有了 jedisPool 技術。

a. 快速入門

package com.regino.test;

import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisPoolTest {

    // 測試Jedis內置的連接池
    @Test
    public void test01() throws Exception {

        // 連接池配置對象
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(100); // 最大連接數
        jedisPoolConfig.setMaxWaitMillis(3000);// 最大等待時間,單位是毫秒,超過會自動拋出異常
        jedisPoolConfig.setMaxIdle(10); // 最大空閒連接數,釋放沒用的資源

        // 創建連接池對象
        JedisPool jedisPool = new JedisPool("localhost", 6379); // 建議使用IP,用localhost只能連接本地

        // 從池中獲取連接
        Jedis jedis = jedisPool.getResource();

        // 操作API
        jedis.hset("myhash", "id", "1");

        // 歸還到連接池
        jedis.close();
    }
}

在這裏插入圖片描述

b. 抽取爲連接池工具類

在這裏插入圖片描述

package com.regino.travel.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.ResourceBundle;

/*
 *   Jedis工具類
 * */
public class JedisUtils {

    private static JedisPool jedisPool;

    private static String host;
    private static Integer port;
    private static Integer maxTotal;
    private static Integer maxIdle;

    // 初始化連接池
    static {
        try {
            ResourceBundle jedis = ResourceBundle.getBundle("jedis");

            // 讀取配置文件給變量賦值
            // 獲取類加載讀取jedis.properties,獲取io流
            InputStream is = JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
            // 創建properties對象 加載io流
            Properties properties = new Properties();
            properties.load(is);
            // 給變量賦值
            host = properties.getProperty("jedis.host");
            port = Integer.parseInt(properties.getProperty("jedis.port"));
            maxTotal = Integer.parseInt(properties.getProperty("jedis.maxTotal"));
            maxIdle = Integer.parseInt(properties.getProperty("jedis.maxIdle"));

            // 創建連接池配置對象
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            jedisPoolConfig.setMaxTotal(maxTotal);
            jedisPoolConfig.setMaxIdle(maxIdle);
            // 創建連接池對象
            jedisPool = new JedisPool(jedisPoolConfig, host, port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

原文鏈接:https://qwert.blog.csdn.net/article/details/106290370

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