上篇文章介紹了redis的基本情況和支持的數據類型,本篇文章將介紹redis持久化、主從復制、簡單的事務支持及發布訂閱功能。
持久化
•redis是一個支持持久化的內存數據庫,也就是說redis需要經常將內存中的數據同步到磁盤來保證持久化,這是相對memcache來說的一個大的優勢。redis支持兩種持久化方式,一種是 Snapshotting(快照)也是默認方式,另一種是Append-only file(縮寫aof)的方式。
Snapshotting
快照是默認的持久化方式。這種方式將內存中數據以快照的方式寫入到二進制文件中,默認的文件名為dump.rdb。可以配置自動做快照持久 化的方式。我們可以配置redis在n秒內如果超過m個key被修改就自動做快照,下面是默認的快照保存配置
save 900 1 #900秒內如果超過1個key被修改,則發起快照保存
save 300 10 #300秒內容如超過10個key被修改,則發起快照保存
save 60 10000
Append-only file
aof 比快照方式有更好的持久化性,是由於在使用aof持久化方式時,redis會將每一個收到的寫命令都通過write函數追加到文件中(默認是 appendonly.aof)。當redis重啟時會通過重新執行文件中保存的寫命令來在內存中重建整個數據庫的內容。當然由於os會在內核中緩存 write做的修改,所以可能不是立即寫到磁盤上。這樣aof方式的持久化也還是有可能會丟失部分修改。不過我們可以通過配置文件告訴redis我們想要 通過fsync函數強制os寫入到磁盤的時機。有三種方式如下(默認是:每秒fsync一次)
appendonly yes //啟用aof持久化方式
# appendfsync always //每次收到寫命令就立即強制寫入磁盤,最慢的,但是保證完全的持久化,不推薦使用
appendfsync everysec //每秒鍾強制寫入磁盤一次,在性能和持久化方面做了很好的折中,推薦
# appendfsync no //完全依賴os,性能最好,持久化沒保證
主從復制
•
主從復制允許多個
slave server
擁有和
master server
相同的數據庫副本。下面是關於
redis
主從復制的一些特點
–
1.master
可以有多個
slave
–
2.
除了多個
slave
連到相同的
master
外,
slave
也可以連接其他
slave
形成圖狀結構
–
3.
主從復制不會阻塞
master
。也就是說當一個或多個
slave
與
master
進行初次同步數據時,
master
可以繼續處理
client
發來的請求。相反
slave
在初次同步數據時則會阻塞,不能處理
client
的請求。
–
4.
主從復制可以用來提高系統的可伸縮性(我們可以用多個
slave
專門用於
client
的讀請求,比如
sort
操作可以使用
slave
來處理),也可以用來做簡單的數據冗余。
-5.可以在master禁用數據持久化,只需要注釋掉master 配置文件中的所有save配置,然后只在slave上配置數據持久化。
事物
•
redis
對事務的支持目前還比較簡單。
redis
只能保證一個
client
發起的事務中的命令可以連續的執行,而中間不會插入其他
client
的命令。
–
Multi
事物開始
–
Exec
執行事務
–
Discard
放棄事物
–
Watch
監聽
key
–
Unwatch
放棄所有
key
的監聽
•
watch
命令會監視給定的
key,
當
exec
時候如果監視的
key
從調用
watch
后發生過變化,則整個事務會失敗。注意
watch
的
key
是對整個連接有效的,和事務一樣,如果連接斷開,監視和事務都會被自動清除。
發布訂閱(pub/sub )
•
發布訂閱
(pub/sub)
是一種消息通信模式。訂閱者可以通過
subscribe
和
psubscribe
命令向
redis
server
訂閱自己感興趣的消息類型,
redis
將消息類型稱為通道
(channel)
。當發布者通過
publish
命令向
redis
server
發送特定類型的消息時。訂閱該消息類型的全部
client
都會收到此消息。這里消息的傳遞是多對多的。一個
client
可以訂閱多個
channel,
也可以向多個
channel
發送消息。
–
Subscribe
–
Unsubscribe
–
Psubscribe
–
Punsubscribe
–
Publish
管道(pipeline)
•
redis
是一個
cs
模式的
tcp
server
,使用和
http
類似的請求響應協議。一個
client
可以通過一個
socket
連接發起多個請求命令。每個請求命令發出后
client
通常 會阻塞並等待
redis
服務處理,
redis
處理完后請求命令后會將結果通過響應報文返回給
client
。基本的通信過程如下
Client: INCR X
Server: 1
Client: INCR X
Server: 2
Client: INCR X
Server: 3
Client: INCR X
Server: 4
•
基本上四個命令需要
8
個
tcp
報文才能完成。由於通信會有網絡延遲
,
假如從
client
和
server
之間的包傳輸時間需要
0.125
秒。那么上面的四個命令
8
個報文至少會需要
1
秒才能完成。
利用pipeline的方式從client打包多條命令一起發出,不需要等待單條命令的響應返回,而redis服務端會處理完多條命令后會將多條命令的處理結果打包到一起返回給客戶端。通信過程如下
Client: INCR X
Client: INCR X
Client: INCR X
Client: INCR X
Server: 1
Server: 2
Server: 3
Server: 4
虛擬內存(VM)
VM的作者已經放棄該功能
•
redis
沒有使用
os
提供的虛擬內存機制而是自己實現了自己的虛擬內存機制 ,但是思路和目的都是相同的。就是暫時把不經常訪問的數據從內存交換到磁盤中,從而騰出內存空間用於其他需要訪問的數據。尤其是對於
redis
這樣的內存數據庫,內存總是不夠用的。除了可以將數據分割到多個
redis
server
外。另外的能夠提高數據庫容量的辦法就是使用
vm
把那些不經常訪問的數據交換的磁盤上。如果我們的存儲的數據總是有少部分數據被經常訪問,大 部分數據很少被訪問,對於網站來說確實總是只有少量用戶經常活躍。當少量數據被經常訪問時,使用
vm
不但能提高單台
redis
server
數據庫的容量,而且也不會對性能造成太多影響。
–
vm
-enabled yes #
開啟
vm
功能
–
vm
-swap-file /
tmp
/
redis.swap
#
交換的
value
保存的文件路徑
/
tmp
/
redis.swap
–
vm
-max-memory 1000000 #
最大內存上限,超過后開始交換
value
到磁盤文件
–
vm
-page-size 32 #
每個頁面的大小
32
個字節
–
vm
-pages 134217728 #
最多使用在文件中使用多少頁面
vm
-max-threads 4 #
用於執行
value
對象換入換出的工作線程數量,
0
表示不使用工作線程