1、redis定義
Redis 是完全開源免費(fèi)的摹蘑,遵守BSD協(xié)議舀透,是一個(gè)高性能的key-value數(shù)據(jù)庫。
Redis 三特點(diǎn):
- 支持?jǐn)?shù)據(jù)的持久化密任,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤中颜启,重啟的時(shí)候可以再次加載進(jìn)行使用。
- 支持簡單的key-value類型的數(shù)據(jù)批什,同時(shí)還提供list农曲,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲乳规。
- 支持?jǐn)?shù)據(jù)的備份形葬,即master-slave模式的數(shù)據(jù)備份。
概述
此文檔介紹Redis數(shù)據(jù)庫與spring boot集成暮的。
Redis簡介
- Redis是一個(gè)高性能的key-value數(shù)據(jù)庫笙以。
- Redis是由C語言編寫,是完全開源免費(fèi)的冻辩。
- Redis性能極高猖腕,一般情況下,Redis能讀的速度是110000次/s恨闪,寫的速度是81000次/s倘感。
- Redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存到磁盤上咙咽,也可以將磁盤上的數(shù)據(jù)讀取到內(nèi)存中老玛。
- Redis支持豐富的數(shù)據(jù)類型:String(字符串)、List(列表)钧敞、Hash(哈希)蜡豹、Set(集合)、Zset(sorted set:有序集合)溉苛。
- Redis的所有操作都是原子性的镜廉,要么全部成功,要么全部失敗愚战。
- Redis官網(wǎng)地址:https://redis.io/
Redis背景
在互聯(lián)網(wǎng)項(xiàng)目中往往存在大數(shù)據(jù)量的需求娇唯,比如一些商品搶購的場景,或是訪問量瞬間較大的時(shí)候凤巨,一瞬間成千上萬的請求就會到來视乐。這就需要在短時(shí)間內(nèi)完成成千上萬次讀或者寫的操作,對于傳統(tǒng)數(shù)據(jù)庫來說敢茁,容易使系統(tǒng)宕機(jī),所以這時(shí)候NoSQL的出現(xiàn)改變了這個(gè)現(xiàn)狀留美,Redis就是NoSQL中的一種彰檬。Redis具有以下特性:
- Redis以內(nèi)存作為數(shù)據(jù)存儲介質(zhì),讀寫數(shù)據(jù)的效率極高谎砾。
- 儲存在Redis中的數(shù)據(jù)是持久化的逢倍,斷電或重啟,數(shù)據(jù)也不會丟失景图。
- Redis的存儲分為內(nèi)存存儲较雕、磁盤存儲和log文件。
- Redis可以從磁盤重新將數(shù)據(jù)加載到內(nèi)存中,也可以通過配置文件對其進(jìn)行配置亮蒋。
- Redis支持主從模式扣典,可以配置集群,更利于支撐大型的項(xiàng)目慎玖。
Redis數(shù)據(jù)庫的連接工具
查看Redis數(shù)據(jù)庫可以采用Redis Desktop軟件贮尖,下載地址是:https://redisdesktop.com/download
連接過程如下圖:
Redis數(shù)據(jù)庫結(jié)構(gòu)介紹如下圖:
Redis的設(shè)計(jì)核心
5.1 Redis的純內(nèi)存操作
Redis緩存數(shù)據(jù)存放在內(nèi)存中,內(nèi)存的響應(yīng)時(shí)間一般情況下大約是100納秒趁怔,這是Redis每秒萬億級別訪問的重要基礎(chǔ)湿硝。
5.2 Redis的單線程機(jī)制
Redis采用單線程,避免了不必要的上下文切換和競爭條件润努。
單線程指的是網(wǎng)絡(luò)請求模塊使用了一個(gè)線程(所以不需考慮并發(fā)安全性)关斜,即一個(gè)線程處理所有網(wǎng)絡(luò)請求。因?yàn)镽edis的性能瓶頸在內(nèi)存的大小和網(wǎng)絡(luò)的帶寬铺浇。Redis數(shù)據(jù)存儲在內(nèi)存痢畜,不涉及I/O操作,因此單線程是最快的随抠。
5.3 Redis采用非阻塞I/O多路復(fù)用機(jī)制
多路I/O復(fù)用模型是利用select裁着、poll、epoll可以同時(shí)監(jiān)察多個(gè)流的I/O事件的能力拱她,在空閑的時(shí)候二驰,會把當(dāng)前線程阻塞掉,當(dāng)有一個(gè)或多個(gè)流有I/O事件時(shí)秉沼,就從阻塞態(tài)中喚醒桶雀,于是程序就會輪詢一遍所有的流(epoll是只輪詢那些真正發(fā)出了事件的流),并且只依次順序的處理就緒的流唬复,這種做法就避免了大量的無用操作矗积。這里"多路"指的是多個(gè)網(wǎng)絡(luò)連接,"復(fù)用"指的是復(fù)用同一個(gè)線程敞咧。加上Redis自身的事件處理模型將epoll中的連接棘捣,讀寫,關(guān)閉都轉(zhuǎn)換為了事件休建,不在I/O上浪費(fèi)過多的時(shí)間乍恐。
Redis的應(yīng)用場景
- 緩存(數(shù)據(jù)查詢、短連接测砂、新聞內(nèi)容茵烈、商品內(nèi)容等)
- 聊天室的在線好友列表
- 任務(wù)隊(duì)列(秒殺、搶購砌些、12306等)
- 應(yīng)用排行榜
- 網(wǎng)站訪問統(tǒng)計(jì)
- 數(shù)據(jù)過期處理(可以精確到毫秒)
- 分布式集群架構(gòu)中的session分離(單點(diǎn)登錄)
Redis支持的數(shù)據(jù)結(jié)構(gòu)及常用命令
Redis支持String(字符串)呜投、List(列表)、Hash(哈希)、Set(集合)仑荐、Zset(sorted set:有序集合)五種數(shù)據(jù)結(jié)構(gòu)雕拼。
7.1 string(字符串)
- 賦值:set key value
- 取值:get key
- 查詢所有的鍵:keys *
- 自增長:incr key
- 自減:decr key
- 刪除鍵:del key
- 增加指定的值:incrby key num
- 拼接字符串:append key value
7.2 hash(哈希)
- 賦值:hset hash field value
- 取值:hget hash field
- 查詢hash中所有的鍵:hkeys hash
- 查詢hash中所有的值:hvals hash
- 查詢hash中的鍵和值:hgetall hash
- 刪除hash中的鍵:hdel hash field
7.3 list(列表)
List允許值重復(fù),有序释漆。
- 從左添加:lpush list val1 val2 val3
- 從右添加:rpush list val1 val2 val3
- 查看:lrange list 0 -1 (0表示開始索引悲没,-1表示查詢到最后。)
- 從左取值:lpop list (注意:取出之后男图,list中就沒有這個(gè)值了示姿。)
- 從右取值:rpop list (注意:取出之后,list中就沒有這個(gè)值了逊笆。)
- 查看list中元素個(gè)數(shù):llen list
7.4 set(集合)
Set不允許值重復(fù)栈戳,無序。
- 添加:sadd set val1 val2 val3
- 查看:smembers set
- 刪除:srem set val1
- 差集:sdiff set1 set2
- 交集:sinter set1 set2
- 并集:sunion set1 set2
7.5 SortedSet(zset有序集合)
有序难裆,不能重復(fù)子檀。
- 添加:zadd zset num1 val1 num2 val2 (第一個(gè)數(shù)為值的排序比重,越大越靠后乃戈。)
- 查看:zrange zset 0 -1
- 刪除:zrem zset val1
Redis在項(xiàng)目中的使用
8.1 項(xiàng)目框架介紹
項(xiàng)目依賴的JDK版本:1.8
依賴說明:
|
groupId
|
artifactId
|
版本
|
說明
|
|
org.springframework.boot
|
spring-boot-starter-parent
|
2.1.7.RELEASE
|
項(xiàng)目框架springboot版本
|
|
org.springframework.boot
|
spring-data-redis
|
2.1.7.RELEASE
|
SpringBoot整合Redis驅(qū)動
|
|
redis.clients
|
jedis
|
2.9.3
|
Redis連接池依賴版本
|
8.2 配置Redis的地址
在application-prod.yml文件中配置Redis的地址信息褂痰。
[圖片上傳失敗...(image-90b850-1590482730108)]
8.3 RedisCacheConfig類
說明:RedisCacheConfig類是實(shí)現(xiàn)Redis數(shù)據(jù)庫的連接方法,該類從application-prod.yml文件中獲取Redis數(shù)據(jù)庫的連接地址症虑。
加了@Bean注解缩歪,在項(xiàng)目啟動的時(shí)候就會自動創(chuàng)建redisTemplate。
[圖片上傳失敗...(image-e1c4b4-1590482730108)]
[圖片上傳失敗...(image-fb06b4-1590482730108)]
在spring容器中創(chuàng)建的名為redisTemplate的Redis數(shù)據(jù)庫操作對象谍憔,在使用時(shí)可通過Autowired注入匪蝙。
[圖片上傳失敗...(image-57bd1-1590482730108)]
8.4 RedisBaseUtil類
說明:此類的Redis數(shù)據(jù)庫的操作工具。 习贫。
方法說明(包含常用的查詢處理逛球,不足的可以自行添加或自定義類):
(1)expire:輸入鍵和時(shí)間,設(shè)置緩存的失效時(shí)間苫昌;
(2)getExpire:根據(jù)鍵颤绕,獲得緩存失效的時(shí)間;
(3)hasKey:判斷key是否存在祟身;
(4)del:根據(jù)鍵屋厘,刪除緩存,可傳入多個(gè)key月而;
(5)get、set议纯、incr父款、decr:string數(shù)據(jù)結(jié)構(gòu)類型的查看、添加、自增憨攒、自減世杀;
(6)hget、hset肝集、hmget瞻坝、hmset、hdel杏瞻、hHasKey所刀、hincr、hdecr:hash數(shù)據(jù)類型的查看捞挥、添加浮创、查詢所有的key、批量添加砌函、刪除斩披、判斷key是否存在、自增讹俊、自減垦沉;
(7)sGet、sHasKey仍劈、sSet厕倍、sGetSetSize、setRemove耳奕、:set數(shù)據(jù)類型的查看绑青、判斷key是否存在、添加屋群、獲取set集合的長度闸婴、刪除;
(8)lGet芍躏、lGetListSize邪乍、lGetIndex、lSet对竣、lUpdateIndex庇楞、lRemove:list數(shù)據(jù)類型的查看、獲得list列表的長度否纬、根據(jù)索引獲得list列表的值吕晌、根據(jù)索引更新list列表的值、刪除临燃。
展開源碼
8.5 RedisRequestDto類
說明:該類用來處理客戶端發(fā)來的請求參數(shù)睛驳,可以根據(jù)需要自己定義或重寫類烙心。
[圖片上傳失敗...(image-687681-1590482730108)]
Redis使用代碼示例
對于一些訪問比較頻繁的,但數(shù)據(jù)又不經(jīng)常變化查詢乏沸,可以將數(shù)據(jù)放到Redis緩存中淫茵。查詢的時(shí)候先去判斷緩存中是否存在,緩存中有則直接查詢蹬跃,緩存中沒有則去查數(shù)據(jù)庫匙瘪,并將查詢的結(jié)果放到緩存中,減輕服務(wù)器的壓力蝶缀。
9.1 啟動項(xiàng)目丹喻,訪問swagger頁面。
使用開發(fā)工具導(dǎo)入項(xiàng)目后扼劈,啟動項(xiàng)目驻啤。url:http://ip:port/dCustomService/docs.html
參數(shù)key為必填項(xiàng),是要查詢的緩存的鍵荐吵。
[圖片上傳失敗...(image-7dc881-1590482730108)]
9.2 controller層實(shí)現(xiàn)
DemoRedisApiCotroller類接收客戶端發(fā)來的請求骑冗,交由service層進(jìn)行處理。
折疊源碼
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
package
[com.hikvision.idatafusion.dcustom.api.controller.demo;](http://bb.corp.hzcominfo.com:8090/pages/com.hikvision.idatafusion.dcustom.api.controller.demo;)
import
[com.hikvision.idatafusion.dcustom.base.common.BaseController;](http://bb.corp.hzcominfo.com:8090/pages/com.hikvision.idatafusion.dcustom.base.common.BaseController;)
import
[com.hikvision.idatafusion.dcustom.base.common.bean.response.CommonResponse;](http://bb.corp.hzcominfo.com:8090/pages/com.hikvision.idatafusion.dcustom.base.common.bean.response.CommonResponse;)
import
[com.hikvision.idatafusion.dcustom.base.constants.Constants;](http://bb.corp.hzcominfo.com:8090/pages/com.hikvision.idatafusion.dcustom.base.constants.Constants;)
import
[com.hikvision.idatafusion.dcustom.datasource.common.bean.dto.atomic.RedisRequestDto;](http://bb.corp.hzcominfo.com:8090/pages/com.hikvision.idatafusion.dcustom.datasource.common.bean.dto.atomic.RedisRequestDto;)
import
[com.hikvision.idatafusion.dcustom.datasource.service.RedisService;](http://bb.corp.hzcominfo.com:8090/pages/com.hikvision.idatafusion.dcustom.datasource.service.RedisService;)
import
[io.swagger.annotations.Api;](http://bb.corp.hzcominfo.com:8090/pages/io.swagger.annotations.Api;)
import
[io.swagger.annotations.ApiOperation;](http://bb.corp.hzcominfo.com:8090/pages/io.swagger.annotations.ApiOperation;)
import
[org.springframework.beans.factory.annotation.Autowired;](http://bb.corp.hzcominfo.com:8090/pages/org.springframework.beans.factory.annotation.Autowired;)
import
[org.springframework.web.bind.annotation.PostMapping;](http://bb.corp.hzcominfo.com:8090/pages/org.springframework.web.bind.annotation.PostMapping;)
import
[javax.validation.Valid;](http://bb.corp.hzcominfo.com:8090/pages/javax.validation.Valid;)
/**
*
*/
@Api``(tags = {``"demo-Redis"``})
public
class
DemoRedisApiCotroller ``extends
BaseController {
@Autowired
private
RedisService redisService;
@ApiOperation``(``"Redis新增數(shù)據(jù)"``)
@PostMapping``(``"/v3/api/insertRedis"``)
public
CommonResponse insertRedis(``@Valid
RedisRequestDto redisRequestDto){
return
success([Constants.SUCCESS,redisService.insertRedis(redisRequestDto));](http://bb.corp.hzcominfo.com:8090/pages/Constants.SUCCESS,redisService.insertRedis(redisRequestDto));)
}
@ApiOperation``(``"Redis修改數(shù)據(jù)"``)
@PostMapping``(``"/v3/api/updateRedis"``)
public
CommonResponse updateRedis(``@Valid
RedisRequestDto redisRequestDto){
return
success([Constants.SUCCESS,redisService.updateRedis(redisRequestDto));](http://bb.corp.hzcominfo.com:8090/pages/Constants.SUCCESS,redisService.updateRedis(redisRequestDto));)
}
@ApiOperation``(``"Redis查詢數(shù)據(jù)"``)
@PostMapping``(``"/v3/api/findRedis"``)
public
CommonResponse findRedis(``@Valid
RedisRequestDto redisRequestDto){
return
success([Constants.SUCCESS,redisService.findRedis(redisRequestDto));](http://bb.corp.hzcominfo.com:8090/pages/Constants.SUCCESS,redisService.findRedis(redisRequestDto));)
}
@ApiOperation``(``"Redis刪除數(shù)據(jù)"``)
@PostMapping``(``"/v3/api/deleteRedis"``)
public
CommonResponse deleteRedis(``@Valid
RedisRequestDto redisRequestDto){
return
success([Constants.SUCCESS,redisService.deleteRedis(redisRequestDto));](http://bb.corp.hzcominfo.com:8090/pages/Constants.SUCCESS,redisService.deleteRedis(redisRequestDto));)
}
}
|
9.3 serviceImpl層實(shí)現(xiàn)
RedisServiceImpl接收controller層傳遞過來的請求先煎,采用RedisBaseUtil類進(jìn)行處理贼涩。
展開源碼
9.4 測試
以string數(shù)據(jù)結(jié)構(gòu)類型為例,測試Redis緩存的使用方法
(1)往Redis緩存中添加數(shù)據(jù)
[圖片上傳失敗...(image-12f564-1590482730108)]
通過Redis Desktop查看Redis緩存中的數(shù)據(jù)薯蝎,與新添加的value值一致遥倦。
[圖片上傳失敗...(image-9f6aaa-1590482730108)]
(2)從Redis緩存中查詢數(shù)據(jù)
[圖片上傳失敗...(image-d6efff-1590482730108)]
(3)修改Redis緩存中的數(shù)據(jù)
[圖片上傳失敗...(image-9c994a-1590482730108)]
通過Redis Desktop查看Redis緩存中的數(shù)據(jù),與新修改的value值一致占锯。
[圖片上傳失敗...(image-7fb402-1590482730108)]
(4)刪除Redis緩存中的數(shù)據(jù)
[圖片上傳失敗...(image-b35fb7-1590482730108)]
通過Redis Desktop查看Redis緩存中的數(shù)據(jù)袒哥。
[圖片上傳失敗...(image-d49c06-1590482730108)]