返回知足給定pattern的全部key
示例:
127.0.0.1:6379> keys *
1) "zset1"
2) "list:1"
3) "s1"
4) "s2"
5) "newlist"
6) "s3"
7) "set2"
8) "set1"
確認一個key是否存在
從示例結果來看,數據庫中不存在HongWan這個key,可是age這個key是存在的
示例:
127.0.0.1:6379> exists set8
(integer) 0
127.0.0.1:6379> exists set1
(integer) 1
刪除一個key
示例:
127.0.0.1:6379> del s3
(integer) 1
127.0.0.1:6379> exists set3
(integer) 0
127.0.0.1:6379>
重命名key
從示例結果來看,s1成功的被咱們更名爲s1_new了。
示例:
127.0.0.1:6379> keys *
1) "zset1"
2) "list:1"
3) "s1"
4) "s2"
5) "newlist"
6) "set2"
7) "set1"
127.0.0.1:6379> rename s1 s1_new
OK
127.0.0.1:6379> keys *
1) "zset1"
2) "list:1"
3) "s2"
4) "newlist"
5) "set2"
6) "s1_new"
7) "set1"
返回值的類型
從示例結果來看,這個方法能夠很是簡單的判斷出值的類型。
示例:
127.0.0.1:6379> keys *
1) "zset1"
2) "list:1"
3) "s2"
4) "newlist"
5) "set2"
6) "s1_new"
7) "set1"
127.0.0.1:6379> type s2
string
127.0.0.1:6379> type set1
set
127.0.0.1:6379> type zset1
zset
127.0.0.1:6379> type list:1
list
EXPIRE key seconds 設置key的生存時間(單位:秒)key在多少秒後會自動刪除
TTL key 查看key生於的生存時間
PERSIST key 清除生存時間
PEXPIRE key milliseconds 生存時間設置單位爲:毫秒
示例:
127.0.0.1:6379> keys *
1) "zset1"
2) "list:1"
3) "s2"
4) "newlist"
5) "set2"
6) "s1_new"
7) "set1"
127.0.0.1:6379> expire s2 10 設置s2的生存時間爲10秒
(integer) 1
127.0.0.1:6379> ttl s2 查看s2的生於生成時間還有4秒刪除
(integer) 4
127.0.0.1:6379> ttl s2
(integer) -2
127.0.0.1:6379> get s2 獲取s2的值,已經刪除
(nil)
RDB方式的持久化是經過
快照(snapshotting)
完成的,當符合必定條件
時Redis會自動將內存中的數據進行快照並持久化到硬盤
。
RDB是Redis默認
採用的持久化方式。javascript
在redis.conf中修改持久化快照的條件,以下圖:css
save 開頭的一行就是持久化配置,能夠配置多個條件(每行配置一個條件),每一個條件之間是「或」的關係。
save 900 1 表示15分鐘(900秒)內至少1個鍵被更改則進行快照。
save 300 10 表示5分鐘(300秒)內至少10個鍵被更改則進行快照。
save 60 10000 表示1分鐘(60秒)內至少10000個鍵被更改則進行快照。
在redis.conf中能夠指定持久化文件存儲的目錄,以下圖:java
dbfilename dump.rdb 表示設置而快照文件(持久化文件)存儲的名稱爲:dump.rdb
dir ./ 表示設置而快照文件(持久化文件)存儲的目錄爲:在當前目錄下
Redis啓動後會讀取RDB快照文件,將數據從硬盤載入到內存。根據數據量大小與結構和服務器性能不一樣,這個時間也不一樣。
一般將記錄一千萬個字符串類型鍵、大小爲1GB的快照文件載入到內存中須要花費20~30秒鐘。
經過RDB方式實現持久化,一旦Redis異常退出(非法關閉),就會丟失最後一次快照之後更改的全部數據。這就須要開發者根據具體的應用場合,經過組合設置自動快照條件的方式來將可能發生的數據損失控制在可以接受的範圍。
若是數據很重要以致於沒法承受任何損失,則能夠考慮使用AOF方式進行持久化。
即:一旦redis非法關閉,那麼會丟失最後一次持久化以後的數據。
若是數據不重要,則沒必要要關心。
若是數據不能容許丟失,那麼要使用AOF方式。node
詳解以下:linux
默認狀況下Redis沒有開啓AOF(append only file)方式的持久化。
能夠經過修改redis.conf配置文件中的appendonly參數開啓,以下:
appendonly yes
開啓AOF持久化後每執行一條會更改Redis中的數據的命令,Redis就會將該命令寫入硬盤中的AOF文件。
AOF文件的保存位置和RDB文件的位置相同,都是經過dir參數設置的。
dir ./
默認的文件名是appendonly.aof,能夠經過appendfilename參數修改:
appendfilename appendonly.aof
在同時使用aof和rdb方式時,若是redis重啓,則數據從aof文件加載。
硬盤損壞
了可能會致使數據丟失,若是經過redis的主從複製機制就能夠避免這種單點故障
,以下圖所示:架構細節:
(1) 全部的redis節點彼此互聯(`PING-PONG機制`),內部使用`二進制協議`優化傳輸速度和帶寬。
(2) 節點的fail(失敗)是經過集羣中`超過半數的節點檢測失效`時才生效。即`集羣搭建中主機的個數爲奇數`。
(3) 客戶端與redis節點直連,不須要中間proxy層,客戶端不須要鏈接集羣全部節點,鏈接集羣中任何一個可用節點便可。
(4) redis-cluster把全部的物理節點映射到[0-16383]slot(槽)上,cluster負責維護node<-->slot<-->value
Redis 集羣中內置了 `16384 個哈希槽`,當須要在 Redis 集羣中放置一個 key-value 時,redis 先對 key 使用 crc16 算法算出一個結果,而後把結果`對 16384 求餘數`,這樣每一個 key 都會對應一個編號在 0-16383 之間的哈希槽,redis 會根據節點數量`大體均等`的將哈希槽映射到不一樣的節點。
示例以下:nginx
(1) 集羣中全部master參與投票,若是半數以上master節點與其中一個master節點通訊超過(cluster-node-timeout),認爲該master節點掛掉。
(2) 何時整個集羣不可用(cluster_state:fail)?
一、若是集羣任意master掛掉,且當前master沒有slave,則集羣進入fail狀態。也能夠理解成集羣的[0-16383]slot映射不徹底時進入fail狀態。
二、若是集羣超過半數以上master掛掉,不管是否有slave,集羣進入fail狀態。
redis-trib.rb
依賴ruby環境
,首先須要安裝ruby環境。redis-trib.rb
拷貝到/user/local/redis/redis-cluster 目錄下(注意:先在/user/local/redis/目錄下建立目錄redis-cluster)[root@itheima redis-cluster]# ./redis-trib.rb create --replicas 1 192.168.5.128:7001 192.168.5.128:7002 192.168.5.128:7003 192.168.5.128:7004 192.168.5.128:7005 192.168.5.128:7006
>>> Creating cluster
Connecting to node 192.168.5.128:7001: OK
Connecting to node 192.168.5.128:7002: OK
Connecting to node 192.168.5.128:7003: OK
Connecting to node 192.168.5.128:7004: OK
Connecting to node 192.168.5.128:7005: OK
Connecting to node 192.168.5.128:7006: OK
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.5.128:7001
192.168.5.128:7002
192.168.5.128:7003
Adding replica 192.168.5.128:7004 to 192.168.5.128:7001
Adding replica 192.168.5.128:7005 to 192.168.5.128:7002
Adding replica 192.168.5.128:7006 to 192.168.5.128:7003
M: 3cbed89c47ca14b3d1eb11dd2f7525fa6cb4fcd7 192.168.5.128:7001
slots:0-5460 (5461 slots) master
M: 27d069e1b4d459a92b6cc9a1c92ad46ea00cb61d 192.168.5.128:7002
slots:5461-10922 (5462 slots) master
M: d7d28caadfdc4161261305f2d2baf55d2d8f4221 192.168.5.128:7003
slots:10923-16383 (5461 slots) master
S: f124b72c0421c7514f44668d30761d075e42643d 192.168.5.128:7004
replicates 3cbed89c47ca14b3d1eb11dd2f7525fa6cb4fcd7
S: 8cf60c085a58b60557a887a5e8451ce38e6b54fa 192.168.5.128:7005
replicates 27d069e1b4d459a92b6cc9a1c92ad46ea00cb61d
S: 05ad0eb9b5f839771b09dc18192909d5fa1f893e 192.168.5.128:7006
replicates d7d28caadfdc4161261305f2d2baf55d2d8f4221
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join......
>>> Performing Cluster Check (using node 192.168.5.128:7001)
M: 3cbed89c47ca14b3d1eb11dd2f7525fa6cb4fcd7 192.168.5.128:7001
slots:0-5460 (5461 slots) master
M: 27d069e1b4d459a92b6cc9a1c92ad46ea00cb61d 192.168.5.128:7002
slots:5461-10922 (5462 slots) master
M: d7d28caadfdc4161261305f2d2baf55d2d8f4221 192.168.5.128:7003
slots:10923-16383 (5461 slots) master
M: f124b72c0421c7514f44668d30761d075e42643d 192.168.5.128:7004
slots: (0 slots) master
replicates 3cbed89c47ca14b3d1eb11dd2f7525fa6cb4fcd7
M: 8cf60c085a58b60557a887a5e8451ce38e6b54fa 192.168.5.128:7005
slots: (0 slots) master
replicates 27d069e1b4d459a92b6cc9a1c92ad46ea00cb61d
M: 05ad0eb9b5f839771b09dc18192909d5fa1f893e 192.168.5.128:7006
slots: (0 slots) master
replicates d7d28caadfdc4161261305f2d2baf55d2d8f4221
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@itheima redis-cluster]#
[root@itheima 7001]# ./redis-cli -h 192.168.5.128 -p 7001 –c
-c:指定是集羣鏈接redis
192.168.5.128:7002> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:2
cluster_stats_messages_sent:1837
cluster_stats_messages_received:1837
192.168.5.128:7002>
192.168.5.128:7002> cluster nodes
d7d28caadfdc4161261305f2d2baf55d2d8f4221 192.168.5.128:7003 master - 0 1541263366376 3 connected 10923-16383
f124b72c0421c7514f44668d30761d075e42643d 192.168.5.128:7004 slave 3cbed89c47ca14b3d1eb11dd2f7525fa6cb4fcd7 0 1541263372425 4 connected
05ad0eb9b5f839771b09dc18192909d5fa1f893e 192.168.5.128:7006 slave d7d28caadfdc4161261305f2d2baf55d2d8f4221 0 1541263371417 6 connected
3cbed89c47ca14b3d1eb11dd2f7525fa6cb4fcd7 192.168.5.128:7001 master - 0 1541263370402 1 connected 0-5460
8cf60c085a58b60557a887a5e8451ce38e6b54fa 192.168.5.128:7005 slave 27d069e1b4d459a92b6cc9a1c92ad46ea00cb61d 0 1541263369396 5 connected
27d069e1b4d459a92b6cc9a1c92ad46ea00cb61d 192.168.5.128:7002 myself,master - 0 0 2 connected 5461-10922
192.168.5.128:7002>
[root@itheima redis-cluster]# ./redis-trib.rb add-node 192.168.5.128:7007 192.168.5.128:7001
>>> Adding node 192.168.5.128:7007 to cluster 192.168.5.128:7001
Connecting to node 192.168.5.128:7001: OK
Connecting to node 192.168.5.128:7006: OK
Connecting to node 192.168.5.128:7004: OK
Connecting to node 192.168.5.128:7002: OK
Connecting to node 192.168.5.128:7005: OK
Connecting to node 192.168.5.128:7003: OK
>>> Performing Cluster Check (using node 192.168.5.128:7001)
M: 3cbed89c47ca14b3d1eb11dd2f7525fa6cb4fcd7 192.168.5.128:7001
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: 05ad0eb9b5f839771b09dc18192909d5fa1f893e 192.168.5.128:7006
slots: (0 slots) slave
replicates d7d28caadfdc4161261305f2d2baf55d2d8f4221
S: f124b72c0421c7514f44668d30761d075e42643d 192.168.5.128:7004
slots: (0 slots) slave
replicates 3cbed89c47ca14b3d1eb11dd2f7525fa6cb4fcd7
M: 27d069e1b4d459a92b6cc9a1c92ad46ea00cb61d 192.168.5.128:7002
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: 8cf60c085a58b60557a887a5e8451ce38e6b54fa 192.168.5.128:7005
slots: (0 slots) slave
replicates 27d069e1b4d459a92b6cc9a1c92ad46ea00cb61d
M: d7d28caadfdc4161261305f2d2baf55d2d8f4221 192.168.5.128:7003
slots:10923-16383 (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Connecting to node 192.168.5.128:7007: OK
>>> Send CLUSTER MEET to node 192.168.5.128:7007 to make it join the cluster.
[OK] New node added correctly.
[root@itheima redis-cluster]#
[root@itheima redis-cluster]# ./redis-trib.rb add-node --slave --master-id 26630461d8a63a7398e3f43b7366014c72a6a7ef 192.168.5.128:7008 192.168.5.128:7007
>>> Adding node 192.168.5.128:7008 to cluster 192.168.5.128:7007
Connecting to node 192.168.5.128:7007: OK
Connecting to node 192.168.5.128:7001: OK
Connecting to node 192.168.5.128:7003: OK
Connecting to node 192.168.5.128:7005: OK
Connecting to node 192.168.5.128:7004: OK
Connecting to node 192.168.5.128:7006: OK
Connecting to node 192.168.5.128:7002: OK
>>> Performing Cluster Check (using node 192.168.5.128:7007)
M: 26630461d8a63a7398e3f43b7366014c72a6a7ef 192.168.5.128:7007
slots:0-165,5461-5627,10923-11088 (499 slots) master
0 additional replica(s)
M: 3cbed89c47ca14b3d1eb11dd2f7525fa6cb4fcd7 192.168.5.128:7001
slots:166-5460 (5295 slots) master
1 additional replica(s)
M: d7d28caadfdc4161261305f2d2baf55d2d8f4221 192.168.5.128:7003
slots:11089-16383 (5295 slots) master
1 additional replica(s)
S: 8cf60c085a58b60557a887a5e8451ce38e6b54fa 192.168.5.128:7005
slots: (0 slots) slave
replicates 27d069e1b4d459a92b6cc9a1c92ad46ea00cb61d
S: f124b72c0421c7514f44668d30761d075e42643d 192.168.5.128:7004
slots: (0 slots) slave
replicates 3cbed89c47ca14b3d1eb11dd2f7525fa6cb4fcd7
S: 05ad0eb9b5f839771b09dc18192909d5fa1f893e 192.168.5.128:7006
slots: (0 slots) slave
replicates d7d28caadfdc4161261305f2d2baf55d2d8f4221
M: 27d069e1b4d459a92b6cc9a1c92ad46ea00cb61d 192.168.5.128:7002
slots:5628-10922 (5295 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Connecting to node 192.168.5.128:7008: OK
>>> Send CLUSTER MEET to node 192.168.5.128:7008 to make it join the cluster.
Waiting for the cluster to join.
>>> Configure node as replica of 192.168.5.128:7007.
[OK] New node added correctly.
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
示例以下:
刪除從節點:算法
[root@itheima redis-cluster]# ./redis-trib.rb del-node 192.168.5.128:7005 8cf60c085a58b60557a887a5e8451ce38e6b54fa
>>> Removing node 8cf60c085a58b60557a887a5e8451ce38e6b54fa from cluster 192.168.5.128:7005
Connecting to node 192.168.5.128:7005: OK
Connecting to node 192.168.5.128:7008: OK
Connecting to node 192.168.5.128:7004: OK
Connecting to node 192.168.5.128:7007: OK
Connecting to node 192.168.5.128:7006: OK
Connecting to node 192.168.5.128:7003: OK
Connecting to node 192.168.5.128:7001: OK
Connecting to node 192.168.5.128:7002: OK
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
[root@itheima redis-cluster]#
刪除主節點:spring
[root@itheima redis-cluster]# ./redis-trib.rb del-node 192.168.5.128:7003 d7d28caadfdc4161261305f2d2baf55d2d8f4221
>>> Removing node d7d28caadfdc4161261305f2d2baf55d2d8f4221 from cluster 192.168.5.128:7003
Connecting to node 192.168.5.128:7003: OK
Connecting to node 192.168.5.128:7001: OK
Connecting to node 192.168.5.128:7008: OK
Connecting to node 192.168.5.128:7007: OK
Connecting to node 192.168.5.128:7004: OK
Connecting to node 192.168.5.128:7002: OK
Connecting to node 192.168.5.128:7006: OK
[ERR] Node 192.168.5.128:7003 is not empty! Reshard data away and try again.
[root@itheima redis-cluster]#
/**
* Jedis鏈接Redis集羣
*/
@Test
public void testJedisCluster1() {
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("192.168.5.128", 7001));
nodes.add(new HostAndPort("192.168.5.128", 7002));
nodes.add(new HostAndPort("192.168.5.128", 7003));
nodes.add(new HostAndPort("192.168.5.128", 7004));
nodes.add(new HostAndPort("192.168.5.128", 7005));
nodes.add(new HostAndPort("192.168.5.128", 7006));
// 建立JedisCluster對象,在系統中是單例存在的
JedisCluster jedisCluster = new JedisCluster(nodes);
// 執行JedisCluster對象中的方法,方法和redis中的一一對應
jedisCluster.set("cluster-test", "Jedis connects Redis cluster test");
String result = jedisCluster.get("cluster-test");
System.out.println(result);
// 程序結束時須要關閉JedisCluster對象
jedisCluster.close();
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
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.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<!-- 鏈接池配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大鏈接數 -->
<property name="maxTotal" value="30" />
<!-- 最大空閒鏈接數 -->
<property name="maxIdle" value="10" />
<!-- 每次釋放鏈接的最大數目 -->
<property name="numTestsPerEvictionRun" value="1024" />
<!-- 釋放鏈接的掃描間隔(毫秒) -->
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<!-- 鏈接最小空閒時間 -->
<property name="minEvictableIdleTimeMillis" value="1800000" />
<!-- 鏈接空閒多久後釋放, 當空閒時間>該值 且 空閒鏈接>最大空閒鏈接數 時直接釋放 -->
<property name="softMinEvictableIdleTimeMillis" value="10000" />
<!-- 獲取鏈接時的最大等待毫秒數,小於零:阻塞不肯定的時間,默認-1 -->
<property name="maxWaitMillis" value="1500" />
<!-- 在獲取鏈接的時候檢查有效性, 默認false -->
<property name="testOnBorrow" value="true" />
<!-- 在空閒時檢查有效性, 默認false -->
<property name="testWhileIdle" value="true" />
<!-- 鏈接耗盡時是否阻塞, false報異常,ture阻塞直到超時, 默認true -->
<property name="blockWhenExhausted" value="false" />
</bean>
<!-- redis集羣 -->
<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg index="0">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.5.128"></constructor-arg>
<constructor-arg index="1" value="7001"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.5.128"></constructor-arg>
<constructor-arg index="1" value="7002"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.5.128"></constructor-arg>
<constructor-arg index="1" value="7003"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.5.128"></constructor-arg>
<constructor-arg index="1" value="7004"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.5.128"></constructor-arg>
<constructor-arg index="1" value="7005"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.5.128"></constructor-arg>
<constructor-arg index="1" value="7006"></constructor-arg>
</bean>
</set>
</constructor-arg>
<constructor-arg index="1" ref="jedisPoolConfig"></constructor-arg>
</bean>
</beans>
private ApplicationContext applicationContext;
@Before
public void init() {
applicationContext = new ClassPathXmlApplicationContext(
"classpath:applicationContext.xml");
}
/**
* 使用spring實現Jedis鏈接Redis集羣
*/
@Test
public void testJedisCluster2() {
JedisCluster jedisCluster = (JedisCluster) applicationContext.getBean("jedisCluster");
jedisCluster.set("name", "xiaoyi");
String value = jedisCluster.get("name");
System.out.println(value); }