1. 程式人生 > 程式設計 >redis從入門到實踐

redis從入門到實踐

一. Redis安裝使用

1.介紹

 redis是一個key-value儲存系統。和Memcached類似,它支援儲存的value型別相對更多,
 包括string(字串)、list(連結串列)、set(集合)、zset(sorted set--有序集合)和hash(雜湊型別)。
 這些資料型別都支援push/pop、add/remove及取交集並集和差集及更豐富的操作,而且
 這些操作都是原子性的。在此基礎上,redis支援各種不同方式的排序。與memcached一樣,
 為了保證效率,資料都是快取在記憶體中。區別的是redis會週期性的把更新的資料寫入磁碟
 或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步。

複製程式碼

2.安裝redis

1.下載官網最新redis安裝包
http://download.redis.io/releases/redis-4.0.0.tar.gz

複製程式碼
2.在/usr/local下建立檔案redis
cd /usr/local
mkdir redis

複製程式碼
3.將下載的redis-4.0.2.tar.gz安裝包解壓到redis資料夾中
cd ~
tar -zxvf redis-4.0.2.tar.gz -C /usr/local/redis

複製程式碼
4.進入解壓後的目錄進行編譯
cd /usr/local/redis/redis-4.0.2
make

複製程式碼
5.安裝到指定目錄,如 /usr/local/redis
cd /usr/local/redis/redis-4.0.2
make PREFIX=/usr/local/redis install

複製程式碼
6.拷貝配置檔案redis.conf到安裝目錄下
cp  /usr/local/redis/redis-4.0.2/redis.conf   /usr/local/redis/bin

複製程式碼
7.修改redis.conf配置檔案,這裡使用預設埠6379,有需要的可以更改。 把daemonize改為yes(這裡推薦以後端模式啟動)
vi /usr/local/redis/bin/redis.conf

-----------------------------------

以後端模式啟動redis
cd
/usr/local/redis ./bin/redis-server ./bin/redis.conf 複製程式碼
8.測試redis
cd /usr/local/redis
./bin/redis-cli
set name zhangsan
get name

複製程式碼
9.Linux開啟關閉redis
1.啟動:./redis-server(redis-server redis.conf)

2.登陸:./redis-cli(redis-cli -p 6379)

3.關閉:./redis-cli shutdown

複製程式碼
10.Linux 為redis配置密碼
1.第一種方式(臨時密碼,Linux重啟後會消失)
(1)
[root@localhost bin]# redis-cli -p 6379
127.0.0.1:6379> 
(2)檢視當前redis有沒有設定密碼:
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
(3)為以上顯示說明沒有密碼,那麼現在來設定密碼:
127.0.0.1:6379> config set requirepass abcdefg
OK
127.0.0.1:6379> 
(4)再次檢視當前redis就提示需要密碼:
127.0.0.1:6379> config get requirepass
(error) NOAUTH Authentication required.
127.0.0.1:6379>

2.第二種方式 (永久方式)
需要永久配置密碼的話就去redis.conf的配置檔案中找到requirepass這個引數,如下配置:
修改redis.conf配置檔案  
# requirepass foobared
requirepass 123   指定密碼123
儲存後重啟redis就可以了

複製程式碼
11.Jedis連線redis
java 程式碼方式
//連線redis伺服器,192.168.0.100:6379
jedis = new Jedis("ip",6379);
//許可權認證
jedis.auth("password");

配置檔案方式
<bean id=”jedisConnectionFactory”
class=”org.springframework.data.redis.connection.jedis.JedisConnectionFactory”>
<property name=”hostName” value=”${redis.host}” />
<property name=”port” value=”${redis.port}” />
<property name=”password” value=”${redis.pass}” />
</bean>

redis的其他命令
如果需要關閉redis:
[root@localhost bin]# pkill redis
如果需要開啟redis:
[root@localhost bin]# redis-server &
加&符號的作用是為了讓此程式轉換為後臺程式,不佔用shell的服務。

複製程式碼

注意事項

1.提示time out錯誤 需要在iptables防火牆上新增6379埠並重啟防火牆服務
2.提示connection refuse錯誤 需要註釋掉redis.conf 檔案中的bind 127.0.0.1
3.提示J edisDataException錯誤 需要將redis.conf檔案中的protect-mode 置為no最後重啟redis

複製程式碼

應用場景

1.快取
2.聊天室,秒殺,任務佇列(list結構,pop(彈出),push(插入))
3.資料儲存(add,del,update,select)定期持久化到硬碟中
4.網站統計
5.資料過期處理
6.分散式叢集架構中的session分離

複製程式碼

主要內容

NoSQL(非關係型資料庫)
redis:key/value鍵值dui儲存資料庫
mongodb:檔案型資料庫
hbase:列式資料庫
neo4j:圖式資料庫,儲存的是圖關係而非行或列。主要用於社交網路的儲存

redis資料結構:String Hash Set SortedSet List
redis事務:multi exec discard
redis持久化:rbd記憶體快照,aof命令日誌

複製程式碼

二.Redis快速入門

1.redis 配置說明
1\. Redis預設不是以守護程式的方式執行,可以通過該配置項修改,使用yes啟用守護程式
daemonize no
2\. 當Redis以守護程式方式執行時,Redis預設會把pid寫入/var/run/redis.pid檔案,可以通過pidfile指定
pidfile /var/run/redis.pid
3\. 指定Redis監聽埠,預設埠為6379,作者在自己的一篇博文中解釋了為什麼選用6379作為預設埠,因為6379在手機按鍵上MERZ對應的號碼,而MERZ取自義大利歌女Alessia Merz的名字
port 6379
4\. 繫結的主機地址
bind 127.0.0.1
5.當 客戶端閒置多長時間後關閉連線,如果指定為0,表示關閉該功能
timeout 300
6\. 指定日誌記錄級別,Redis總共支援四個級別:debug、verbose、notice、warning,預設為verbose
loglevel verbose
7\. 日誌記錄方式,預設為標準輸出,如果配置Redis為守護程式方式執行,而這裡又配置為日誌記錄方式為標準輸出,則日誌將會傳送給/dev/null
logfile stdout
8\. 設定資料庫的數量,預設資料庫為0,可以使用SELECT <dbid>命令在連線上指定資料庫id
databases 16
9\. 指定在多長時間內,有多少次更新操作,就將資料同步到資料檔案,可以多個條件配合
save <seconds> <changes>
Redis預設配置檔案中提供了三個條件:
save 900 1
save 300 10
save 60 10000
分別表示900秒(15分鐘)內有1個更改,300秒(5分鐘)內有10個更改以及60秒內有10000個更改。
10\. 指定儲存至本地資料庫時是否壓縮資料,預設為yes,Redis採用LZF壓縮,如果為了節省CPU時間,可以關閉該選項,但會導致資料庫檔案變的巨大
rdbcompression yes
11\. 指定本地資料庫檔名,預設值為dump.rdb
dbfilename dump.rdb
12\. 指定本地資料庫存放目錄
dir ./
13\. 設定當本機為slav服務時,設定master服務的IP地址及埠,在Redis啟動時,它會自動從master進行資料同步
slaveof <masterip> <masterport>
14\. 當master服務設定了密碼保護時,slav服務連線master的密碼
masterauth <master-password>
15\. 設定Redis連線密碼,如果配置了連線密碼,客戶端在連線Redis時需要通過AUTH <password>命令提供密碼,預設關閉
requirepass foobared
16\. 設定同一時間最大客戶端連線數,預設無限制,Redis可以同時開啟的客戶端連線數為Redis程式可以開啟的最大檔案描述符數,如果設定 maxclients 0,表示不作限制。當客戶端連線數到達限制時,Redis會關閉新的連線並向客戶端返回max number of clients reached錯誤資訊
maxclients 128
17\. 指定Redis最大記憶體限制,Redis在啟動時會把資料載入到記憶體中,達到最大記憶體後,Redis會先嚐試清除已到期或即將到期的Key,當此方法處理 後,仍然到達最大記憶體設定,將無法再進行寫入操作,但仍然可以進行讀取操作。Redis新的vm機制,會把Key存放記憶體,Value會存放在swap區
maxmemory <bytes>
18\. 指定是否在每次更新操作後進行日誌記錄,Redis在預設情況下是非同步的把資料寫入磁碟,如果不開啟,可能會在斷電時導致一段時間內的資料丟失。因為 redis本身同步資料檔案是按上面save條件來同步的,所以有的資料會在一段時間內只存在於記憶體中。預設為no
appendonly no
19\. 指定更新日誌檔名,預設為appendonly.aof
appendfilename appendonly.aof
20\. 指定更新日誌條件,共有3個可選值: 
no:表示等作業系統進行資料快取同步到磁碟(快) 
always:表示每次更新操作後手動呼叫fsync()將資料寫到磁碟(慢,安全) 
everysec:表示每秒同步一次(折衷,預設值)
appendfsync everysec
21\. 指定是否啟用虛擬記憶體機制,預設值為no,簡單的介紹一下,VM機制將資料分頁存放,由Redis將訪問量較少的頁即冷資料swap到磁碟上,訪問多的頁面由磁碟自動換出到記憶體中(在後面的文章我會仔細分析Redis的VM機制)
vm-enabled no
22\. 虛擬記憶體檔案路徑,預設值為/tmp/redis.swap,不可多個Redis例項共享
vm-swap-file /tmp/redis.swap
23\. 將所有大於vm-max-memory的資料存入虛擬記憶體,無論vm-max-memory設定多小,所有索引資料都是記憶體儲存的(Redis的索引資料 就是keys),也就是說,當vm-max-memory設定為0的時候,其實是所有value都存在於磁碟。預設值為0
vm-max-memory 0
24\. Redis swap檔案分成了很多的page,一個物件可以儲存在多個page上面,但一個page上不能被多個物件共享,vm-page-size是要根據儲存的 資料大小來設定的,作者建議如果儲存很多小物件,page大小最好設定為32或者64bytes;如果儲存很大大物件,則可以使用更大的page,如果不 確定,就使用預設值
vm-page-size 32
25\. 設定swap檔案中的page數量,由於頁表(一種表示頁面空閒或使用的bitmap)是在放在記憶體中的,,在磁碟上每8個pages將消耗1byte的記憶體。
vm-pages 134217728
26\. 設定訪問swap檔案的執行緒數,最好不要超過機器的核數,如果設定為0,那麼所有對swap檔案的操作都是序列的,可能會造成比較長時間的延遲。預設值為4
vm-max-threads 4
27\. 設定在向客戶端應答時,是否把較小的包合併為一個包傳送,預設為開啟
glueoutputbuf yes
28\. 指定在超過一定的數量或者最大的元素超過某一臨界值時,採用一種特殊的雜湊演演算法
hash-max-zipmap-entries 64
hash-max-zipmap-value 512
29\. 指定是否啟用重置雜湊,預設為開啟(後面在介紹Redis的雜湊演演算法時具體介紹)
activerehashing yes
30\. 指定包含其它的配置檔案,可以在同一主機上多個Redis例項之間使用同一份配置檔案,而同時各個例項又擁有自己的特定配置檔案
include /path/to/local.conf

複製程式碼

Redis 鍵(key)

Redis 鍵命令用於管理 redis 的鍵。

語法

Redis 鍵命令的基本語法如下:

redis 127.0.0.1:6379> COMMAND KEY_NAME

複製程式碼
例項
redis 127.0.0.1:6379> SET runoobkey redis
OK
redis 127.0.0.1:6379> DEL runoobkey
(integer) 1

在以上例項中 DEL 是一個命令, runoobkey 是一個鍵。 如果鍵被刪除成功,命令執行後輸出 (integer) 1,否則將輸出 (integer) 0

複製程式碼
Redis keys 命令

下表給出了與 Redis 鍵相關的基本命令:

1   DEL key
該命令用於在 key 存在時刪除 key。
2	DUMP key 
序列化給定 key ,並返回被序列化的值。
3	EXISTS key 
檢查給定 key 是否存在。
4	EXPIRE key seconds
為給定 key 設定過期時間。
5	EXPIREAT key timestamp 
EXPIREAT 的作用和 EXPIRE 類似,都用於為 key 設定過期時間。 不同在於 EXPIREAT 命令接受的時間引數是 UNIX 時間戳(unix timestamp)。
6	PEXPIRE key milliseconds 
設定 key 的過期時間以毫秒計。
7	PEXPIREAT key milliseconds-timestamp 
設定 key 過期時間的時間戳(unix timestamp) 以毫秒計
8	KEYS pattern 
查詢所有符合給定模式( pattern)的 key 。
9	MOVE key db 
將當前資料庫的 key 移動到給定的資料庫 db 當中。
10	PERSIST key 
移除 key 的過期時間,key 將持久保持。
11	PTTL key 
以毫秒為單位返回 key 的剩餘的過期時間。
12	TTL key 
以秒為單位,返回給定 key 的剩餘生存時間(TTL,time to live)。
13	RANDOMKEY 
從當前資料庫中隨機返回一個 key 。
14	RENAME key newkey 
修改 key 的名稱
15	RENAMENX key newkey 
僅當 newkey 不存在時,將 key 改名為 newkey 。
16	TYPE key 
返回 key 所儲存的值的型別

複製程式碼

Redis 資料型別

Redis支援五種資料型別:
string(字串),
hash(雜湊),
list(列表),
set(集合)
zset(sorted set:有序集合)。

複製程式碼

String(字串)

string是redis最基本的型別,你可以理解成與Memcached一模一樣的型別,一個key對應一個value。
string型別是二進位制安全的。意思是redis的string可以包含任何資料。比如jpg圖片或者序列化的物件 。
string型別是Redis最基本的資料型別,一個鍵最大能儲存512MB。

複製程式碼
例項
redis 127.0.0.1:6379> SET name "runoob"
OK
redis 127.0.0.1:6379> GET name
"runoob"

在以上例項中我們使用了 Redis 的 SET 和 GET 命令。鍵為 name,對應的值為 runoob。
注意:一個鍵最大能儲存512MB。

複製程式碼
Redis 字串命令
1	SET key value 
設定指定 key 的值
2	GET key 
獲取指定 key 的值。
3	GETRANGE key start end 
返回 key 中字串值的子字元
4	GETSET key value
將給定 key 的值設為 value ,並返回 key 的舊值(old value)。
5	GETBIT key offset
對 key 所儲存的字串值,獲取指定偏移量上的位(bit)。
6	MGET key1 [key2..]
獲取所有(一個或多個)給定 key 的值。
7	SETBIT key offset value
對 key 所儲存的字串值,設定或清除指定偏移量上的位(bit)。
8	SETEX key seconds value
將值 value 關聯到 key ,並將 key 的過期時間設為 seconds (以秒為單位)。
9	SETNX key value
只有在 key 不存在時設定 key 的值。
10	SETRANGE key offset value
用 value 引數覆寫給定 key 所儲存的字串值,從偏移量 offset 開始。
11	STRLEN key
返回 key 所儲存的字串值的長度。
12	MSET key value [key value ...]
同時設定一個或多個 key-value 對。
13	MSETNX key value [key value ...] 
同時設定一個或多個 key-value 對,當且僅當所有給定 key 都不存在。
14	PSETEX key milliseconds value
這個命令和 SETEX 命令相似,但它以毫秒為單位設定 key 的生存時間,而不是像 SETEX 命令那樣,以秒為單位。
15	INCR key
將 key 中儲存的數字值增一。
16	INCRBY key increment
將 key 所儲存的值加上給定的增量值(increment) 。
17	INCRBYFLOAT key increment
將 key 所儲存的值加上給定的浮點增量值(increment) 。
18	DECR key
將 key 中儲存的數字值減一。
19	DECRBY key decrement
key 所儲存的值減去給定的減量值(decrement) 。
20	APPEND key value
如果 key 已經存在並且是一個字串, APPEND 命令將 value 追加到 key 原來的值的末尾。

複製程式碼

Hash(雜湊)

Redis hash 是一個鍵值(key=>value)對集合。
Redis hash是一個string型別的field和value的對映表,hash特別適合用於儲存物件。

複製程式碼
例項
redis> HMSET myhash field1 "Hello" field2 "World"
"OK"
redis> HGET myhash field1
"Hello"
redis> HGET myhash field2
"World"

以上例項中 hash 資料型別儲存了包含使用者指令碼資訊的使用者物件。 例項中我們使用了 Redis HMSET,HGETALL 命令,user:1 為鍵值。
每個 hash 可以儲存 232 -1 鍵值對(40多億)。

複製程式碼
Redis hash 命令
1	HDEL key field1 [field2] 
刪除一個或多個雜湊表字段
2	HEXISTS key field 
檢視雜湊表 key 中,指定的欄位是否存在。
3	HGET key field 
獲取儲存在雜湊表中指定欄位的值。
4	HGETALL key 
獲取在雜湊表中指定 key 的所有欄位和值
5	HINCRBY key field increment 
為雜湊表 key 中的指定欄位的整數值加上增量 increment 。
6	HINCRBYFLOAT key field increment 
為雜湊表 key 中的指定欄位的浮點數值加上增量 increment 。
7	HKEYS key 
獲取所有雜湊表中的欄位
8	HLEN key 
獲取雜湊表中欄位的數量
9	HMGET key field1 [field2] 
獲取所有給定欄位的值
10	HMSET key field1 value1 [field2 value2 ] 
同時將多個 field-value (域-值)對設定到雜湊表 key 中。
11	HSET key field value 
將雜湊表 key 中的欄位 field 的值設為 value 。
12	HSETNX key field value 
只有在欄位 field 不存在時,設定雜湊表字段的值。
13	HVALS key 
獲取雜湊表中所有值
14	HSCAN key cursor [MATCH pattern] [COUNT count] 
迭代雜湊表中的鍵值對。

複製程式碼

List(列表)

Redis 列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素到列表的頭部(左邊)或者尾部(右邊)。

複製程式碼
例項
redis 127.0.0.1:6379> lpush runoob redis
(integer) 1
redis 127.0.0.1:6379> lpush runoob mongodb
(integer) 2
redis 127.0.0.1:6379> lpush runoob rabitmq
(integer) 3
redis 127.0.0.1:6379> lrange runoob 0 10
1) "rabitmq"
2) "mongodb"
3) "redis"
redis 127.0.0.1:6379>

列表最多可儲存 232 - 1 元素 (4294967295,每個列表可儲存40多億)。

複製程式碼
Redis 列表命令
1	BLPOP key1 [key2 ] timeout 
移出並獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
2	BRPOP key1 [key2 ] timeout 
移出並獲取列表的最後一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
3	BRPOPLPUSH source destination timeout 
從列表中彈出一個值,將彈出的元素插入到另外一個列表中並返回它; 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
4	LINDEX key index 
通過索引獲取列表中的元素
5	LINSERT key BEFORE|AFTER pivot value 
在列表的元素前或者後插入元素
6	LLEN key 
獲取列表長度
7	LPOP key 
移出並獲取列表的第一個元素
8	LPUSH key value1 [value2] 
將一個或多個值插入到列表頭部
9	LPUSHX key value 
將一個值插入到已存在的列表頭部
10	LRANGE key start stop 
獲取列表指定範圍內的元素
11	LREM key count value 
移除列表元素
12	LSET key index value 
通過索引設定列表元素的值
13	LTRIM key start stop 
對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除。
14	RPOP key 
移除並獲取列表最後一個元素
15	RPOPLPUSH source destination 
移除列表的最後一個元素,並將該元素新增到另一個列表並返回
16	RPUSH key value1 [value2] 
在列表中新增一個或多個值
17	RPUSHX key value 
為已存在的列表新增值

複製程式碼

Set(集合)

Redis的Set是string型別的無序集合。
集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是O(1)。
sadd 命令
新增一個string元素到,key對應的set集合中,成功返回1,如果元素已經在集合中返回0,key對應的set不存在返回錯誤。
sadd key member

複製程式碼
例項
redis 127.0.0.1:6379> sadd runoob redis
(integer) 1
redis 127.0.0.1:6379> sadd runoob mongodb
(integer) 1
redis 127.0.0.1:6379> sadd runoob rabitmq
(integer) 1
redis 127.0.0.1:6379> sadd runoob rabitmq
(integer) 0
redis 127.0.0.1:6379> smembers runoob

1) "rabitmq"
2) "mongodb"
3) "redis"

注意:以上例項中 rabitmq 添加了兩次,但根據集合內元素的唯一性,第二次插入的元素將被忽略。
集合中最大的成員數為 232 - 1(4294967295,每個集合可儲存40多億個成員)。

複製程式碼
Redis 集合命令
1	SADD key member1 [member2] 
向集合新增一個或多個成員
2	SCARD key 
獲取集合的成員數
3	SDIFF key1 [key2] 
返回給定所有集合的差集
4	SDIFFSTORE destination key1 [key2] 
返回給定所有集合的差集並儲存在 destination 中
5	SINTER key1 [key2] 
返回給定所有集合的交集
6	SINTERSTORE destination key1 [key2] 
返回給定所有集合的交集並儲存在 destination 中
7	SISMEMBER key member 
判斷 member 元素是否是集合 key 的成員
8	SMEMBERS key 
返回集合中的所有成員
9	SMOVE source destination member 
將 member 元素從 source 集合移動到 destination 集合
10	SPOP key 
移除並返回集合中的一個隨機元素
11	SRANDMEMBER key [count] 
返回集合中一個或多個隨機數
12	SREM key member1 [member2] 
移除集合中一個或多個成員
13	SUNION key1 [key2] 
返回所有給定集合的並集
14	SUNIONSTORE destination key1 [key2] 
所有給定集合的並集儲存在 destination 集合中
15	SSCAN key cursor [MATCH pattern] [COUNT count] 
迭代集合中的元素

複製程式碼

zset(sorted set:有序集合)

Redis zset 和 set 一樣也是string型別元素的集合,且不允許重複的成員。
不同的是每個元素都會關聯一個double型別的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。
zset的成員是唯一的,但分數(score)卻可以重複。
zadd 命令
新增元素到集合,元素在集合中存在則更新對應score
zadd key score member

複製程式碼
例項
redis 127.0.0.1:6379> zadd runoob 0 redis
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 mongodb
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq
(integer) 0
redis 127.0.0.1:6379> ZRANGEBYSCORE runoob 0 1000

1) "redis"
2) "mongodb"
3) "rabitmq"

複製程式碼
Redis 有序集合命令
1	ZADD key score1 member1 [score2 member2] 
向有序集合新增一個或多個成員,或者更新已存在成員的分數
2	ZCARD key 
獲取有序集合的成員數
3	ZCOUNT key min max 
計算在有序集合中指定區間分數的成員數
4	ZINCRBY key increment member 
有序集合中對指定成員的分數加上增量 increment
5	ZINTERSTORE destination numkeys key [key ...] 
計算給定的一個或多個有序集的交集並將結果集儲存在新的有序集合 key 中
6	ZLEXCOUNT key min max 
在有序集合中計算指定字典區間內成員數量
7	ZRANGE key start stop [WITHSCORES] 
通過索引區間返回有序集合成指定區間內的成員
8	ZRANGEBYLEX key min max [LIMIT offset count] 
通過字典區間返回有序集合的成員
9	ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] 
通過分數返回有序集合指定區間內的成員
10	ZRANK key member 
返回有序集合中指定成員的索引
11	ZREM key member [member ...] 
移除有序集合中的一個或多個成員
12	ZREMRANGEBYLEX key min max 
移除有序集合中給定的字典區間的所有成員
13	ZREMRANGEBYRANK key start stop 
移除有序集合中給定的排名區間的所有成員
14	ZREMRANGEBYSCORE key min max 
移除有序集合中給定的分數區間的所有成員
15	ZREVRANGE key start stop [WITHSCORES] 
返回有序集中指定區間內的成員,通過索引,分數從高到底
16	ZREVRANGEBYSCORE key max min [WITHSCORES] 
返回有序集中指定分數區間內的成員,分數從高到低排序
17	ZREVRANK key member 
返回有序集合中指定成員的排名,有序整合員按分數值遞減(從大到小)排序
18	ZSCORE key member 
返回有序集中,成員的分數值
19	ZUNIONSTORE destination numkeys key [key ...] 
計算給定的一個或多個有序集的並集,並儲存在新的 key 中
20	ZSCAN key cursor [MATCH pattern] [COUNT count] 
迭代有序集合中的元素(包括元素成員和元素分值)

複製程式碼

HyperLogLog

Redis 在 2.8.9 版本添加了 HyperLogLog 結構。
Redis HyperLogLog 是用來做基數統計的演演算法,HyperLogLog 的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定 的、並且是很小的。
在 Redis 裡面,每個 HyperLogLog 鍵只需要花費 12 KB 記憶體,就可以計算接近 2^64 個不同元素的基 數。這和計算基數時,元素越多耗費記憶體就越多的集合形成鮮明對比。
但是,因為 HyperLogLog 只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個元素。

複製程式碼

什麼是基數?

比如資料集 {1,3,5,7,8}, 那麼這個資料集的基數集為 {1,8},基數(不重複元素)為5。 基數估計就是在誤差可接受的範圍內,快速計算基數。

複製程式碼
例項
redis 127.0.0.1:6379> PFADD runoobkey "redis"
1) (integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mongodb"
1) (integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mysql"
1) (integer) 1
redis 127.0.0.1:6379> PFCOUNT runoobkey
(integer) 3

複製程式碼
Redis HyperLogLog 命令
1	PFADD key element [element ...] 
新增指定元素到 HyperLogLog 中。
2	PFCOUNT key [key ...] 
返回給定 HyperLogLog 的基數估算值。
3	PFMERGE destkey sourcekey [sourcekey ...] 
將多個 HyperLogLog 合併為一個 HyperLogLog

複製程式碼

釋出訂閱

Redis 釋出訂閱(pub/sub)是一種訊息通訊模式:傳送者(pub)傳送訊息,訂閱者(sub)接收訊息。
Redis 客戶端可以訂閱任意數量的頻道。
下圖展示了頻道 channel1 , 以及訂閱這個頻道的三個客戶端 —— client2 、 client5 和 client1 之間的關係:

複製程式碼

image

當有新訊息通過 PUBLISH 命令傳送給頻道 channel1 時, 這個訊息就會被髮送給訂閱它的三個客戶端:

複製程式碼

image

例項
redis 127.0.0.1:6379> SUBSCRIBE redisChat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1

現在,我們先重新開啟個 redis 客戶端,然後在同一個頻道 redisChat 釋出兩次訊息,訂閱者就能接收到訊息。

redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"
(integer) 1
redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by runoob.com"
(integer) 1

# 訂閱者的客戶端會顯示如下訊息
1) "message"
2) "redisChat"
3) "Redis is a great caching technique"
1) "message"
2) "redisChat"
3) "Learn redis by runoob.com"

複製程式碼
Redis 釋出訂閱命令
1	PSUBSCRIBE pattern [pattern ...] 
訂閱一個或多個符合給定模式的頻道。
2	PUBSUB subcommand [argument [argument ...]] 
檢視訂閱與釋出系統狀態。
3	PUBLISH channel message 
將資訊傳送到指定的頻道。
4	PUNSUBSCRIBE [pattern [pattern ...]] 
退訂所有給定模式的頻道。
5	SUBSCRIBE channel [channel ...] 
訂閱給定的一個或多個頻道的資訊。
6	UNSUBSCRIBE [channel [channel ...]] 
指退訂給定的頻道。

複製程式碼

Redis 事務

Redis 事務可以一次執行多個命令, 並且帶有以下兩個重要的保證:
事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端傳送來的命令請求所打斷。
事務是一個原子操作:事務中的命令要麼全部被執行,要麼全部都不執行。
一個事務從開始到執行會經歷以下三個階段:
開始事務。
命令入隊。
執行事務。

複製程式碼
例項

`` txt 以下是一個事務的例子, 它先以 MULTI 開始一個事務, 然後將多個命令入隊到事務中, 最後由 EXEC 命令觸發事務, 一併執行事務中的所有命令: redis 127.0.0.1:6379> MULTI OK redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days" QUEUED redis 127.0.0.1:6379> GET book-name QUEUED redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series" QUEUED redis 127.0.0.1:6379> SMEMBERS tag QUEUED redis 127.0.0.1:6379> EXEC

  1. OK
  2. "Mastering C++ in 21 days"
  3. (integer) 3
    1. "Mastering Series"
    2. "C++"
    3. "Programming"

#####  Redis 事務命令

``` txt
1	DISCARD 
取消事務,放棄執行事務塊內的所有命令。
2	EXEC 
執行所有事務塊內的命令。
3	MULTI 
標記一個事務塊的開始。
4	UNWATCH 
取消 WATCH 命令對所有 key 的監視。
5	WATCH key [key ...] 
監視一個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。

複製程式碼

Redis 連線

Redis 連線命令主要是用於連線 redis 服務。

複製程式碼
例項
以下例項演示了客戶端如何通過密碼驗證連線到 redis 服務,並檢測服務是否在執行:
redis 127.0.0.1:6379> AUTH "password"
OK
redis 127.0.0.1:6379> PING
PONG

複製程式碼
Redis 連線命令
1	AUTH password 
驗證密碼是否正確
2	ECHO message 
列印字串
3	PING 
檢視服務是否執行
4	QUIT 
關閉當前連線
5	SELECT index 
切換到指定的資料庫

複製程式碼

Redis 伺服器

Redis 伺服器命令主要是用於管理 redis 服務。

複製程式碼
例項
以下例項演示瞭如何獲取 redis 伺服器的統計資訊:
redis 127.0.0.1:6379> INFO

複製程式碼
Redis 伺服器命令
1	BGREWRITEAOF 
非同步執行一個 AOF(AppendOnly File) 檔案重寫操作
2	BGSAVE 
在後臺非同步儲存當前資料庫的資料到磁碟
3	CLIENT KILL [ip:port] [ID client-id] 
關閉客戶端連線
4	CLIENT LIST 
獲取連線到伺服器的客戶端連線列表
5	CLIENT GETNAME 
獲取連線的名稱
6	CLIENT PAUSE timeout 
在指定時間內終止執行來自客戶端的命令
7	CLIENT SETNAME connection-name 
設定當前連線的名稱
8	CLUSTER SLOTS 
獲取叢集節點的對映陣列
9	COMMAND 
獲取 Redis 命令詳情陣列
10	COMMAND COUNT 
獲取 Redis 命令總數
11	COMMAND GETKEYS 
獲取給定命令的所有鍵
12	TIME 
返回當前伺服器時間
13	COMMAND INFO command-name [command-name ...] 
獲取指定 Redis 命令描述的陣列
14	CONFIG GET parameter 
獲取指定配置引數的值
15	CONFIG REWRITE 
對啟動 Redis 伺服器時所指定的 redis.conf 配置檔案進行改寫
16	CONFIG SET parameter value 
修改 redis 配置引數,無需重啟
17	CONFIG RESETSTAT 
重置 INFO 命令中的某些統計資料
18	DBSIZE 
返回當前資料庫的 key 的數量
19	DEBUG OBJECT key 
獲取 key 的除錯資訊
20	DEBUG SEGFAULT 
讓 Redis 服務崩潰
21	FLUSHALL 
刪除所有資料庫的所有key
22	FLUSHDB 
刪除當前資料庫的所有key
23	INFO [section] 
獲取 Redis 伺服器的各種資訊和統計數值
24	LASTSAVE 
返回最近一次 Redis 成功將資料儲存到磁碟上的時間,以 UNIX 時間戳格式表示
25	MONITOR 
實時打印出 Redis 伺服器接收到的命令,除錯用
26	ROLE 
返回主從例項所屬的角色
27	SAVE 
非同步儲存資料到硬碟
28	SHUTDOWN [NOSAVE] [SAVE] 
非同步儲存資料到硬碟,並關閉伺服器
29	SLAVEOF host port 
將當前伺服器轉變為指定伺服器的從屬伺服器(slave server)
30	SLOWLOG subcommand [argument] 
管理 redis 的慢日誌
31	SYNC 
用於複製功能(replication)的內部命令

複製程式碼

Redis 資料備份與恢復

Redis SAVE 命令用於建立當前資料庫的備份。
語法
redis Save 命令基本語法如下:
redis 127.0.0.1:6379> SAVE

複製程式碼
例項
redis 127.0.0.1:6379> SAVE 
OK
該命令將在 redis 安裝目錄中建立dump.rdb檔案。

複製程式碼
恢復資料
如果需要恢復資料,只需將備份檔案 (dump.rdb) 移動到 redis 安裝目錄並啟動服務即可。獲取 redis 目錄可以使用 CONFIG 命令,如下所示:
redis 127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/usr/local/redis/bin"
以上命令 CONFIG GET dir 輸出的 redis 安裝目錄為 /usr/local/redis/bin。

複製程式碼
Bgsave
建立 redis 備份檔案也可以使用命令 BGSAVE,該命令在後臺執行。
例項
127.0.0.1:6379> BGSAVE
Background saving started

複製程式碼

Redis 客戶端連線

Redis 通過監聽一個 TCP 埠或者 Unix socket 的方式來接收來自客戶端的連線,當一個連線建立後,Redis 內部會進行以下一些操作:

首先,客戶端 socket 會被設定為非阻塞模式,因為 Redis 在網路事件處理上採用的是非阻塞多路複用模型。
然後為這個 socket 設定 TCP_NODELAY 屬性,禁用 Nagle 演演算法
然後建立一個可讀的檔案事件用於監聽這個客戶端 socket 的資料傳送

複製程式碼
最大連線數
在 Redis2.4 中,最大連線數是被直接硬編碼在程式碼裡面的,而在2.6版本中這個值變成可配置的。
maxclients 的預設值是 10000,你也可以在 redis.conf 中對這個值進行修改。
config get maxclients
1) "maxclients"
2) "10000"

複製程式碼
例項
以下例項我們在服務啟動時設定最大連線數為 100000:
redis-server --maxclients 100000

複製程式碼
客戶端命令
1	CLIENT LIST	返回連線到 redis 服務的客戶端列表
2	CLIENT SETNAME	設定當前連線的名稱
3	CLIENT GETNAME	獲取通過 CLIENT SETNAME 命令設定的服務名稱
4	CLIENT PAUSE	掛起客戶端連線,指定掛起的時間以毫秒計
5	CLIENT KILL	關閉客戶端連線

複製程式碼

三.Java 使用 Redis

下載jedis.jar

連線到 redis 服務

import redis.clients.jedis.Jedis;

public class RedisJava {
    public static void main(String[] args) {
        //連線本地的 Redis 服務
        Jedis jedis = new Jedis("localhost");
        System.out.println("連線成功");
        //檢視服務是否執行
        System.out.println("服務正在執行: "+jedis.ping());
    }
}

複製程式碼
編譯以上 Java 程式,確保驅動包的路徑是正確的。

連線成功
服務正在執行: PONG

複製程式碼

Redis Java String(字串) 例項

import redis.clients.jedis.Jedis;

public class RedisStringJava {
    public static void main(String[] args) {
        //連線本地的 Redis 服務
        Jedis jedis = new Jedis("localhost");
        System.out.println("連線成功");
        //設定 redis 字串資料
        jedis.set("runoobkey","www.runoob.com");
        // 獲取儲存的資料並輸出
        System.out.println("redis 儲存的字串為: "+ jedis.get("runoobkey"));
    }
}

複製程式碼
編譯以上程式。

連線成功
redis 儲存的字串為: www.runoob.com

複製程式碼

Redis Java List(列表) 例項

import java.util.List;
import redis.clients.jedis.Jedis;

public class RedisListJava {
    public static void main(String[] args) {
        //連線本地的 Redis 服務
        Jedis jedis = new Jedis("localhost");
        System.out.println("連線成功");
        //儲存資料到列表中
        jedis.lpush("site-list","Runoob");
        jedis.lpush("site-list","Google");
        jedis.lpush("site-list","Taobao");
        // 獲取儲存的資料並輸出
        List<String> list = jedis.lrange("site-list",2);
        for(int i=0; i<list.size(); i++) {
            System.out.println("列表項為: "+list.get(i));
        }
    }
}

複製程式碼
編譯以上程式。

連線成功
列表項為: Taobao
列表項為: Google
列表項為: Runoob

複製程式碼

Redis Java Keys 例項

import java.util.Iterator;
import java.util.Set;
import redis.clients.jedis.Jedis;

public class RedisKeyJava {
    public static void main(String[] args) {
        //連線本地的 Redis 服務
        Jedis jedis = new Jedis("localhost");
        System.out.println("連線成功");

        // 獲取資料並輸出
        Set<String> keys = jedis.keys("*"); 
        Iterator<String> it=keys.iterator() ;   
        while(it.hasNext()){   
            String key = it.next();   
            System.out.println(key);   
        }
    }
}

複製程式碼
編譯以上程式。

連線成功
runoobkey
site-list

複製程式碼

Maven依賴

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.1.0</version>
</dependency>

複製程式碼

java 程式碼

package com.shier.common.test;

import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class RedisTest {
    private Jedis jedis;

    @Before
    public void setup() {
        //連線redis伺服器,192.168.0.100:6379
        jedis = new Jedis("172.16.57.150",6379);
        //許可權認證
        jedis.auth("[email protected]");
        jedis.select(1);
    }

    /**
     * redis儲存字串
     */
    @Test
    public void testString() {
        //-----新增資料----------
        jedis.set("name","xinxin");//向key-->name中放入了value-->xinxin
        System.out.println(jedis.get("name"));//執行結果:xinxin

        jedis.append("name"," is my lover"); //拼接
        System.out.println(jedis.get("name"));

        //jedis.del("name");  //刪除某個鍵
        System.out.println(jedis.get("name"));
        //設定多個鍵值對
        //jedis.mset("name","liuling","age","23","qq","476777XXX");
        //jedis.incr("age"); //進行加1操作
        System.out.println(jedis.get("name") + "-" + jedis.get("age") + "-" + jedis.get("qq"));

    }

    /**
     * redis操作Map
     */
    @Test
    public void testMap() {
        //-----新增資料----------
        Map<String,String> map = new HashMap<String,String>();
        map.put("name","xinxin");
        map.put("age","22");
        map.put("qq","123456");
        jedis.hmset("user",map);
        //取出user中的name,執行結果:[minxr]-->注意結果是一個泛型的List
        //第一個引數是存入redis中map物件的key,後面跟的是放入map中的物件的key,後面的key可以跟多個,是可變引數
        List<String> rsmap = jedis.hmget("user","name","qq");
        System.out.println(rsmap);

        //刪除map中的某個鍵值
        jedis.hdel("user","age");
        System.out.println(jedis.hmget("user","age")); //因為刪除了,所以返回的是null
        System.out.println(jedis.hlen("user")); //返回key為user的鍵中存放的值的個數2
        System.out.println(jedis.exists("user"));//是否存在key為user的記錄 返回true
        System.out.println(jedis.hkeys("user"));//返回map物件中的所有key
        System.out.println(jedis.hvals("user"));//返回map物件中的所有value

        Iterator<String> iter = jedis.hkeys("user").iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            System.out.println(key + ":" + jedis.hmget("user",key));
        }
    }

    /**
     * jedis操作List
     */
    @Test
    public void testList() {
        //開始前,先移除所有的內容
        jedis.del("java framework");
        System.out.println(jedis.lrange("java framework",-1));
        //先向key java framework中存放三條資料
        jedis.lpush("java framework","spring");
        jedis.lpush("java framework","struts");
        jedis.lpush("java framework","hibernate");
        //再取出所有資料jedis.lrange是按範圍取出,
        // 第一個是key,第二個是起始位置,第三個是結束位置,jedis.llen獲取長度 -1表示取得所有
        System.out.println(jedis.lrange("java framework",-1));

        jedis.del("java framework");
        jedis.rpush("java framework","spring");
        jedis.rpush("java framework","struts");
        jedis.rpush("java framework","hibernate");
        System.out.println(jedis.lrange("java framework",-1));
    }

    /**
     * jedis操作Set
     */
    @Test
    public void testSet() {
        //新增
        jedis.sadd("user","liuling");
        jedis.sadd("user","xinxin");
        jedis.sadd("user","ling");
        jedis.sadd("user","zhangxinxin");
        jedis.sadd("user","who");
        //移除noname
        jedis.srem("user","who");
        System.out.println(jedis.smembers("user"));//獲取所有加入的value
        System.out.println(jedis.sismember("user","who"));//判斷 who 是否是user集合的元素
        System.out.println(jedis.srandmember("user"));
        System.out.println(jedis.scard("user"));//返回集合的元素個數
    }

    @Test
    public void test() throws InterruptedException {
        //jedis 排序
        //注意,此處的rpush和lpush是List的操作。是一個雙向連結串列(但從表現來看的)
        jedis.del("a");//先清除資料,再加入資料進行測試
        jedis.rpush("a","1");
        jedis.lpush("a","6");
        jedis.lpush("a","3");
        jedis.lpush("a","9");
        System.out.println(jedis.lrange("a",-1));// [9,6,1]
        System.out.println(jedis.sort("a")); //[1,9]  //輸入排序後結果
        System.out.println(jedis.lrange("a",-1));
    }

}

複製程式碼

RedisUtil

package com.shier.common.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public final class RedisUtil {

    //Redis伺服器IP
    private static String ADDR = "172.16.57.150";

    //Redis的埠號
    private static int PORT = 6379;

    //訪問密碼
    private static String AUTH = "[email protected]";
    //可用連線例項的最大數目,預設值為8;
    //如果賦值為-1,則表示不限制;如果pool已經分配了maxActive個jedis例項,則此時pool的狀態為exhausted(耗盡)。
    private static int MAX_ACTIVE = 1024;

    //控制一個pool最多有多少個狀態為idle(空閒的)的jedis例項,預設值也是8。
    private static int MAX_IDLE = 200;

    //等待可用連線的最大時間,單位毫秒,預設值為-1,表示永不超時。如果超過等待時間,則直接丟擲JedisConnectionException;
    private static int MAX_WAIT = 10000;

    private static int TIMEOUT = 10000;

    //在borrow一個jedis例項時,是否提前進行validate操作;如果為true,則得到的jedis例項均是可用的;
    private static boolean TEST_ON_BORROW = true;

    private static JedisPool jedisPool = null;

    /**
     * 初始化Redis連線池
     */
    static {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxActive(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWait(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            jedisPool = new JedisPool(config,ADDR,PORT,TIMEOUT,AUTH);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 獲取Jedis例項
     *
     * @return
     */
    public synchronized static Jedis getJedis() {
        try {
            if (jedisPool != null) {
                Jedis resource = jedisPool.getResource();
                return resource;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 釋放jedis資源
     *
     * @param jedis
     */
    public static void returnResource(final Jedis jedis) {
        if (jedis != null) {
            jedisPool.returnResource(jedis);
        }
    }
}

-----------------------------------------------------------------

package com.shier.common.test;

import com.shier.common.util.RedisUtil;
import org.junit.Test;
import redis.clients.jedis.Jedis;

public class RedisTest {

    @Test
    public void testRedisPool() {
        RedisUtil.getJedis().set("newname","中文測試");
        System.out.println(RedisUtil.getJedis().get("newname"));
    }
}

複製程式碼

四.Spring整合Redis

新增Redis Maven依賴
<span style="white-space:pre;">	</span><!-- redis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.6.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.7.1.RELEASE</version>
        </dependency>

複製程式碼

config.properties


redis.host=192.168.0.254
redis.port=6379  
redis.password=jedis21tb

redis.maxIdle=300  
redis.maxWait=1000  
redis.testOnBorrow=true  
redis.timeout=3000

複製程式碼

spring配置檔案(applicationContext.xml)


<!--引入配置屬性檔案 -->
	<context:property-placeholder location="classpath:config.properties" />
    <!-- redis -->
    <!-- jedis 配置 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >
          <property name="maxIdle" value="${redis.maxIdle}" />
          <property name="maxWaitMillis" value="${redis.maxWait}" />
          <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    </bean >
   <!-- redis伺服器中心 -->
    <bean id="connectionFactory"  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
          <property name="poolConfig" ref="poolConfig" />
          <property name="port" value="${redis.port}" />
          <property name="hostName" value="${redis.host}" />
          <property name="password" value="${redis.password}" />
          <property name="timeout" value="${redis.timeout}" ></property>
    </bean >
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
          <property name="connectionFactory" ref="connectionFactory" />
          <property name="keySerializer" >
              <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
          </property>
          <!-- <property name="valueSerializer" >
              <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
          </property> -->
    </bean >

    <bean id="redisUtil" class="com.kttx.common.RedisUtil" >
          <property name="redisTemplate" ref="redisTemplate" />
    </bean >

複製程式碼

java程式碼


package com.kttx.common;

import java.io.Serializable;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

/**
 * redis
 * @author txs
 *
 */
public class RedisUtil {

	private static Logger logger = Logger.getLogger(RedisUtil.class);

	private static RedisTemplate<Serializable,Object> redisTemplate;

	/**
	 * 寫入或更新快取
	 * @param key
	 * @param value
	 * @return
	 */
	public static boolean set(final String key,Object value)
	{
		boolean result = false;
		try {
			ValueOperations<Serializable,Object> operations = redisTemplate
					.opsForValue();
			operations.set(key,value);
			result = true;
		} catch (Exception e) {
			logger.error("write redis is faill");
			e.printStackTrace();

		}
		return result;
	}

	  /** 
     * 寫入快取 
     *  設定失效時間
     * @param key 
     * @param value 
     * @return 
     */  
    public static boolean set(final String key,Object value,Long expireTime) {  
        boolean result = false;  
        try {  
            ValueOperations<Serializable,Object> operations = redisTemplate  
                    .opsForValue();  
            operations.set(key,value);  
            redisTemplate.expire(key,expireTime,TimeUnit.SECONDS);  
            result = true;  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return result;  
    }  
	/**
	 * 讀取快取
	 * @param key
	 * @return
	 */
	public static Object get(final String key)
	{
		Object result = null;
		ValueOperations<Serializable,Object> operations = redisTemplate
				.opsForValue();
		result = operations.get(key);
		return result;
	}

	/**
	 * 刪除對應的value
	 * @param key
	 */
	public static void remove(final String key)
	{
		if (exists(key)) {
			redisTemplate.delete(key);
		}
	}

	/**
	 * 批量刪除對應的value
	 * 
	 * @param keys
	 */
	public static void remove(final String... keys) {
		for (String key : keys) {
			remove(key);
		}
	}

	/**
	 * 批量刪除key
	 * 
	 * @param pattern 正則表示式
	 */
	public static void removePattern(final String pattern) {
		Set<Serializable> keys = redisTemplate.keys(pattern);
		if (keys.size() > 0)
			redisTemplate.delete(keys);
	}

	/**
	 * 判斷快取中是否有對應的value
	 * 
	 * @param key
	 * @return
	 */
	public static boolean exists(final String key) {
		return redisTemplate.hasKey(key);
	}

	public  void setRedisTemplate(
			RedisTemplate<Serializable,Object> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}
}

複製程式碼

五.Spring boot整合Redis

新增maveny依賴
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.6.2</version>
</dependency>

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>1.7.1.RELEASE</version>
</dependency>

複製程式碼

配置屬性:

# database name
spring.redis.database=0
# server host
spring.redis.host=127.0.0.1  
# server password
spring.redis.password=123456
#connection port
spring.redis.port=6379
# pool settings ...
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1

複製程式碼

redis配置

package com.ming.config;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
@EnableCaching // 啟用快取,這個註解很重要;
public class RedisCacheConfig extends CachingConfigurerSupport {

     /**
     * 生成key的策略
     *
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target,Method method,Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     * 管理快取
     *
     * @param redisTemplate
     * @return
     */
    @SuppressWarnings("rawtypes")
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
        //設定快取過期時間
        // rcm.setDefaultExpiration(60);//秒
        //設定value的過期時間
        Map<String,Long> map=new HashMap<String,Long>();
        map.put("test",60L);
        rcm.setExpires(map);
        return rcm;
    }

    /**
     * RedisTemplate配置
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory factory) {
         StringRedisTemplate template = new StringRedisTemplate(factory);
         Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
         ObjectMapper om = new ObjectMapper();
         om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
         om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
         jackson2JsonRedisSerializer.setObjectMapper(om);
         template.setValueSerializer(jackson2JsonRedisSerializer);//如果key是String 需要配置一下StringSerializer,不然key會亂碼 /XX/XX
         template.afterPropertiesSet();
         return template;
    }

}

複製程式碼
package com.ming.config;

import java.io.Serializable;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

/**
 * redicache 工具類
 * 
 */
@SuppressWarnings("unchecked")
@Component
public class RedisUtils {

    @SuppressWarnings("rawtypes")
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 批量刪除對應的value
     * 
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    /**
     * 批量刪除key
     * 
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0)
            redisTemplate.delete(keys);
    }

    /**
     * 刪除對應的value
     * 
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    /**
     * 判斷快取中是否有對應的value
     * 
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 讀取快取
     * 
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable,Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }

    /**
     * 寫入快取
     * 
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key,Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable,Object> operations = redisTemplate.opsForValue();
            operations.set(key,value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 寫入快取
     * 
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key,Long expireTime) {
        boolean result = false;
        try {
            ValueOperations<Serializable,value);
            redisTemplate.expire(key,TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

複製程式碼

測試

package com.ming.web.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ming.config.RedisUtils;

@RestController
@RequestMapping("/caches")
public class CacheController {

    @Autowired
    private RedisUtils redisUtils;

    @RequestMapping("/test")
    public String  test(){
        redisUtils.set("123","hello world");
        System.out.println("進入了方法");
        String string= redisUtils.get("123").toString();
        return string;
    }

}

複製程式碼