Redis經過將數據存儲在內存中而得到了極快的速度,但爲了保證Redis在重啓後數據不丟失,須要將數據從內存持久化到硬盤中。redis
持久化的方式有兩種,兩者能夠只用一種,也能夠組合使用:docker
RDB是Redis默認採用的持久化方式,當符合必定條件時Redis會自動將內存中的全部數據進行快照(snapshotting)並存儲在硬盤上。進行快照的條件能夠由用戶在配置文件中自定義,配置由兩個參數構成:時間和改動的鍵的個數。當在指定的時間內被更改的鍵的個數大於指定的數值時就會進行快照。在配置文件redis.conf中已經預置了3個條件:數據庫
save 900 1 save 300 10 save 60 10000
這些條件直接是「或」的關係。若是須要禁用自動快照,能夠將全部的save配置刪除。緩存
除了自動快照,還能夠手動發送SAVE或BGSAVE命令讓Redis執行快照,SAVE命令是由主進程進行快照操做,會阻塞住其餘請求,而BGSAVE命令則會經過fork子進程進行快照操做。安全
Redis默認會將快照文件存儲在當前目錄的dump.rdb文件中,能夠經過配置dir和dbfilename兩個參數分別指定快照文件的存儲路徑和文件名。bash
RDB快照的過程爲:服務器
Redis在進行快照的過程當中不會修改RDB文件,只有快照結束後纔會將舊的文件替換成新的,也就是說任什麼時候候RDB文件都是完整的,因此能夠經過定時備份RDB文件來實現Redis數據庫備份。RDB文件是通過壓縮的二進制格式,佔用的空間會小於內存中的數據大小。但壓縮過程也會增長CPU佔用,若有須要能夠經過修改配置rdbcompression參數以禁用壓縮。併發
config set rdbcompression no
AOF全稱爲append only file,在這種持久化方式下,每執行一條會更改Redis中的數據的命令,Redis都會將該命令寫入硬盤中的AOF文件。
AOF文件的保存位置和RDB文件的位置相同,均可以經過dir參數設置,默認的文件名是appendonly.aof,能夠經過appendfilename參數修改。
AOF文件是純文本文件,其內容是Redis客戶端向Redis發送的原始通訊協議的內容。設想執行這樣幾條命令:app
SET key1 1 SET key1 2 SET key1 3
AOF文件中會記錄這三次操做,但實際上前兩條其實是多餘的,只須要記錄最終一次的命令便可。隨着執行的命令愈來愈多,AOF文件也會愈來愈大,而Redis能夠經過去除這類多餘命令記錄,自動對AOF文件進行優化。負載均衡
每當達到必定條件時Redis就會自動重寫AOF文件,這個條件能夠在配置文件中設置:
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage設置當目前的AOF文件大小超過上一次重寫時的AOF文件大小的百分之多少時會再次進行重寫,若是以前沒有重寫過,則以啓動時的AOF文件大小爲依據。
auto-aof-rewrite-min-size則限制了容許重寫的最小AOF文件大小,一般在AOF文件很小的狀況下即便其中有不少冗餘的命令也不須要重寫。
除了讓Redis自動執行重寫外,還能夠主動使用BGREWRITEAOF命令手動執行AOF重寫。
在重啓時Redis會逐個執行AOF文件中的命令來將硬盤中的數據載入到內存中,載入的速度相較RDB會慢一些。
雖然每次執行更改數據庫內容的操做時,AOF都會將命令記錄在AOF文件中,但實際上因爲操做系統的緩存機制的存在,數據並無真正地寫入硬盤,而是進入了系統的硬盤緩存。在默認狀況下系統每30秒會執行一次同步操做,以便將硬盤緩存中的內容真正地寫入硬盤,在這30秒的過程當中若是系統異常退出則會致使硬盤緩存中的數據丟失。通常來說啓用AOF持久化的應用都沒法容忍這樣的損失,這就須要Redis在寫入AOF文件後主動要求系統將緩存內容同步到硬盤中。
能夠經過appendfsync參數設置同步的時機:
config set appendfsync always/eversec/no
若是選擇RDB的持久化方式,一旦Redis異常退出,就會丟失最後一次快照之後更改的全部數據。這就須要開發者根據具體的應用場合,經過組合設置自動快照條件的方式來將可能發生的數據損失控制在可以接受的範圍。若是數據很重要以致於沒法承受任何損失,則能夠考慮使用AOF方式進行持久化。
能夠同時開啓AOF和RDB,這樣既保證了數據安全,又使得進行備份等操做十分容易。此時從新啓動Redis後Redis會使用AOF文件來恢復數據,由於AOF方式的持久化可能丟失的數據更少。
Redis的持久化功能能夠保證在服務器重啓的狀況下不會損失(或少許損失)數據。可是因爲數據只存儲在一臺服務器,若是這臺服務器的硬盤出現故障,也會致使數據丟失。爲了不單點故障,將數據庫複製多個副本以部署在不一樣的服務器上,組成集羣,這樣即便有一臺服務器出現故障時,其餘服務器依然能夠繼續提供服務,此外也提高了總體的性能。
Redis提供了複製(replication)功能用以保障構成集羣的多臺服務器之間數據的同步。
構成集羣的數據庫分爲兩類,主數據庫(master)和從數據庫(slave)。主數據庫能夠進行讀寫操做,當發生寫操做時自動將數據同步給從數據庫。而從數據庫通常是隻讀的,並接受主數據庫同步過來的數據。主從數據庫是一對多的關係。
要把一個數據庫做爲從數據庫,須要在啓動參數或者配置文件中加入:
slaveof 主數據庫的IP 端口
接下來使用redis的docker鏡像試驗主從複製,首先啓動兩個實例:
docker run --name redis-6379 -p 6379:6379 -d redis docker run --name redis-6380 -p 6380:6379 -d redis
redis-6379將被做爲主數據庫,redis-6380爲從庫,首先獲取redis-6379容器的內網IP地址:
docker inspect redis-6379
在"NetworkSettings"結點下能夠看到IP和端口爲172.17.0.2 6379
進入redis-6380,設置其爲從數據庫:
> docker exec -it redis-6380 /bin/bash root@cd19cbbab6d9:/data# redis-cli 127.0.0.1:6379> SLAVEOF 172.17.0.2 6379
這樣主從數據庫就設置好了,能夠測試下在主數據庫插入一個鍵,而後在從數據庫讀取。
從數據庫默認是隻讀的,嘗試寫入將提示:
SET KEY1 1 (error) READONLY You can't write against a read only replica.
能夠經過設置從數據庫的配置文件中的slave-read-only爲no以使從數據庫可寫,可是對從數據庫的任何更改都不會同步給其餘數據庫,而且一旦主數據庫中更新了對應的數據就會覆蓋從數據庫中的改動。
在redis實例運行也可使用SLAVEOF命令,若是該數據庫已是其餘主數據庫的從數據庫,則SLAVEOF命令會中止和原來數據庫的同步轉而和新數據庫同步。還可使用SLAVEOF NO ONE來使當前數據庫中止接收其餘數據庫的同步轉成主數據庫。
數據冗餘:主從複製實現了數據的熱備份,是持久化以外的一種數據冗餘方式。
故障恢復:當主節點出現問題時,能夠由從節點提供服務,實現快速的故障恢復;其實是一種服務的冗餘。
讀寫分離:能夠用於實現讀寫分離,主庫寫、從庫讀,讀寫分離不只能夠提升服務器的負載能力,同時可根據需求的變化,改變從庫的數量;
負載均衡:在主從複製的基礎上,配合讀寫分離,能夠由主節點提供寫服務,由從節點提供讀服務分擔服務器負載;尤爲是在寫少讀多的場景下,經過多個從節點分擔讀負載,能夠大大提升Redis服務器的併發量。
高可用基石:除了上述做用之外,主從複製仍是哨兵和集羣可以實施的基礎,所以說主從複製是Redis高可用的基礎。
在安全方面,Redis提供了下面幾種策略。
Redis安全設計都是創建在「Redis運行在可信環境」這個前提下的,在生產環境運行時不能容許外界直接鏈接到Redis服務器上,而應該經過應用程序進行中轉,運行在可信的環境中是保證Redis安全的最重要方法。
Redis的默認會接受來自任何地址發送來的請求,要更改這一設置,能夠在配置文件中修改bind參數,如只容許本機應用鏈接Redis,能夠將bind參數改爲:
bind 127.0.0.1
要設置密碼,能夠修改配置文件中的requirepass參數,例如:
requirepass 123456
docker鏡像也能夠在啓動容器的時候設置密碼:
docker run --name redis-test -p 6379:6379 redis --requirepass 123456
添加密碼後,客戶端在鏈接時須要輸入密碼:
redis-cli -h 127.0.0.1 -p 6379 -a 123456
設置密碼後,若是要搭建主從數據庫,須要在從數據庫配置文件中的masterauth添加主數據庫的密碼。
須要注意的是,因爲Redis的性能極高,而且輸入錯誤密碼後Redis並不會進行主動延遲,因此攻擊者能夠經過窮舉法破解Redis的密碼(1秒內可以嘗試十幾萬個密碼),所以在設置時必定要選擇複雜的密碼。
Redis支持在配置文件中將命令重命名,好比將FLUSHALL命令重命名成一個比較複雜的名字,以保證只有本身的應用可使用該命令:
rename-command FLUSHALL oiuyhjkghjgyutdfhbuhbnjinjbgyvtcrd
若是但願直接禁用某個命令,能夠將命令重命名成空字符串。