Redis - 非關系型資料庫
- Redis是Key-Value型NoSQL資料庫
- Redis将資料存儲在記憶體中,同時也能持久化到磁盤
- Redis常用于緩存,利用記憶體的高效提高程式的處理速度
Redis特點
- 速度快
- 廣泛的語言支援
- 持久化
- 多種資料結構
- 主從複制 - 多台資料庫伺服器内容相同
- 分布式與高可用
Redis的安裝與啟動
https://redis.io/
Linux系統安裝Redis
安裝gcc後才能使用make指令
[[email protected] ~]# cd /usr/local/
[[email protected] local]# mkdir redis
[[email protected] local]# cd redis
[[email protected] redis]# yum install gcc
安裝redis
$ wget https://download.redis.io/releases/redis-6.2.5.tar.gz
$ tar xzf redis-6.2.5.tar.gz
$ cd redis-6.2.5
$ make
在src目錄中,
redis-server
是啟動指令,
redis-cli
開啟用戶端連接配接。
啟動redis
[[email protected] redis-6.2.5]# ./src/redis-server redis.conf
Windows系統安裝Redis
微軟提供了一個能在Windows平台下使用的redis
https://github.com/MicrosoftArchive/redis
不過該項目在3.2.1版本之後就不在更新了
https://github.com/microsoftarchive/redis/releases
下載下傳Redis-x64-3.2.100.zip
解壓壓縮包,使用cmd指令啟動加載
redis-server redis.windows.conf
Redis的常用基本配置
配置項 | 示例 | 說明 |
---|---|---|
daemonize | daemonize yes | 是否啟用背景運作,預設no |
port | port 6379 | 設定端口号,預設6379 |
logfile | logfile 日志檔案 | 設定日志檔案 |
databases | databases 255 | 設定redis資料庫總量 |
dir | dir 資料檔案目錄 | 設定資料檔案存儲目錄 |
requirepass | requirepass 12345 | 設定使用密碼 |
守護程序方式啟動Redis
vim redis.conf
daemonize 參數值改為yes,esc :wq儲存退出
重新啟動redis
netstat -tulpn | grep 6379可以檢視到redis程序和pid
kill -9 redis的pid 後再檢視就不見了
kill指令不推薦使用,下面會學習到使用redis用戶端,使用redis提供的指令關閉redis
Redis用戶端
啟動redis-cli;ping指令用于檢查redis服務,會傳回PONG;退出exit;
[[email protected] redis-6.2.5]# ./src/redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> exit
關閉redis
使用redis自帶的指令關閉redis
[[email protected]host redis-6.2.5]# ./src/redis-cli shutdown
設定端口号
port 後面參數修改
啟動redis-cli時加上端口号參數
[[email protected] redis-6.2.5]# ./src/redis-cli -p 端口号
設定日志檔案
vim redis.conf
logfile “” 預設是一個空字元串,可以改為.log結尾的檔案
logfile “redis.log”
設定資料庫總量
redis資料庫名是由數字管理的,預設是0-15,16個
[[email protected] redis-6.2.5]# ./src/redis-cli
127.0.0.1:6379> select 0
OK
127.0.0.1:6379> select 15
OK
可以使用配置檔案修改:
databases 資料庫總量
設定身份校驗密碼
requirepass 密碼
使用時提供密碼
[[email protected] redis-6.2.5]# ./src/redis-cli
127.0.0.1:6379> auth 密碼
指定資料檔案的儲存路徑
一般預設不用修改
dir ./
Redis通用指令
指令 | 示例 | 說明 |
---|---|---|
select | select 0 | 選擇0号資料庫 |
set | set name lily | 設定key=name, value=lily |
get | get hello | 獲得key=hello結果 |
keys | keys he* | 根據Pattern表達式查詢符号條件的Key |
dbsize | dbsize | 傳回key的總數 |
exists | exists a | 檢查key=a是否存在 |
del | del a | 删除key=a的資料 |
expire | expire hello 20 | 設定key=hello 20秒後過期 |
ttl | ttl hello | 檢視key=a的過期剩餘時間 |
Redis資料類型
String - 字元串類型
String最大512mb,建議單個ky不超過100kb
字元串指令
指令 | 示例 | 說明 |
---|---|---|
get | get hello | 獲得key=hello結果 |
set | set hello world | 設定key=hello, value=hello |
mset mget | mset hello world java best mget hello java | 一次性設定或者擷取多個值 |
del | del hello | 删除key=hello |
incr/decr | incr count decr count | key值自增/自減1 |
incrby/decrby | incrby conut 99 decrby count 99 | 自增自減指定步長 |
Hash - Hash類型
Hash類型用于存儲結構化資料
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL0kFVPlXWE1UejpWT5VkMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLmFGNxkzM4IGOmZjM0kjY5YWN2QDMzIjY4UWZ1IjM4YzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
Hash 指令
指令 | 示例 | 說明 |
---|---|---|
hget | hget emp:1 age | 擷取hash中key=age的值 |
hset | hset emp:1 age 24 | 設定hash中age=23 |
hmset hmget hgetall | hmset emp:1 age 30 name kaka hmget emp:1 age name hgetall emp:1 | 設定hash多個值 擷取hash多個值 擷取hash所有值 |
hdel | hdel emp:1 age | 删除emp:1的age· |
hexists | hexists emp:1 name | 檢查是否存在 |
hlen | hlen emp:1 | 擷取指定長度 |
List - 清單類型
List清單就是一系列字元串的“數組”,按插入順序排序
List清單最大長度為2的32次方-1,可以包含40億個元素
List 指令
- rpush listkey c b a - 右側插入c,b,a
- lpush listkey f e d - 左側插入f,e,d
- rpop listkey - 右側彈出
- lpop listkey - 左側彈出
- lrange listkey 0 -1 輸出所有元素
Set - 集合類型
Set集合是字元串的無序集合,集合成員是唯一的
sadd set1 a 建立集合set1,放入a
sadd set1 b 放入b
sadd set2 b 建立集合set2,放入b
sadd set2 c 放入c
smembers set1 檢視set1内容
sinter set1 set2 交集
sunion set1 set2 并集
sdiff set1 set2 差集
Zset - 有序集合類型
Zset集合的字元串的有序集合,集合成員是唯一的
zadd zset1 100 a
zadd zset1 100 a
zrange zset1 0 -1 輸入指定範圍(所有)元素
輸入a,b
zadd zset1 99 c
zrange zset1 0 -1
輸出c,a,b
zrange zset1 0 -1 輸出所有元素和對應的分數(序号)
zrangebyscore zset1 100 103 輸入分數100-103的元素
Java用戶端 - Jedis
- Jedis是Java語言開發的Redis用戶端工具包
- Jedis隻是對Redis指令的封裝,掌握Redis指令便可輕易上手
環境準備
vim redis.conf
修改:
protected- mode no 關閉指定主機連接配接
#bind 127.0.0.1 将bind指定的本機ip注釋
注意這隻是開發測試,實際項目中還是要指定ip
啟動redis:
[[email protected] redis-6.2.5]# ./src/redis-server redis.conf
[[email protected] redis-6.2.5]# netstat -tulpn | grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 8761/./src/redis-se
tcp6 0 0 ::1:6379 ::😗 LISTEN 8761/./src/redis-se
可以看到redis已經啟動
将防火牆6379端口開放:
firewall-cmd --zone=public --add-port=6379/tcp --permanent
重新加載防火牆:
[[email protected] redis-6.2.5]# firewall-cmd --reload
找到伺服器ip位址:ifconfig
用戶端
redis.io官網找到redis用戶端
clients -> java
跳轉到github官網下載下傳:
https://github.com/redis/jedis
可以看到該項目也提供了Maven加載(2.9.0不是最新版,但是大多數項目使用的穩定版本)
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
連接配接測試:
Jedis操作各種資料類型
src/main/java/jedis/JedisTestor.java
package jedis;
import redis.clients.jedis.Jedis;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JedisTestor {
public static void main(String[] args) {
Jedis jedis = new Jedis("192.168.40.133", 6379);
try {
// jedis.auth("12345"); //密碼
System.out.println(jedis.ping());
jedis.select(2);
// Jedis操作字元串類型
jedis.set("sn", "7781-9938");
String sn = jedis.get("sn");
System.out.println(sn);
jedis.mset(new String[]{"title", "小餅幹", "num", "20"});
List<String> goods = jedis.mget(new String[]{"sn", "title", "num"});
System.out.println(goods);
Long num = jedis.incr("num");
System.out.println(num);
// Jedis操作Hash類型
jedis.hset("student:3312", "name", "小明");
String name = jedis.hget("student:3312", "name");
System.out.println(name);
Map<String, String> studentMap = new HashMap<>();
studentMap.put("name", "小李");
studentMap.put("age", "18");
studentMap.put("id", "3313");
jedis.hmset("student:3313", studentMap);
Map<String, String> smap = jedis.hgetAll("student:3313");
System.out.println(smap);
// Jedis操作List類型
jedis.del("letter");
jedis.rpush("letter", new String[]{"d", "e", "f"});
jedis.lpush("letter", new String[]{"c", "b", "a"});
List<String> letter = jedis.lrange("letter", 0, -1);
jedis.lpop("letter");
jedis.rpop("letter");
letter = jedis.lrange("letter", 0, -1);
System.out.println(letter);
} catch (Exception e) {
e.printStackTrace();
} finally {
jedis.close();
}
}
}
運作結果:
PONG
7781-9938
[7781-9938, 小餅幹, 20]
21
小明
{name=小李, age=18, id=3313}
[b, c, d, e]
利用Jedis緩存資料
pom.xml maven引入fastjson操作對象
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
Goods.java 商品類
package jedis;
public class Goods {
private Integer goodsId;
private String goodsName;
private String description;
private Float price;
public Goods(){}
public Goods(Integer goodsId, String goodsName, String description, Float price) {
this.goodsId = goodsId;
this.goodsName = goodsName;
this.description = description;
this.price = price;
}
public Integer getGoodsId() {
return goodsId;
}
public void setGoodsId(Integer goodsId) {
this.goodsId = goodsId;
}
public String getGoodsName() {
return goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
}
CacheSample.java 緩存資料類
package jedis;
import com.alibaba.fastjson.JSON;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CacheSample {
//通過構造函數将資料存入Redis
public CacheSample(){
Jedis jedis = new Jedis("192.168.40.133", 6379);
try {
List<Goods> goodsList = new ArrayList<Goods>();
goodsList.add(new Goods(1234, "蘋果", "描述資訊", 21f));
goodsList.add(new Goods(1235, "臍橙", "描述資訊", 80f));
goodsList.add(new Goods(1236, "香蕉", "描述資訊", 6f));
// jedis.auth("12345"); //資料庫密碼
jedis.select(3);
for (Goods goods : goodsList) {
//将對象轉為JSON字元串存入
String json = JSON.toJSONString(goods);
System.out.println(json);
String key = "goods:" + goods.getGoodsId();
jedis.set(key, json);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
jedis.close();
}
}
//提取資料
public static void main(String[] args) {
new CacheSample();
System.out.print("請輸入要查詢的商品編号: ");
String goodsId = new Scanner(System.in).next();
Jedis jedis = new Jedis("192.168.40.133", 6379);
try {
// jedis.auth("12345");
jedis.select(3);
String key = "goods:" + goodsId;
if (jedis.exists(key)) {
String json = jedis.get(key);
System.out.println(json);
Goods goods = JSON.parseObject(json, Goods.class);
System.out.println(goods.getGoodsId());
System.out.println(goods.getGoodsName());
System.out.println(goods.getDescription());
System.out.println(goods.getPrice());
}else{
System.out.println("您輸入的商品編号不存在!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
jedis.close();
}
}
}