目錄
1. redis發佈訂閱(pub/sub)
redis發佈訂閱(pub/sub)是一種消息通信模式:發送者發送消息,訂閱者接收消息。
發佈訂閱也叫生產者消費者模式,是實現消息隊列的一種方式。
1.1 發佈訂閱命令
命令 |
說明 |
subscribe channel1 [channel2…] |
訂閱給定的一個或多個頻道的信息 |
psubscribe pattern1 [pattern2…] |
訂閱一個或多個符合給定模式的頻道的信息 |
publish channel message |
將信息發送到指定的頻道 |
pubsub subcommand [argument1 [argument2…]] |
查看訂閱與發佈系統狀態 |
unsubscribe [channel1 [channel2…]] |
推定一個或多個給定的頻道 |
punsubscribe [pattern1 [pattern2…]] |
退訂一個或多個符合給定模式的頻道的信息 |
1.2 發佈訂閱實例
開啓redis客戶端,讓消息訂閱者訂閱某個頻道
[root@CentOS7 src]# ./redis-cli
127.0.0.1:6379> SUBSCRIBE channel
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel"
3) (integer) 1
重新開啓另一個redis客戶端,讓消息發佈者向頻道發佈消息
[root@CentOS7 src]# ./redis-cli
127.0.0.1:6379> PUBLISH channel "hello,everyone"
(integer) 2
127.0.0.1:6379> PUBLISH channel "你好"
(integer) 2
然後觀察消息的發佈和訂閱情況
2. redis 事務
2.1 事務與redis事務
事務:事務是指一系列操作步驟,這一系列的操作步驟,要麼完全地執行,要麼完全地不執行。
要保證一系列的操作都完全成功,提出了事務控制的概念。
redis事務:redis中的事務(transaction)是一組命令的集合,至少是兩個或兩個以上的命令。redis事務保證這些命令被執行時中間不會被任何其他操作終端。
2.2 事務命令
事務命令 |
說明 |
multi |
標記一個事務的開始 |
exec |
執行所有事務塊內的命令 |
watch key1 [key2…] |
監視一個或多個key,如果在事務執行之前這些key被其他命令所改動,那麼事務將被打斷 |
unwatch |
取消watch命令對所有key的監視 |
discard |
取消事務,放棄執行事務塊內的所有命令 |
3. redis對事務控制的實現
一個事務從開始到執行會經歷以下三個步驟:開始事務、執行命令、提交事務
3.1 正常情況
# 用multi命令告訴redis,接下來要執行的命令先不要執行,而是將它們暫時存儲起來(開啓事務)
127.0.0.1:6379> MULTI
OK
# 第一條命令進入等待隊列(命令入隊)
127.0.0.1:6379> set k1 v1
QUEUED
# 第二條命令進入等待隊列(命令入隊)
127.0.0.1:6379> set k2 v2
QUEUED
# 告知redis執行前面發送的兩條命令(提交事務)
127.0.0.1:6379> EXEC
1) OK
2) OK
#測試可以獲取到k1和k2的值
127.0.0.1:6379> mget k1 k2
1) "v1"
2) "v2"
3.2 異常情況(回滾)
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k3 v3
QUEUED
# 命令語法錯誤
127.0.0.1:6379> set k4
(error) ERR wrong number of arguments for 'set' command
# 無法執行事務,那麼第一條正確的命令也不會執行
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
#獲取不到k3和k4的值
127.0.0.1:6379> mget k3 k4
1) (nil)
2) (nil)
3.3 例外情況(部分支持事務)
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k5 v5
QUEUED
# 此命令錯誤,字符串不能自增,但是命令入隊成功(語法上無錯誤)
127.0.0.1:6379> incr key
QUEUED
# 事務依然提交,然是key的值時字符串,自增操作執行失敗,但整個事務沒有回滾
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range
127.0.0.1:6379> get k5
"v5"
3.4 放棄情況
127.0.0.1:6379> set k6 v6
QUEUED
127.0.0.1:6379> set k6 vv
QUEUED
# 放棄事務,則命令隊列都不會被執行
127.0.0.1:6379> discard
OK
# 獲取不到k6的值
127.0.0.1:6379> get k6
(nil)
3.5 複雜情況
1. 悲觀鎖
悲觀鎖(pessimistic lock),每次去拿數據的時候都認爲別人會修改數據,所以每次在拿數據的時候都會先上鎖,這樣別人想拿這個數據就會block阻塞直到它拿到鎖。傳統的關係型數據庫裏邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖,讓別人無法操作該數據。
2. 樂觀鎖
樂觀鎖(optimistic lock),每次去拿數據的時候都認爲別人不會修改該數據,所以不會上鎖,但是在更新數據的時候會判斷在此期間有沒有去更新這條數據,一般使用版本號機制進行判斷。樂觀鎖適用於多讀的應用類型,可以提高吞吐量。
樂觀鎖大多情況是基於數據版本號(version)的機制實現的。數據版本,即爲數據增加一個版本標識,在基於數據庫表的解決方案種,一般是通過爲數據庫表添加一個"version"字段來實現讀取出數據時,將此版本號一同讀出。之後更新時,對此版本號加1。此時,將提交數據的版本號與數據庫表對應記錄的當前版本號進行比對,如果提交的數據版本號大於數據庫表當前版本號,則予以更新,否則認爲是過期數據,不予更新。
3. watch機制實現樂觀鎖
127.0.0.1:6379> set k7 v7
OK
127.0.0.1:6379> watch k7
OK
127.0.0.1:6379> set k7 vvv
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k7 v
QUEUED
# 提交事務,但k7值不會被修改爲v,k7的值仍然是vvv,因爲在事務開啓之前k7的值被修改了
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get k7
"vvv"
4. reids持久化
4.1 持久化概述
持久化可以理解爲存儲,就是將數據存儲到一個不會丟失的地方,如果把數據放在內存種,電腦關閉或重啓數據就會丟失,所以放在內存中的數據不是持久的,而放在磁盤種的數據就算是一種持久化。
redis的數據存儲在內存中。內存是瞬時的,如果系統宕機或重啓,或redis崩潰或重啓,所有的內存數據都會丟失。爲解決這個問題,redis提供兩種機制對數據進行持久化存儲,便於發生故障後能迅速恢復數據。
4.2 redis兩種持久化方式
1. RDB
redis database(RDB),就是在指定的時間間隔將內存中的數據集快照寫入磁盤,數據恢復時將快照文件直接再讀到內存。
RDB方式的數據持久化,需修改redis.conf配置文件。
[root@CentOS7 redis-5.0.5]# vim redis.conf
# 指定再多長時間內,有多少次更新操作,就將數據同步到數據文件,可以將多個條件配合。redis默認配置文件中提供了三個條件:分別表示900s內有一個更改、300s內有10個更改以及60s內有10000個更改
218 save 900 1
219 save 300 10
220 save 60 10000
235 stop-writes-on-bgsave-error yes
# 指定存儲至本地數據庫時是否壓縮數據,默認爲yes
241 rdbcompression yes
250 rdbchecksum yes
# 設置RDB的文件名,默認dump.rdb
253 dbfilename dump.rdb
# 指定RDB和AOF文件目錄
263 dir ./
2. AOF
Append-only file(AOF),redis每接收一條改變數據的命令時,它將該命令寫到一個AOF文件中(只記錄寫操作,不記錄讀操作),當redis重啓時,它通過執行AOF文件中所有的命令來恢復數據。
AOF方式的數據持久化,需修改redis.conf配置文件。
[root@CentOS7 redis-5.0.5]# vim redis.conf
# 是否開啓AOF持久化,默認爲no(建議設置爲yes)
699 appendonly no
# 指定AOF文件名,默認appendonly.aof
703 appendfilename "appendonly.aof"
# 配置向AOF文件寫命令數據的策略,有三個可選值:
# no表示不主動進行同步操作,而是完全交由操作系統來做(每30s一次),比較快但不是很安全;
# always表示每次寫入都會執行同步,較慢但是比較安全;
# everysec表示每s執行一次同步操作,比較平衡,介於速度和安全之間;
729 appendfsync everysec
751 no-appendfsync-on-rewrite no
# 當目前AOF文件大小超過上一次重寫時的AOF文件大小的百分之多少時會再次進行重寫,如果之前沒有重寫,則以啓動時的AOF文件大小爲依據
770 auto-aof-rewrite-percentage 100
# 允許重寫的最小AOF文件大小,默認64Mb
771 auto-aof-rewrite-min-size 64mb
795 aof-load-truncated yes
806 aof-use-rdb-preamble yes
AOF實例
首先隨便設置幾個鍵的值value
[root@CentOS7 src]# ./redis-cli
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> exit
查看對應的AOF文件
[root@CentOS7 src]# cat appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
*3
$3
set
$2
k2
$2
v2