1、Redis的簡單介紹
1)Redis 是一個開源(BSD許可)的,內存中的數據結構存儲系統,它可以用作數據庫、緩存和消息中間件。 它支持多種類型的數據結構,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 與范圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。 這些數據類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。Redis 內置了 復制(replication),LUA腳本(Lua scripting), LRU驅動事件(LRU eviction),事務(transactions) 和不同級別的 磁盤持久化(persistence), 并通過 Redis哨兵(Sentinel)和自動 分區(Cluster)提供高可用性(high availability)。Redis 是完全開源免費的,遵守BSD協議,是一個高性能的key-value數據庫。
2)Redis的內存管理機制:
在Redis中,并不是所有的數據都一直存儲在內存中的。當物理內存用完時,Redis可以將一些很久沒用到的value交換到磁盤。Redis只會緩存所有的key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據“swappability = age*log(size_in_memory)”計算出哪些key對應的value需要swap到磁盤。然后再將這些key對應的value持久化到磁盤中,同時在內存中清除。這種特性使得Redis可以保持超過其機器本身內存大小的數據。
3)Redis性能和集群管理:
Redis雖然支持數據的持久化,但是全內存畢竟才是其高性能的本質。作為基于內存的存儲系統來說,機器物理內存的大小就是系統能夠容納的最大數據量。如果需要處理的數據量超過了單臺機器的物理內存大小,就需要構建分布式集群來擴展存儲能力。Redis更偏向于在服務器端構建分布式存儲。
4)Redis 同其他 key - value 緩存數據庫比較具有以下
- Redis支持數據的持久化,可以將內存中的數據保存在磁盤中,重啟的時候可以再次加載進行使用。
- Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
- Redis支持數據的備份,即master-slave模式的數據備份。
5)Redis優勢
- .性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
- .豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。
- .原子 – Redis的所有操作都是原子性的,意思就是要么成功執行要么失敗完全不執行。單個操作是原子性的。多個操作也支持事務,即原子性,通過MULTI和EXEC指令包起來。
- .豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性。
- .Redis運行在內存中但是可以持久化到磁盤,所以在對不同數據集進行高速讀寫時需要權衡內存,因為數據量不能大于硬件內存。在內存數據庫方面的另一個優點是,相比在磁盤上相同的復雜的數據結構,在內存中操作起來非常簡單,這樣Redis可以做很多內部復雜性很強的事情。同時,在磁盤格式方面他們是緊湊的以追加的方式產生的,因為他們并不需要進行隨機訪問。
2、spring框架中接入redis的兩種方式:
步驟1:引入相關依賴
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
|
<!--使用jedis 需要引入 commons-pool 的依賴,否則Jedis會實例化失敗--> < dependency > < groupId >redis.clients</ groupId > < artifactId >jedis</ artifactId > < version >2.7.1</ version > </ dependency > < dependency > < groupId >commons-pool</ groupId > < artifactId >commons-pool</ artifactId > < version >1.5.6</ version > </ dependency > < dependency > < groupId >org.springframework.data</ groupId > < artifactId >spring-data-redis</ artifactId > < version >1.6.2.RELEASE</ version > </ dependency > <!-- redis中 如果存儲的是Map<String,Object>需要導入jackson相關的包,存儲的時候使用json序列化器存儲。如果不導入jackson的包會報錯。 --> < dependency > < groupId >com.fasterxml.jackson.core</ groupId > < artifactId >jackson-core</ artifactId > < version >2.5.1</ version > </ dependency > < dependency > < groupId >com.fasterxml.jackson.core</ groupId > < artifactId >jackson-databind</ artifactId > < version >2.5.1</ version > </ dependency > < dependency > < groupId >com.fasterxml.jackson.core</ groupId > < artifactId >jackson-annotations</ artifactId > < version >2.5.1</ version > </ dependency > |
步驟2:Redis相關屬性文件:redis.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#訪問地址 redis.host=127.0.0.1 #訪問端口 redis.port=6379 #注意,如果沒有password,此處不設置值,但這一項要保留 redis.password=@redisLearn #最大空閑數,數據庫連接的最大空閑時間。超過空閑時間,數據庫連接將被標記為不可用,然后被釋放。設為0表示無限制。 redis.maxIdle=300 #連接池的最大數據庫連接數。設為0表示無限制 redis.maxActive=600 #最大建立連接等待時間。如果超過此時間將接到異常。設為-1表示無限制。 redis.maxWait=1000 #在borrow一個jedis實例時,是否提前進行alidate操作;如果為true,則得到的jedis實例均是可用的; redis.testOnBorrow= true #客戶端連接超時時間 redis.timeout=30000 #可用數據庫數 redis.database = 0 |
步驟3:Spring中引入Redis配置、及調用實例(方式1和方式2選擇其中一種進行配置)
方式1:通過spring-data-redis工具實現對Redis的操作 spring-redis.xml
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
43
44
45
46
47
|
<? xml version = "1.0" encoding = "UTF-8" ?> < beans xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://www.springframework.org/schema/beans" xmlns:context = "http://www.springframework.org/schema/context" xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx = "http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd "> <!-- 連接池基本參數配置,類似數據庫連接池 --> < context:property-placeholder location = "classpath:conf/redis.properties" ignore-unresolvable = "true" /> <!-- redis連接池 --> < bean id = "poolConfig" class = "redis.clients.jedis.JedisPoolConfig" > < property name = "maxTotal" value = "${redis.maxActive}" /> < property name = "maxIdle" value = "${redis.maxIdle}" /> < property name = "testOnBorrow" value = "${redis.testOnBorrow}" /> </ bean > <!-- 連接池配置,類似數據庫連接池 --> < bean id = "jedisConnectionFactory" class = "org.springframework.data.redis.connection.jedis.JedisConnectionFactory" > < property name = "hostName" value = "${redis.host}" ></ property > < property name = "port" value = "${redis.port}" ></ property > <!-- <property name="password" value="${redis總結.pass}"></property> --> < property name = "poolConfig" ref = "poolConfig" ></ property > </ bean > <!--redis操作模版,使用該對象可以操作redis --> < bean id = "redisTemplate" class = "org.springframework.data.redis.core.RedisTemplate" > < property name = "connectionFactory" ref = "jedisConnectionFactory" /> <!--如果不配置Serializer,那么存儲的時候缺省使用String,如果用User類型存儲,那么會提示錯誤User can't cast to String!! --> < property name = "keySerializer" > < bean class = "org.springframework.data.redis.serializer.StringRedisSerializer" /> </ property > < property name = "valueSerializer" > < bean class = "org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" /> </ property > < property name = "hashKeySerializer" > < bean class = "org.springframework.data.redis.serializer.StringRedisSerializer" /> </ property > < property name = "hashValueSerializer" > < bean class = "org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" /> </ property > <!--開啟事務 --> < property name = "enableTransactionSupport" value = "true" ></ property > </ bean > </ beans > |
方式2:通過jedis客戶端工具實現對Redis的操作 spring-jedis.xml
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
|
<? xml version = "1.0" encoding = "UTF-8" ?> < beans xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://www.springframework.org/schema/beans" xmlns:context = "http://www.springframework.org/schema/context" xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx = "http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd "> <!-- 連接池基本參數配置,類似數據庫連接池 --> < context:property-placeholder location = "classpath:conf/redis.properties" ignore-unresolvable = "true" /> <!-- redis連接池 --> < bean id = "poolConfig" class = "redis.clients.jedis.JedisPoolConfig" > < property name = "maxTotal" value = "${redis.maxActive}" /> < property name = "maxIdle" value = "${redis.maxIdle}" /> < property name = "testOnBorrow" value = "${redis.testOnBorrow}" /> </ bean > < bean id = "jedisPool" class = "redis.clients.jedis.JedisPool" > < constructor-arg name = "poolConfig" ref = "poolConfig" /> < constructor-arg name = "host" value = "${redis.host}" /> < constructor-arg name = "port" value = "${redis.port}" type = "int" /> < constructor-arg name = "timeout" value = "${redis.timeout}" type = "int" /> < constructor-arg name = "password" value = "${redis.password}" /> < constructor-arg name = "database" value = "${redis.database}" type = "int" /> </ bean > </ beans > |
步驟4:在web.xml中進行 進行 servletContext上下文讀取
1
2
3
4
5
6
7
|
< context-param > < param-name >contextConfigLocation</ param-name > < param-value > <!--classpath:spring/spring-redis.xml,--> classpath:spring/spring-jedis.xml, </ param-value > </ context-param > |
步驟5:接入測試
方式1:測試代碼
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
@Controller @RequestMapping ( "/redis" ) public class RedisController { @Resource (name= "redisTemplate" ) private RedisTemplate redisTemplate; @RequestMapping ( "/operate.do" ) @ResponseBody public Map springRedisDo() { Map result= new HashMap(); // stringRedisTemplate的操作 // String讀寫 redisTemplate.delete( "myStrKey" ); redisTemplate.opsForValue().set( "myStrKey" , "strValue" ); String strValue= (String) redisTemplate.opsForValue().get( "myStrKey" ); result.put( "strValue" ,strValue); // List讀寫 redisTemplate.delete( "myListKey" ); redisTemplate.opsForList().rightPush( "myListKey" , "listValue1" ); redisTemplate.opsForList().rightPush( "myListKey" , "listValue2" ); redisTemplate.opsForList().leftPush( "myListKey" , "listValue3" ); List<String> myListKeyValues = redisTemplate.opsForList().range( "myListKey" , 0 , - 1 ); for (String s : myListKeyValues) { System.out.println( "myListKey數據元素>>>" +s); } result.put( "myListKeyValues" ,myListKeyValues); // Set讀寫 redisTemplate.delete( "mySet" ); redisTemplate.opsForSet().add( "mySetKey" , "setValue1" ); redisTemplate.opsForSet().add( "mySetKey" , "setValue2" ); redisTemplate.opsForSet().add( "mySetKey" , "setValue3" ); redisTemplate.opsForSet().add( "mySetKey" , "setValue3" ); redisTemplate.opsForSet().add( "mySetKey" , "setValue3" ); Set<String> setValues = redisTemplate.opsForSet().members( "mySetKey" ); for (String s : setValues) { System.out.println( "mySetKey數據元素>>>" +s); } result.put( "setValues" ,setValues); // Hash讀寫 redisTemplate.delete( "myHashKey" ); redisTemplate.opsForHash().put( "myHashKey" , "BJ" , "北京" ); redisTemplate.opsForHash().put( "myHashKey" , "SH" , "上海" ); redisTemplate.opsForHash().put( "myHashKey" , "TJ" , "天津" ); Map<String, String> hashValues = redisTemplate.opsForHash().entries( "myHashKey" ); List myHashList= redisTemplate.opsForHash().values( "myHashKey" ); System.out.println( "myHashList數據信息>>>" +myHashList); for (Map.Entry entry : hashValues.entrySet()) { System.out.println( "myHashValues>>>" +entry.getKey() + " - " + entry.getValue()); } result.put( "hashValues" ,hashValues); return result; } } |
spring 封裝了 RedisTemplate 對象來進行對redis的各種操作,它支持所有的 redis 原生的 api。在RedisTemplate中提供了幾個常用的接口方法的使用,分別是:
RedisTemplate中定義了對5種數據結構操作
- redisTemplate.opsForValue();//操作字符串
- redisTemplate.opsForHash();//操作hash
- redisTemplate.opsForList();//操作list
- redisTemplate.opsForSet();//操作set
- redisTemplate.opsForZSet();//操作有序set
注:StringRedisTemplate與 RedisTemplate關系
StringRedisTemplate繼承RedisTemplate,兩者的數據是不共通的;也就是說StringRedisTemplate只能管理StringRedisTemplate里面的數據,RedisTemplate只能管理RedisTemplate中的數據。SDR默認采用的序列化策略有兩種,一種是String的序列化策略,一種是JDK的序列化策略。StringRedisTemplate默認采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。RedisTemplate默認采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
方式2:測試代碼
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
43
44
45
46
47
48
49
50
51
52
53
|
@Controller @RequestMapping ( "/jedis/" ) public class JedisController { @Autowired private JedisPool jedisPool; /** * @Method: * @Author: * @Description: * param: 通過jedis客戶端,往Redis中 存入數據 * @Return: * @Exception: * @Date: 2020/9/10 10:38 */ @RequestMapping ( "save" ) @ResponseBody public Map getSave(String key, String val) { Map result= new HashMap(); boolean executeResult= false ; Jedis jedis = null ; try { jedis = jedisPool.getResource(); jedis.set(key, val); executeResult= true ; } catch (Exception e) { System.out.println( "獲取jedis鏈接異常" +e); } result.put( "executeResult" ,executeResult); return result; } /** * @Method: * @Author: * @Description: * param: 查詢Redis中存儲的信息 * @Return: * @Exception: * @Date: 2020/9/10 10:40 */ @RequestMapping ( "queryKeyInfo.do" ) @ResponseBody public Map getKey(String key) { Map result= new HashMap(); Jedis jedis = jedisPool.getResource(); String redisValue=jedis.get(key); result.put( "key" ,redisValue); return result; } } |
通過redis.clients.jedis.JedisPool來管理,即通過池來管理,通過池對象獲取jedis實例,然后通過jedis實例直接操作redis服務,剔除了與業務無關的冗余代碼,從工廠類到池的方式變化,就相當于mybatis連接mysql方變化是一樣的,代碼變得更簡潔,維護也更容易了。Jedis使用apache commons-pool2對Jedis資源池進行管理,所以在定義JedisPool時一個很重要的參數就是資源池GenericObjectPoolConfig
注:使用JedisPool 的方式進行redis操作時候,需要設置redis服務的登錄密碼,否則會有相應的錯誤提示。redis.windows.conf 文件中 通過修改requirepass 信息來進行redis服務訪問密碼設置,并通過redis-server.exe redis.windows.conf 命令方式進行訪問,否則會報錯:redis.clients.jedis.exceptions.JedisDataException: ERR Client sent AUTH, but no password is set
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://www.cnblogs.com/jiarui-zjb/p/13645858.html