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)支持五種數據類型:
- 字符串:String
- 哈希:HashMap
- 雙向鏈表:LinkedList,有序且能重複,可以左壓棧也可以右壓棧
- 無序集合:HashSet,無序且不能重複
- 有序集合: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 快速入門
方法 |
解釋 |
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 {
@Test
public void test01() throws Exception {
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.set("Regino", "你好");
jedis.close();
}
@Test
public void test02() throws Exception {
Jedis jedis = new Jedis();
String java = jedis.get("Regino");
System.out.println(java);
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 {
@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);
Jedis jedis = jedisPool.getResource();
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;
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");
InputStream is = JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
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();
}
}
public static Jedis getJedis() {
return jedisPool.getResource();
}
}
原文鏈接:https://qwert.blog.csdn.net/article/details/106290370