redis的安裝和使用

一,redis的瞭解html

Redis 是一個開源軟件擁有( Berkly Software Distribution 許可 ),它是一個 內存數據結構存貯,一般被用於 數據庫 , 緩存 , 消息代理。 。 它支持: 字符串 , 哈希 , 列表 , 集
合 , 數組集合 , 位圖 , 高壓縮算法以及地圖索引等數據結構。Redis 支持集羣,lua 腳本,以及  LRU(近期最少使用 Least Recently Used )淘汰算法,事物以及不一樣級別的 磁盤
持久化,可以提供一個高可用的 Redis Sentinel 的集羣方案。從這段簡介中咱們應該掌握一下幾點:
1. Redis 是把數據存放在內存當中,因此它的運行速度會很是快
2. Redis 具備多種數據存儲結構
3.  Redis  具備持久化的功能
4. Redis 上的數據能夠設置過時
5. Redis 支持集羣,並且能夠自動切換
6. 跨平臺 支持多種語言客戶端
Redis 用途:
緩存(StackOverFlow),數據庫(微博),消息中間件(隊列,微博)java

二,redis的安裝mysql

1,經過 xshell 創建鏈接,下載 redis 並執行解壓redis

wget  http://download.redis.io/releases/redis-3.2.8.tar.gz算法

2,解壓的命令 :tar -zxvf redis-3.2.8.tar.gzspring

3,編譯安裝,解壓以後進入redis-3.2.8的目錄,在進入src目錄,而後make.注意:執行 e make  命令前  若是沒有gcc,安裝會報錯sql

三,啓動服務shell

進入src目錄執行./redis-server &數據庫

啓動成功的界面以下:數組

四,redis的基本命令

exists key 檢測指定 key 是否存在,返回 1 表示存在, 0 不存在
del key1 key2 ...... keyN 刪除給定 key,返回刪除 key 的數目, 0 表示給定 key 都不存在

type key 返回給定 key 值的類型。 返回 none 表示 key 不存在,string 字符類型, list 鏈表類型 set 無序集合類型......
keys pattern 返回匹配指定模式的全部 key
randomkey 返回從當前數據庫中隨機選擇的一個 key,若是當前數據庫是空的,返回空串
rename oldkey newkey 重命名一個 key,若是 newkey 存在,將會被覆蓋,返回1 表示成功,0 失敗。多是 oldkey 不存在或者和 newkey 相同。

renamenx oldkey newkey 同上,可是若是 newkey 存在返回失敗。
expire key seconds 爲 key 指定過時時間, 單位是秒。 返回 1 成功, 0 表示key 已經設置過過時時間或者不存在。
ttl key 返回設置過過時時間 key 的剩餘過時秒數。 -1 表示 key 不存在或者未設置過時時間。
select db-index 經過索引選擇數據庫, 默認鏈接的數據庫是 0,默認數據庫數是16 個。 返回 1表示成功, 0 失敗。
move key db-index 將 key 從當前數據庫移動到指定數據庫。返回 1 表示成功。0 表示 key不存在或者已經在指定數據庫中。

五,五種基本數據類型

redis 提供五種數據類型: string,hash,list,set 及sorted set

String 類型
string 是最基本的類型,並且 string 類型是二進制安全的。意思是 redis 的string 能夠包含任何數據。好比 jpg 圖片或者序列化的對象。從內部實現來看其實string 能夠看做 byte 組,最大上限是 1G 字節。1G=1024MB
string 類型數據操做指令簡介:
set key value 設置 key 對應 string 類型的值, 返回 1 表示成功, 0 失敗。
setnx key value 若是 key 不存在, 設置 key 對應 string 類型的值。 若是key 已經存在,返回 0。
get key 獲取 key 對應的 string 值,若是 key 不存在返回 nil
getset key value 先獲取 key 的值,再設置 key 的值。若是 key 不存在返回 nil。
mget key1 key2 ......keyN 一次獲取多個 key 的值,若是對應 key 不存在,則對應返回 nil。

mset key1 value1 ......keyN valueN 一次設置多個 key 的值,成功返回 1表示全部的值都設置了,失敗返回 0 表示沒有任何值被設置。
msetnx key1 value1 ......keyN valueN 一次設置多個 key 的值,可是不會覆蓋已經存在的 key
 incr key 對 key 的值作++操做, 並返回新的值。 注意 incr 一個不是 int 的
value 會返回錯誤, incr 一個不存在的 key,則設置 key 值爲 1。
decr key 對 key 的值作--操做, decr 一個不存在 key,則設置 key 值爲-1。
incrby key integer 對 key 加上指定值 , key 不存在時候會設置 key,並認爲原來的 value 是 0。
decrby key integer 對 key 減去指定值。decrby 徹底是爲了可讀性,咱們徹底能夠經過 incrby 一個負值來實現一樣效果,反之同樣

應用場景
String 是最經常使用的一種數據類型,普通的 key/value 存儲均可以歸爲此類,value 其實不只是 String,也能夠是數字:好比想知道何時封鎖一個 IP 地址(訪問超過幾回)。
INCRBY 命令讓這些變得很容易,經過原子遞增保持計數

Hash 類型
Hash  類型數據操做指令
hset key field value 設置 hash field 爲指定值,若是 key 不存在,則建立
hget key field 獲取指定的 hash field。
hmget key filed1....fieldN 獲取所有指定的 hash filed。
hmset key filed1 value1 ......filedN valueN 同時設置hash的多個 field。
hincrby key field integer 將指定的 hash filed 加上指定值。成功返回 hash
filed 變動後的值。
hexists key field 檢測指定 field 是否存在。
hdel key field 刪除指定的 hash field。
hlen key 返回指定 hash 的 field 數量
hkeys key 返回 hash 的全部 field。
hvals key 返回 hash 的全部 value。
hgetall  key 返回 hash 的全部 filed 和 value。

 

List類型

lpush key string 在 key 對應 list 的頭部添加字符串元素,返回 1 表示成功, 0表示 key 存在且不是 list 類型。
rpush key string 在 key 對應 list 的尾部添加字符串元素。
 llen key 返回 key 對應 list 的長度, 若是 key 不存在返回 0, 若是 key 對應類型不是 list 返回錯誤。

lrange key start end 返回指定區間內的元素, 下標從 0 開始, 負值表示從後面計算, -1 表示倒數第一個元素 , key 不存在返回空列表。
ltrim key start end 截取 list 指定區間內元素,成功返回 1, key 不存在返回錯誤。
lset key indexvalue 設置 list 中指定下標的元素值,成功返回 1, key 或者下標不存在返回錯誤。
 lrem key count value 從 List 的頭部 ( count 正數)或尾部 ( count 負數)刪除必定數量 ( count)匹配 value 的元素,返回刪除的元素數量。 count 爲 0時候刪除所有。
lpop key 從 list 的頭部刪除並返回刪除元素。若是 key 對應 list 不存在或者是空返回 nil,若是 key 對應值不是 list 返回錯誤。

rpop key 從 list 的尾部刪除並返回刪除元素。
blpop key1 ......keyN timeout 從左到右掃描,返回對第一個非空 list 進行
lpop  操做並返回,好比 blpop list1 list2 list3 0 ,若是 list 不存在list2,list3 都是非空則對 list2 作 lpop 並返回從 list2 中刪除的元素。若是全部的 list 都是空或不存在,則會阻塞 timeout 秒, timeout 爲 0 表示一直阻塞。當阻塞時,若是有 client 對 key1...keyN 中的任意 key 進行 push 操做, 則第一在這個 key 上被阻塞的 client 會當即返回。 若是超時發生, 則返回 nil。有點像unix 的 select 或者 poll。
brpop 同 blpop,一個是從頭部刪除一個是從尾部刪除

 

Set 類型
是無序集合,最大能夠包含(2 的 32 次方-1)個元素。 set 的是經過 hashtable 實現的,因此添加, 刪除, 查找的複雜度都是 O(1)。 hash table 會隨着添加或者刪除自動的調整大小。須要注意的是調整 hashtable 大小時候須要同步(獲取寫鎖)會阻塞其餘讀寫操做。可能不久後就會改用跳錶( skip list)來實現。 跳錶已經在 sortedsets 中使用了。關於 set 集合類型除了基本的添加刪除操做, 其它有用的操做還包含集合的取並集(union), 交集(intersection),差集(difference)。經過這些操做能夠很容易的實現 SNS 中的好友推薦和 blog 的 tag 功能

set  類型數據操做指令簡介

sadd key member 添加一個 string 元素到 key 對應 set 集合中,成功返回 1,若是元素以及在集合中則返回 0, key 對應的 set 不存在則返回錯誤。
srem key member 從 key 對應 set 中移除指定元素,成功返回 1,若是 member在集合中不存在或者 key 不存在返回 0,若是 key 對應的不是 set 類型的值返回錯誤。
spop key 刪除並返回 key 對應 set 中隨機的一個元素,若是 set 是空或者 key不存在返回 nil。
srandmember key 同 spop,隨機取 set 中的一個元素,可是不刪除元素。
 smove srckey dstkey member 從 srckey 對應 set 中移除 member 並添加到
dstkey 對應 set 中,整個操做是原子的。 成功返回 1,若是 member 在 srckey 中不存在返回 0, 若是 key 不是 set 類型返回錯誤。
Scard key 返回 set 的元素個數,若是 set 是空或者 key 不存在返回 0。
sismember key member 判斷 member 是否在 set 中,存在返回 1, 0 表示不存在或者 key 不存在。
sinter key1 key2 …… keyN 返回全部給定 key 的交集。
sinterstore dstkey key1 ....... keyN 返回全部給定 key 的交集, 並保存交集存到 dstkey 下。
sunion key1 key2 ...... keyN 返回全部給定 key 的並集。
sunionstore dstkey key1 ......keyN 返回全部給定 key 的並集, 並保存並集到 dstkey 下。
sdiff key1 key2 ......keyN 返回全部給定 key 的差集。
sdiffstore dstkey key1 ......keyN 返回全部給定 key 的差集,並保存差集到 dstkey 下。
smembers key 返回 key 對應 set 的全部元素,結果是無序的。

 

Sorted Set 類型

Sorted Set 是有序集合, 它在 set 的基礎上增長了一個順序屬性,這一屬性在添加修改元素的時候能夠指定, 每次指定後, 會自動從新按新的值調整順序。 能夠理解了有兩列的 mysql 表,一列存 value,一列存順序。操做中 key 理解爲sorted set 的名字,最多包含 2^32-1 個元素

Sorted t Set 類型數據操做指令簡介

zadd key score member 添加元素到集合,元素在集合中存在則更新對應 score。
zrem key member 刪除指定元素, 1 表示成功,若是元素不存在返回 0。
zincrby key incrmember 增長對應 member 的 score 值, 而後移動元素並保持 skip list 保持有序。返回更新後的 score 值。
zrank key member 返回指定元素在集合中的排名(下標), 集合中元素是按 score從小到大排序的。
zrevrankkey member 同上,可是集合中元素是按 score 從大到小排序。
zrange key start end 相似 lrange 操做從集合中去指定區間的元素。返回的是有序結果
zrevrange key start end 同上,返回結果是按 score 逆序的。
zrangebyscore key min max 返回集合中 score 在給定區間的元素。
zcount key min max 返回集合中 score 在給定區間的數量。
zcard key 返回集合中元素個數。
zscore key element 返回給定元素對應的 score

 

應用場景
以某個條件爲權重,好比按頂的次數排序.ZREVRANGE 命令能夠用來按照得分來獲取前 100 名的用戶,ZRANK 能夠用來獲取用
戶排名,很是直接並且操做容易。
Redis sorted set 的使用場景與 set 相似,區別是 set 不是自動有序的,而 sortedset 能夠經過用戶額外提供一個優先級(score)的參數來爲成員排序,而且是插入有序的,
即自動排序。好比:twitter 的 public timeline 能夠以發表時間做爲 score 來存儲,這樣獲取時就是自動按時間排好序的。
好比:全班同窗成績的 SortedSets,value 能夠是同窗的學號,而 score 就能夠是其考試得分,這樣數據插入集合的,就已經進行了自然的排序。
好比網易雲音樂排行榜實現;另外還能夠用 Sorted Sets 來作帶權重的隊列,好比普通消息的 score 爲 1,重要消息的 score 爲 2,而後工做線程能夠選擇按 score 的倒序來獲取工做任務。讓重要的任務優先執行

 

須要精準設定過時時間的應用
好比你能夠把上面說到的 sorted set 的 score 值設置成過時時間的時間戳,那麼就能夠簡單地經過過時時間排序,定時清除過時數據了,不只是清除 Redis 中的過時數據,你徹底能夠把 Redis 裏這個過時時間當成是對數據庫中數據的索引,用 Redis 來找出哪些數據須要過時刪除,而後再精準地從數據庫中刪除相應的記錄

 

 

Redis  搭建主從複用- - 讀寫分離

Redis 支持主從複用。數據能夠從主服務器向任意數量的從服務器上同步,同步使用的是發佈/訂閱機制。Mater Slave 的模式,從 Slave 向 Master 發起 SYNC 命令。能夠是 1 臺Master 多 Slave,能夠分層,Slave 下能夠再接 Slave,可擴展成樹狀結構。由於沒有兩臺電腦,因此只能在一臺機器上搭建兩個 Redis 服務端。這裏使用單機來模擬 redis 主從服務器 ,實現讀寫分離配置

在 home 目錄文件夾並拷貝兩份 redis 服務器文件到該目錄下,命名以下

修改主服務器的配置

一、slave-read-only yes  從服務器默認是隻讀的不容許輸入,主服務器的端口號是6379

 

修改從服務器的配置

1,修改從服務器配置,從服務器的端口號爲6380

 

slaveof 127.0.0.1 6379 這個只能配置在從服務器中,當主從配置中出現都是從服務器和都是主服務器的時候必定是這個地方出現問題了,將從服務器的這行命令打開或者主服務器上的這個命令要註釋掉就能夠了.

 而後分別分啓動主服務器和從服務器

主服務器的啓動

 

 從服務器的啓動

 

 

 

 Redis  主備切換服務器端配置

 1.redis  節點準備(單臺服務器不一樣端口模擬 2 2  臺服務器配置)
127.0.0.1 6379(master-主節點)
127.0.0.1 6380(slave-從節點)

 主節點的redis.config的配置

設置端口 ,daemonize(啓動後臺進程),密碼,鏈接主節點密碼,requirepass 禁用 bind 等 基本配置

配置密碼爲 liuqingfeng

禁用bind服務

端口

後臺進程開啓

 

 從節點的redis.config的配置

設置端口 ,daemonize,密碼,鏈接主節點密碼 禁用 bind 等 基本配置,slave of 屬性設置等

禁用bind

 

設置端口

開啓後臺進程

默認的數據庫個數爲16(默認設置便可,不用修改);

配置從服務器

配置鏈接主服務器的密碼

設置從服務器爲只讀

 

 sentinel.conf  哨兵文件配置

設置監控主服務器的名稱,ip地址,端口號,以及

配置對應的主服務器的密碼

 

redis的持久化

對於 Redis,其提供了不一樣級別的持久化操做:

1.RDB 持久化能夠在指定的時間間隔內生成數據集的時間點快照
2.AOF 持久化記錄服務器執行的全部寫操做命令,並在服務器啓動時,經過從新執行這些命令來還原數據集。AOF 文件中的命令所有以 Redis 協議的格式來保存,新命令會被追加到文件的末尾。Redis 還能夠在後臺對 AOF 文件進行重寫(rewrite),使得 AOF文件的體積不會超出保存數據集狀態所需的實際大小。
3. Redis 還能夠同時使用 AOF 持久化和 RDB 持久化。在這種狀況下,當 Redis 重啓時,它會優先使用 AOF 文件來還原數據集,由於 AOF 文件保存的數據集一般比 RDB文件所保存的數據集更完整。
4.持久化功能固然也能夠進行關閉操做,讓數據僅在服務器運行時存在.

 

RDB 持久化操做(快照 SnapShot 方式)

在默認狀況下, Redis 將數據庫快照保存在名字爲 dump.rdb 的二進制文件中。固然,這裏能夠經過修改 redis.conf 配置文件來對數據存儲條件進行定義,規定在「 N 秒內數據集至少有 M 個改動」這一條件被知足時,自動保存一次數據集。也能夠經過調用 save 或 bgsave ,手動讓 Redis 進行數據集保存操做

 

 

 Save |Bgsave 手動方式保存數據,經過 save 操做 ,當前 io 操做被阻塞,當 save 保存執行完畢纔會進行後續 io 操做

save 操做執行成功後能夠看到 dump.rdb 文件

bgsave 操做在背後開啓一個新的進行來對數據進行快照處理

快照運行方式
當 Redis 須要保存 dump.rdb 文件時, 服務器執行如下操做:
1. Redis 調用 fork() ,同時擁有父進程和子進程。
2. 子進程將數據集寫入到一個臨時 RDB 文件中。
3. 當子進程完成對新 RDB 文件的寫入時,Redis 用新 RDB 文件替換原來的 RDB 文件,並刪除舊的 RDB 文件。

RDB 優缺點
優勢:

1. RDB 是一個很是緊湊(compact)的文件,它保存了 Redis 在某個時間點上的數據集。該文件適合用於進行備份 。好比說,能夠在最近的 24 小時內,每小時備份一次 RDB 文件,而且在每月的每一天,也備份一個 RDB 文件。 這樣的話,即便趕上問題,也能夠隨時將數據集還原到不一樣的版本。
2. RDB 很是適用於災難恢復(disaster recovery):它只有一個文件,而且內容都很是緊湊,能夠(在加密後)將它傳送到別的數據中心
3. RDB 能夠最大化 Redis 的性能:父進程在保存 RDB 文件時惟一要作的就是 fork 出一個子進程,而後這個子進程就會處理接下來的全部保存工做,父進程無須執行任何磁盤 I/O操做。
4. RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。

 

缺點:
  1. 若是想要作到數據實時備份級別,此時使用 rdb 快照進行備份可能會出現數據沒法備份完整狀況,好比在數據備份完畢下次備份操做發起前,服務器因爲某種緣由意外宕機,此時採用 rdb 就沒法對當前狀況作的實時響應處理
  2. RDB 須要常常 fork 子進程來保存數據集到硬盤上,當數據集比較大的時候,fork 的過程是很是耗時的,可能會致使Redis在一些毫秒級內不能響應客戶端的請求.若是數據集巨大而且CPU性能不是很好的狀況下,這種狀況會持續 1 秒,AOF 也須要 fork,可是你能夠調節重寫日誌文件的頻率來提升數據集的耐久度.

 

AOF 只追加操做的文件

RDB 須要常常 fork 子進程來保存數據集到硬盤上,當數據集比較大的時候,fork 的過程是很是耗時的,可能會致使Redis在一些毫秒級內不能響應客戶端的請求.若是數據集巨大而且 CPU性能不是很好的狀況下,這種狀況會持續1 秒,AOF也須要fork,可是你能夠調節重寫日誌文件的頻率來提升數據集的耐久度.

appendonly yes
從如今開始, 每當 Redis 執行一個改變數據集的命令時(好比 SET), 這個命令就會被追加到 AOF 文件的末尾。這樣的話, 當 Redis 從新啓時, 程序就能夠經過從新執行
AOF 文件中的命令來達到重建數據集的目的

日誌重寫
由於 AOF 的運做方式是不斷地將命令追加到文件的末尾, 因此隨着寫入命令的不斷增長,AOF 文件的體積也會變得愈來愈大。舉個例子, 若是你對一個計數器調用了 100 次
INCR , 那麼僅僅是爲了保存這個計數器的當前值, AOF 文件就須要使用 100 條記錄(entry)。然而在實際上, 只使用一條 SET 命令已經足以保存計數器的當前值了, 其
餘 99 條記錄實際上都是多餘的

爲了處理這種狀況,Redis 支持一種有趣的特性:能夠在不打斷服務客戶端的狀況下,對AOF 文件進行重建(rebuild)。執行 BGREWRITEAOF 命令, Redis 將生成一個新的
AOF 文件, 這個文件包含重建當前數據集所需的最少命令。Redis 2.2 須要本身手動執行 BGREWRITEAOF 命令; Redis 2.4 則能夠自動觸發 AOF 重寫。參考:
http://www.redis.cn/topics/persistence.html

AOF 重寫文件配置:

 

使用 s Jedis  客戶端工具操做

1,Redis 服務器配置文件修改,添加認證密碼,外界進行訪問時 經過密碼來進行訪問操做

2,ip  地址 的 bind  屬性修改,註釋掉,將 bind 127.0.0.1 屬性禁用,(若是不由用,僅限本機 ip 訪問 redis 服務器) 可以讓外界客戶端進行訪問

3. 關閉防火牆
service iptables stop

4. 從新啓動 redis服務器

 

Java客戶端代碼的實現

1,建立普通的maven項目

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>

 

經過Junit進行單元測試

blic void test01() {
// 新建 redis 客戶端鏈接對象
Jedis jedis=new Jedis("192.168.1.120", 6379);
// 設置認證密碼
jedis.auth("123456");
// 經過 set 方法 添加字符串類型數據
jedis.set("shsxt", "實戰化教學第一品牌!");
// 獲取緩存數據並輸出
System.out.println(jedis.get("shsxt"));
}

@Test
public void test02(){
// 初始化 redis 客戶端鏈接詞
JedisPool jedisPool=new JedisPool(new JedisPoolConfig(),
"192.168.2.180", 6379,10000, "123456");
// 從鏈接池獲取鏈接
Jedis jedis=jedisPool.getResource();
jedis.set("redis", "redis is so easy");
System.out.println("redis:"+jedis.get("redis"));
}

 

封裝 RedisUtil 對外提供鏈接對象獲取方法

package com.shsxt.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.sql.Time;

/**
 * @author Created by lqf on 2018/10/26.
 */
public final class RedisUtil  {
    //redis的服務器ip
    private static String ADDR="192.168.1.3";
    //redis的端口號
    private static Integer PORT=6379;

    //訪問密碼
    private static String AUTH="liuqingfeng";

    //設置最大的鏈接數
    private static int MAX_ACTIVE=1024;

    //設置一個鏈接池中最大有多少個空閒的鏈接
    private static int MAX_IDLE=200;
    //等待可用鏈接最大時間
    private static int MAX_WAIT = 10000;
    private static int TIMEOUT=10000;

    //確認鏈接是否可用,爲true,表示不用校驗
    private static boolean  TEST_ON_BORROW = true;


    private static JedisPool jedisPool=null;

    //初始化redis的鏈接池
    static{
        try {
            JedisPoolConfig config=new JedisPoolConfig();
            config.setMaxTotal(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWaitMillis(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            jedisPool=new JedisPool(config,ADDR,PORT, TIMEOUT,AUTH);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

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


    //釋放資源
    public static void returnResouce(final Jedis jedis){
        if(jedis!=null){
            jedisPool.close();
        }
    }

}

測試

import com.shsxt.util.RedisUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author Created by lqf on 2018/10/26.
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application-bak.xml"})
public class test02 {
    private Jedis jedis;
    @Before
    public void init(){
        jedis= RedisUtil.getJedis();
    }
    @Test
    public void test_redis(){
        //set,get
        jedis.set("shsxt","實戰化教學");
        jedis.append("shsxt","第一品牌");
        System.out.println(jedis.get("shsxt"));

        System.out.println("*******************************************");

        //mset,mget
        jedis.mset("name","liuqingfeng","age","18","sex","man");
        List<String> list=jedis.mget("name","age","sex");
        if(list!=null || list.size()>0){
            for(String str:list){
                System.out.println(str);
            }
        }
        System.out.println("*******************************************");

        //incr, incyBy
        System.out.println(jedis.get("age")+"before");
        System.out.println(jedis.incr("age")+"incr"+"after");
       jedis.incrBy("age",20);
       System.out.println(jedis.get("age"));

        System.out.println("*******************************************");



    }
      @Test
    public void test02(){
        Map<String,String> map=new HashMap<String,String>();
        map.put("id","1");
        map.put("username","柳慶峯");
        map.put("addr","上海尚學堂");
        map.put("age","18");
        System.out.println("結果"+jedis.hmset("user1",map));
        System.out.println("結果"+jedis.hget("user1","username"));
       // System.out.println("刪除"+jedis.del("user1","age"));
        System.out.println(jedis.hexists("user1","age"));
        //返回的是一個set集合,能夠用迭代器
       Set<String> set= jedis.hkeys("user1");
       Iterator<String> iterator =set.iterator();
       while(iterator.hasNext()){
           System.out.println("***");
           String key=iterator.next();
           System.out.println("key:"+key+"   value:"+jedis.hget("user1",key));
       }

        RedisUtil.returnResouce(jedis);
    }


    /*
    list 操做
    * */
    @Test
    public void test03(){
        jedis.del("java");
        jedis.lpush("java","java se");
        jedis.lpush("java","java me");
        jedis.lpush("java","java ee");
        System.out.println(jedis.lrange("java",0,-1));
        RedisUtil.returnResouce(jedis);
    }

    //set操做
    @Test
    public void test04(){
        jedis.sadd("user","老劉");
        jedis.sadd("user","老六");
        jedis.sadd("user","老牛");
        System.out.println(jedis.smembers("user"));
        //判斷一個集合中是否存在某個值
        System.out.println(jedis.sismember("user", "老六"));

        //從set中隨機抽取一個元素,不會刪除
        System.out.println(jedis.srandmember("user"));
        //刪除並返回一個元素
        System.out.println(jedis.spop("user"));
        System.out.println(jedis.smembers("user"));
        //返回set中元素的個數
        System.out.println(jedis.scard("user"));

        RedisUtil.returnResouce(jedis);
    }
    @Test
    public void test05(){
        jedis.zadd("百家姓",100,"趙");
        jedis.zadd("百家姓",90,"錢");
        jedis.zadd("百家姓",80,"孫");
        jedis.zadd("百家姓",70,"李");

        System.out.println(jedis.zrange("百家姓",0,-1));
        System.out.println(jedis.zrevrange("百家姓",0,-1));
        System.out.println(jedis.zrangeByScore("百家姓", 70, 90));
    }

    @Resource
    private RedisTemplate<String, Object> template;
    @Test
    public void test06() {
        ValueOperations<String, Object> stringOperations= template.opsForValue();
        stringOperations.set("str", "string 數據類型");
        System.out.println(stringOperations.get("str"));
    }

    @Test
    //過時秒數的實現
    public void test07(){
        BoundValueOperations<String,Object> sbvo=template.boundValueOps("13689854565");
        sbvo.append("123456");
        System.out.println("驗證碼: "+sbvo.get());
        sbvo.expire(20, TimeUnit.SECONDS);
    }
}

Spring環境下配置讀寫分離

application的配置

<?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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 鏈接池配置 -->
    <bean id="jedisPoolConfig"
          class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大鏈接數 -->
        <property name="maxTotal" value="1024" />
        <!-- 最大 空閒鏈接數 -->
        <property name="maxIdle" value="200" />
        <!-- 獲取鏈接時最大等待毫秒數 -->
        <property name="maxWaitMillis" value="10000" />
        <!-- 在獲取鏈接時檢查有效性 -->
        <property name="testOnBorrow" value="true" />
    </bean>
    <bean id="redisSentinelConfiguration" class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
        <property name="master">
            <bean
                    class="org.springframework.data.redis.connection.RedisNode">
                <property name="name" value="mymaster"></property>
            </bean>
        </property>
        <property name="sentinels">
            <set>
                <bean
                        class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host"
                                     value="192.168.1.3"></constructor-arg>
                    <constructor-arg name="port"
                                     value="26379"></constructor-arg>
                </bean>
                <bean
                        class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host"
                                     value="192.168.1.3"></constructor-arg>
                    <constructor-arg name="port"
                                     value="26380"></constructor-arg>
                </bean>
            </set>
        </property>
    </bean>
    <!-- 客戶端鏈接工廠 -->
    <bean id="jedisConnFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <!-- 鏈接池引用 -->
        <constructor-arg name="poolConfig" ref="jedisPoolConfig"
        />
        <constructor-arg name="sentinelConfig"
                         ref="redisSentinelConfiguration"/>
        <property name="password" value="liuqingfeng"></property>
    </bean>
    <!-- redisTemplate 配置 -->
    <bean id="redisTemplate"
          class="org.springframework.data.redis.core.RedisTemplate"
          p:connection-factory-ref="jedisConnFactory" >
        <!-- 配置序列化操做 -->
        <property name="keySerializer">
            <bean
                    class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="valueSerializer">
            <bean
                    class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
        <property name="hashKeySerializer">
            <bean
                    class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="hashValueSerializer">
            <bean
                    class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
    </bean>

</beans>

test code

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:application.xml"})
    public class TestSpringDataRedis {
    @Resource
    private RedisTemplate<String, String> redisTemplate;

   @Test
    public void test01() {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("redis02", "hello redis");
    }
}
相關文章
相關標籤/搜索