Redis入門(7) - 持久化、主從復(fù)制、安全

  • 持久化
    • RDB方式
      • Redis實現(xiàn)快照的過程
    • AOF方式
      • 操作系統(tǒng)緩存
      • RDB與AOF
  • 復(fù)制
    • 主從數(shù)據(jù)庫
    • 主從復(fù)制的意義
  • 安全

持久化

Redis通過將數(shù)據(jù)存儲在內(nèi)存中而獲得了極快的速度,但為了保證Redis在重啟后數(shù)據(jù)不丟失,需要將數(shù)據(jù)從內(nèi)存持久化到硬盤中。

持久化的方式有兩種,二者可以只用一種,也可以組合使用:

  • RDB方式
  • AOF方式

RDB方式

RDB是Redis默認(rèn)采用的持久化方式,當(dāng)符合一定條件時Redis會自動將內(nèi)存中的所有數(shù)據(jù)進行快照(snapshotting)并存儲在硬盤上。進行快照的條件可以由用戶在配置文件中自定義,配置由兩個參數(shù)構(gòu)成:時間和改動的鍵的個數(shù)。當(dāng)在指定的時間內(nèi)被更改的鍵的個數(shù)大于指定的數(shù)值時就會進行快照。在配置文件redis.conf中已經(jīng)預(yù)置了3個條件:

save 900 1
save 300 10
save 60 10000

這些條件直接是“或”的關(guān)系。如果需要禁用自動快照,可以將所有的save配置刪除。

除了自動快照,還可以手動發(fā)送SAVE或BGSAVE命令讓Redis執(zhí)行快照,SAVE命令是由主進程進行快照操作,會阻塞住其他請求,而BGSAVE命令則會通過fork子進程進行快照操作。

Redis默認(rèn)會將快照文件存儲在當(dāng)前目錄的dump.rdb文件中,可以通過配置dir和dbfilename兩個參數(shù)分別指定快照文件的存儲路徑和文件名。

Redis實現(xiàn)快照的過程

RDB快照的過程為:

  1. Redis使用fork函數(shù)復(fù)制一份當(dāng)前進程(父進程)的副本(子進程);
  2. 父進程繼續(xù)接收并處理客戶端發(fā)來的命令,子進程則開始將內(nèi)存中的數(shù)據(jù)寫入硬盤中的臨時文件;
  3. 當(dāng)子進程寫入完所有數(shù)據(jù)后,會用該臨時文件替換舊的RDB文件,至此一次快照操作完成。
  4. Redis重新啟動時會讀取RDB快照文件,將數(shù)據(jù)從硬盤載入到內(nèi)存。(根據(jù)數(shù)據(jù)量大小與結(jié)構(gòu)和服務(wù)器性能不同,這個時間也不同。通常將一個記錄一千萬個字符串類型鍵、大小為1GB的快照文件載入到內(nèi)存中需要花費20~30秒鐘)。

Redis在進行快照的過程中不會修改RDB文件,只有快照結(jié)束后才會將舊的文件替換成新的,也就是說任何時候RDB文件都是完整的,所以可以通過定時備份RDB文件來實現(xiàn)Redis數(shù)據(jù)庫備份。RDB文件是經(jīng)過壓縮的二進制格式,占用的空間會小于內(nèi)存中的數(shù)據(jù)大小。但壓縮過程也會增加CPU占用,如有需要可以通過修改配置rdbcompression參數(shù)以禁用壓縮。

config set rdbcompression no

AOF方式

AOF全稱為append only file,在這種持久化方式下,每執(zhí)行一條會更改Redis中的數(shù)據(jù)的命令,Redis都會將該命令寫入硬盤中的AOF文件。
AOF文件的保存位置和RDB文件的位置相同,都可以通過dir參數(shù)設(shè)置,默認(rèn)的文件名是appendonly.aof,可以通過appendfilename參數(shù)修改。
AOF文件是純文本文件,其內(nèi)容是Redis客戶端向Redis發(fā)送的原始通信協(xié)議的內(nèi)容。設(shè)想執(zhí)行這樣幾條命令:

SET key1 1
SET key1 2
SET key1 3

AOF文件中會記錄這三次操作,但實際上前兩條實際上是多余的,只需要記錄最終一次的命令即可。隨著執(zhí)行的命令越來越多,AOF文件也會越來越大,而Redis可以通過去除這類多余命令記錄,自動對AOF文件進行優(yōu)化。

每當(dāng)達(dá)到一定條件時Redis就會自動重寫AOF文件,這個條件可以在配置文件中設(shè)置:

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

auto-aof-rewrite-percentage設(shè)置當(dāng)目前的AOF文件大小超過上一次重寫時的AOF文件大小的百分之多少時會再次進行重寫,如果之前沒有重寫過,則以啟動時的AOF文件大小為依據(jù)。
auto-aof-rewrite-min-size則限制了允許重寫的最小AOF文件大小,通常在AOF文件很小的情況下即使其中有很多冗余的命令也不需要重寫。

除了讓Redis自動執(zhí)行重寫外,還可以主動使用BGREWRITEAOF命令手動執(zhí)行AOF重寫。

在重啟時Redis會逐個執(zhí)行AOF文件中的命令來將硬盤中的數(shù)據(jù)載入到內(nèi)存中,載入的速度相較RDB會慢一些。

操作系統(tǒng)緩存

雖然每次執(zhí)行更改數(shù)據(jù)庫內(nèi)容的操作時,AOF都會將命令記錄在AOF文件中,但實際上由于操作系統(tǒng)的緩存機制的存在,數(shù)據(jù)并沒有真正地寫入硬盤,而是進入了系統(tǒng)的硬盤緩存。在默認(rèn)情況下系統(tǒng)每30秒會執(zhí)行一次同步操作,以便將硬盤緩存中的內(nèi)容真正地寫入硬盤,在這30秒的過程中如果系統(tǒng)異常退出則會導(dǎo)致硬盤緩存中的數(shù)據(jù)丟失。一般來講啟用AOF持久化的應(yīng)用都無法容忍這樣的損失,這就需要Redis在寫入AOF文件后主動要求系統(tǒng)將緩存內(nèi)容同步到硬盤中。
可以通過appendfsync參數(shù)設(shè)置同步的時機:

config set appendfsync always/eversec/no
  • always 每次執(zhí)行寫入都會執(zhí)行同步,這種模式最安全但也最慢
  • everysec 每秒同步一次
  • no 不主動進行同步操作,操作系統(tǒng)沒30秒同步一次

RDB與AOF

如果選擇RDB的持久化方式,一旦Redis異常退出,就會丟失最后一次快照以后更改的所有數(shù)據(jù)。這就需要開發(fā)者根據(jù)具體的應(yīng)用場合,通過組合設(shè)置自動快照條件的方式來將可能發(fā)生的數(shù)據(jù)損失控制在能夠接受的范圍。如果數(shù)據(jù)很重要以至于無法承受任何損失,則可以考慮使用AOF方式進行持久化。
可以同時開啟AOF和RDB,這樣既保證了數(shù)據(jù)安全,又使得進行備份等操作十分容易。此時重新啟動Redis后Redis會使用AOF文件來恢復(fù)數(shù)據(jù),因為AOF方式的持久化可能丟失的數(shù)據(jù)更少。

復(fù)制

Redis的持久化功能可以保證在服務(wù)器重啟的情況下不會損失(或少量損失)數(shù)據(jù)。但是由于數(shù)據(jù)只存儲在一臺服務(wù)器,如果這臺服務(wù)器的硬盤出現(xiàn)故障,也會導(dǎo)致數(shù)據(jù)丟失。為了避免單點故障,將數(shù)據(jù)庫復(fù)制多個副本以部署在不同的服務(wù)器上,組成集群,這樣即使有一臺服務(wù)器出現(xiàn)故障時,其他服務(wù)器依然可以繼續(xù)提供服務(wù),此外也提升了整體的性能。
Redis提供了復(fù)制(replication)功能用以保障構(gòu)成集群的多臺服務(wù)器之間數(shù)據(jù)的同步。

主從數(shù)據(jù)庫

構(gòu)成集群的數(shù)據(jù)庫分為兩類,主數(shù)據(jù)庫(master)和從數(shù)據(jù)庫(slave)。主數(shù)據(jù)庫可以進行讀寫操作,當(dāng)發(fā)生寫操作時自動將數(shù)據(jù)同步給從數(shù)據(jù)庫。而從數(shù)據(jù)庫一般是只讀的,并接受主數(shù)據(jù)庫同步過來的數(shù)據(jù)。主從數(shù)據(jù)庫是一對多的關(guān)系。

要把一個數(shù)據(jù)庫作為從數(shù)據(jù)庫,需要在啟動參數(shù)或者配置文件中加入:

slaveof 主數(shù)據(jù)庫的IP 端口

接下來使用redis的docker鏡像試驗主從復(fù)制,首先啟動兩個實例:

docker run --name redis-6379 -p 6379:6379 -d redis
docker run --name redis-6380 -p 6380:6379 -d redis

redis-6379將被作為主數(shù)據(jù)庫,redis-6380為從庫,首先獲取redis-6379容器的內(nèi)網(wǎng)IP地址:

docker inspect redis-6379

在"NetworkSettings"結(jié)點下可以看到IP和端口為172.17.0.2 6379

進入redis-6380,設(shè)置其為從數(shù)據(jù)庫:

> docker exec -it redis-6380 /bin/bash
root@cd19cbbab6d9:/data# redis-cli
127.0.0.1:6379> SLAVEOF 172.17.0.2 6379

這樣主從數(shù)據(jù)庫就設(shè)置好了,可以測試下在主數(shù)據(jù)庫插入一個鍵,然后在從數(shù)據(jù)庫讀取。

從數(shù)據(jù)庫默認(rèn)是只讀的,嘗試寫入將提示:

SET KEY1 1
(error) READONLY You can't write against a read only replica.

可以通過設(shè)置從數(shù)據(jù)庫的配置文件中的slave-read-only為no以使從數(shù)據(jù)庫可寫,但是對從數(shù)據(jù)庫的任何更改都不會同步給其他數(shù)據(jù)庫,并且一旦主數(shù)據(jù)庫中更新了對應(yīng)的數(shù)據(jù)就會覆蓋從數(shù)據(jù)庫中的改動。

在redis實例運行也可以使用SLAVEOF命令,如果該數(shù)據(jù)庫已經(jīng)是其他主數(shù)據(jù)庫的從數(shù)據(jù)庫,則SLAVEOF命令會停止和原來數(shù)據(jù)庫的同步轉(zhuǎn)而和新數(shù)據(jù)庫同步。還可以使用SLAVEOF NO ONE來使當(dāng)前數(shù)據(jù)庫停止接收其他數(shù)據(jù)庫的同步轉(zhuǎn)成主數(shù)據(jù)庫。

主從復(fù)制的意義

  • 數(shù)據(jù)冗余:主從復(fù)制實現(xiàn)了數(shù)據(jù)的熱備份,是持久化之外的一種數(shù)據(jù)冗余方式。

  • 故障恢復(fù):當(dāng)主節(jié)點出現(xiàn)問題時,可以由從節(jié)點提供服務(wù),實現(xiàn)快速的故障恢復(fù);實際上是一種服務(wù)的冗余。

  • 讀寫分離:可以用于實現(xiàn)讀寫分離,主庫寫、從庫讀,讀寫分離不僅可以提高服務(wù)器的負(fù)載能力,同時可根據(jù)需求的變化,改變從庫的數(shù)量;

  • 負(fù)載均衡:在主從復(fù)制的基礎(chǔ)上,配合讀寫分離,可以由主節(jié)點提供寫服務(wù),由從節(jié)點提供讀服務(wù)分擔(dān)服務(wù)器負(fù)載;尤其是在寫少讀多的場景下,通過多個從節(jié)點分擔(dān)讀負(fù)載,可以大大提高Redis服務(wù)器的并發(fā)量。

  • 高可用基石:除了上述作用以外,主從復(fù)制還是哨兵和集群能夠?qū)嵤┑幕A(chǔ),因此說主從復(fù)制是Redis高可用的基礎(chǔ)。

安全

在安全方面,Redis提供了下面幾種策略。

可信的環(huán)境

Redis安全設(shè)計都是建立在“Redis運行在可信環(huán)境”這個前提下的,在生產(chǎn)環(huán)境運行時不能允許外界直接連接到Redis服務(wù)器上,而應(yīng)該通過應(yīng)用程序進行中轉(zhuǎn),運行在可信的環(huán)境中是保證Redis安全的最重要方法。

Redis的默認(rèn)會接受來自任何地址發(fā)送來的請求,要更改這一設(shè)置,可以在配置文件中修改bind參數(shù),如只允許本機應(yīng)用連接Redis,可以將bind參數(shù)改成:

bind 127.0.0.1

密碼

要設(shè)置密碼,可以修改配置文件中的requirepass參數(shù),例如:

requirepass 123456

docker鏡像也可以在啟動容器的時候設(shè)置密碼:

docker run --name redis-test -p 6379:6379 redis --requirepass 123456

添加密碼后,客戶端在連接時需要輸入密碼:

redis-cli -h 127.0.0.1 -p 6379 -a 123456

設(shè)置密碼后,如果要搭建主從數(shù)據(jù)庫,需要在從數(shù)據(jù)庫配置文件中的masterauth添加主數(shù)據(jù)庫的密碼。

需要注意的是,由于Redis的性能極高,并且輸入錯誤密碼后Redis并不會進行主動延遲,所以攻擊者可以通過窮舉法破解Redis的密碼(1秒內(nèi)能夠嘗試十幾萬個密碼),因此在設(shè)置時一定要選擇復(fù)雜的密碼。

命令重命名

Redis支持在配置文件中將命令重命名,比如將FLUSHALL命令重命名成一個比較復(fù)雜的名字,以保證只有自己的應(yīng)用可以使用該命令:

rename-command FLUSHALL oiuyhjkghjgyutdfhbuhbnjinjbgyvtcrd

如果希望直接禁用某個命令,可以將命令重命名成空字符串。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容