1、安全性
設置客戶端連接后進行任何其他操作前先驗證密碼。
因為Redis速度相當快,所以在一台比較好的服務器下,一個外部用戶可以在一秒鍾進行150K次的密碼嘗試,這意味着需要指定一個非常強大的密碼來防止暴力破解。
2、主從復制
Redis主從復制配置和使用都非常簡單,通過主從復制可以允許多個slave server擁有和master server相同的數據庫副本。
主從復制特點:
- master可以擁有多個slave
- 多個slave可以連接同一個master外,還可以連接到其他slave
- 主從復制不會阻塞master,在同步數據時master可以繼續處理client請求
- 提高系統的伸縮性
主從復制過程:
- slave server啟動連接到master server之后,salve server主動發送SYNC命令給master server
- master server接受SYNC命令之后,判斷,是否有正在進行內存快照的子進程,如果有,則等待其結束,否則,fork一個子進程,子進程把內存數據保存為文件,並發送給slave server
- master server子進程進程做數據快照時,父進程可以繼續接收client端請求寫數據,此時,父進程把新寫入的數據放到待發送緩存隊列中
- slave server 接收內存快照文件之后,清空內存數據,根據接收的快照文件,重建內存表數據結構
- master server把快照文件發送完畢之后,發送緩存隊列中保存的子進程快照期間改變的數據給slave server,slave server做相同處理,保存數據一致性
- master server 后續接收的數據,都會通過步驟1建立的連接,把數據發送到slave server
需要注意:slave server如果因為網絡或其他原因斷與master server的連接,當slave server重新連接時,需要重新獲取master server的內存快照文件,slave server的數據會自動全部清空,然后再重新建立內存表,這樣會讓slave server 啟動恢復服務比較慢,同時也給master server帶來較大壓力,可以看出redis的復制沒有增量復制的概念,這是redis主從復制的一個主要弊端,在實際環境中,盡量規避中途增加從庫。redis2.8之前不支持增量,到2.8之后就支持增量了!
配置主從服務器:
master服務器不用進行任何配置
slave服務器,只需在slave服務器的配置文件中加入以下配置
#指定master服務器的ip和端口
slaveof 192.168.1.99 6379
#指定master服務器認證信息
masterauth xxx
主從配置的作用:
配置master只能為寫,slave只能為度,在客戶端請求的時候會將寫請求轉到master上面,讀請求轉到slave上面,同時master和slave有同步功能,這就實現了(數據層)讀寫分離對上層(邏輯層)透明的正常邏輯,無需再通過中間件或者代碼進行讀寫分離實現。
Redis cluster(集群)
Redis cluster至少需要3(Master)+3(Slave)才能建立集群,是無中心的分布式存儲架構,可以在多個節點之間進行數據共享,解決了Redis高可用、可擴展等問題。
redis集群提供了以下兩個好處
- 將數據自動切分(split)到多個節點
- 當集群中的某一個節點故障時,redis還可以繼續處理客戶端的請求。
集群中的主從復制
集群中的每個節點都有1個至N個復制品,其中一個為主節點,其余的為從節點,如果主節點下線了,集群就會把這個主節點的一個從節點設置為新的主節點繼續工作,這樣集群就不會因為一個主節點的下線而無法正常工作。
注意:
- 如果某一個主節點和他所有的從節點都下線的話,redis集群就會停止工作了。redis集群不保證數據的強一致性,在特定的情況下,redis集群會丟失已經被執行過的寫命令
- 使用異步復制(asynchronous replication)是redis 集群可能會丟失寫命令的其中一個原因,有時候由於網絡原因,如果網絡斷開時間太長,redis集群就會啟用新的主節點,之前發給主節點的數據就會丟失。
3、事物處理
Redis對事務的支持目前還比較簡單。Redis只能保證一個client發起的事務中的命令可以連續的執行,而中間不會插入其他的client的命令。當一個client在一個連接中發出multi命令時,這個連接會進入一個事務上下文,改連接后續的命令不會立即執行,而是先放到一個隊列中,當執行exex命令時,redis會順序的執行隊列中的所有命令。
multi開始事務的命令隊列
discard清空事務的命令隊列並退出事務上下文
exec執行事務隊列
樂觀鎖:大多數是基於數據版本(version)的記錄機制實現的。即為數據增加一個版本表示,在基於數據庫表的版本解決方案中,一般是通過為數據庫表添加一個“version”字段來實現讀取出數據時,將此版本號一同讀出,之后更新時,對此版本號加1.此時,將提交數據的版本號與數據庫表對應記錄的當前版本號進行對比,如果提交的數據版本號大於數據庫當前版本號,則予以更新,否則認為是過期數據。
watch:watch命令會監視給定的key,當exec時候如果監視的key從調用watch后發生過變化,則整個事務會失敗。也可以調用watch多次監視多個key,這樣就可以對指定的key加樂觀鎖了。注意watch的key是對整個連接有效的,事務也一樣。如果連接斷開,監視和事務都會被自動清除。exec,discar,unwatch命令都會清除連接中的所有監視。
事務回滾問題:
redis只能保證事務的每個命令連續執行,但是如果事務中的一個命令失敗了,並不回滾其他命令。
4、持久化機制
Redis是一個支持持久化的內存數據庫,也就是說redis需要經常將內存中的數據同步到硬盤來保證持久化。
Redis支持兩種持久化方式:
- snapshotting(快照)默認方式
快照是默認的持久化方式。這種方式是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名為dump.rdb。可以通過配置設置自動做快照持久化的方式。配置redis在n秒內如果超過m個key被修改就自動做快照。
save 900 1 #900秒內如果超過1個key被修改,則發起快照保存
save 900 10 #300秒內如果超過10個key被修改,則發起快照保存
- append-only file aof方式
由於快照方式是在一定時間間隔做一次的,所以如果redis意外宕機,就回丟失最后一次快照后的所有修改。AOF比快照方式有更好的持久化性,是由於使用AOF時,redis會將每一個收到的寫命令都通過write函數追加到文件中,當redis重啟時會通過重新執行文件中保存的寫命令來在內存中重建整個數據庫的內容。
當然由於os會在內核中緩存write做的修改,所以可能不是立即寫到磁盤上。這樣AOF方式的持久化也還是有可能會丟失部分修改,可以通過配置文件,使用fsync函數強制os寫入到磁盤的時機。
appendonly yes #啟用aof持久化方式
#appendfsync always //收到寫命令就立即寫入磁盤,最慢,但是保證完全的持久化
#appendfsync everysec //每秒鍾寫入磁盤一次,在性能和持久化方面做了很好的折中
#appendfsync no //完全依賴os,性能最好,持久化沒有保證
相關指令
./redis-cli bgsave //異步保存數據到磁盤(快照保存)
./redis-cli 1h 127.0.0.1 -p 6379 bgsave
./redis-cli lastsave //返回上次成功保存到磁盤的unix時間戳
./redis-cli shutdown //同步保存到服務器並關閉redis服務器
./redis-cli bgrewriteaof //當日志文件過長時優化AOF日志文件存儲
5、發布訂閱消息
發布訂閱(pub/sub)是一種消息通信模式,主要的目的是解除消息發布者和消息訂閱者之間的耦合,Redis作為一個pub/sub的server,在訂閱者和發布者之間起到了消息路由的功能。訂閱者可以通過subscribe和psubscribe命令向Redis server 訂閱自己感興趣的消息類型,redis將信息類型稱為通道(channel)。當發布者通過publish命令向Redis server發送特定類型的信息時,訂閱該信息類型的全部client都會收到此消息。
原理:下圖展示了三個客戶端client1, client2, client5訂閱了頻道channel1
當有新消息通過PUBLISH發送給channel1時,這時候channel1就會把消息同時發布給訂閱者
創建訂閱頻道redisChat
localhost:6379> subscribe redisChat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1
打開幾個客戶端,訂閱channel redisCha
localhost:6379> psubscribe redisChat
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "redisChat"
3) (integer) 1
然后給channel redisChat發送消息“Hello World”
localhost:6379> publish redisChat "Hello World"
(integer) 1
客戶端會收到消息
Reading messages... (press Ctrl-C to quit)
1) "pmessage"
2) "redisChat"
3) "redisChat"
4) "Hello World"
6、虛擬內存的使用
Redis的虛擬內存就是暫時把不經常訪問的數據從內存交換到磁盤中。
vm相關配置
vm-enabled yes #開啟vm功能
vm-swap-file /tmp/redis.swap #交換出來的value保存的文件路徑
vm-max-memory 1000000 #redis使用的最大內存上限
vm-page-size 32 #每個頁面的大小32字節
vm-pages 134217728 #最多使用多少頁面
vm-max-threads 4 #用於執行value對象換入換出工作線程數量