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 的鍵。html

語法

Redis 鍵命令的基本語法以下:java

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 鍵相關的基本命令:mysql

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 不能像集合那樣,返回輸入的各個元素。

複製代碼

什麼是基數?linux

好比數據集 {1, 3, 5, 7, 5, 7, 8}, 那麼這個數據集的基數集爲 {1, 3, 5 ,7, 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> EXECweb

  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", 0 ,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("shier@ixiye.com");
        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", "age", "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", 0, -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", 0, -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", 0, -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", 0, -1));// [9, 3, 6, 1]
        System.out.println(jedis.sort("a")); //[1, 3, 6, 9]  //輸入排序後結果
        System.out.println(jedis.lrange("a", 0, -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 = "shier@ixiye.com";
    //可用鏈接實例的最大數目,默認值爲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, 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;
    }
}

複製代碼

測試

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;
    }

}

複製代碼
相關文章
相關標籤/搜索