新聞中心
Redis復(fù)制
在生產(chǎn)環(huán)境中,Redis通過(guò)持久化功能(RDB和AOF技術(shù))保證了即使在服務(wù)器重啟的情況下也不會(huì)損失(或少量損失)數(shù)據(jù)。但是由于數(shù)據(jù)是存儲(chǔ)在一臺(tái)服務(wù)器上的,如果這臺(tái)服務(wù)器出現(xiàn)硬盤故障等問(wèn)題(生產(chǎn)環(huán)境中多次遇到),也會(huì)導(dǎo)致數(shù)據(jù)丟失,為了避免單點(diǎn)故障,通常的做法是將數(shù)據(jù)庫(kù)復(fù)制多個(gè)副本以部署在不同的服務(wù)器上,這樣即使有一臺(tái)服務(wù)器出現(xiàn)故障,其他服務(wù)器依然可以以最快的速度提供服務(wù)。為此,Redis提供了復(fù)制(replication)功能,可以實(shí)現(xiàn)當(dāng)一臺(tái)數(shù)據(jù)庫(kù)中的數(shù)據(jù)更新后,自動(dòng)將更新的數(shù)據(jù)同步到其他數(shù)據(jù)庫(kù)上。

在復(fù)制的概念中,數(shù)據(jù)庫(kù)分為兩類,一類是主數(shù)據(jù)庫(kù)(master),另一類是從數(shù)據(jù)庫(kù)(slave)。主數(shù)據(jù)庫(kù)可以進(jìn)行讀寫操作,當(dāng)寫操作導(dǎo)致數(shù)據(jù)變化時(shí)自動(dòng)將數(shù)據(jù)同步給從數(shù)據(jù)庫(kù)。而從數(shù)據(jù)庫(kù)一般是只讀的,并接受主數(shù)據(jù)庫(kù)同步過(guò)來(lái)的數(shù)據(jù)。一個(gè)主數(shù)據(jù)庫(kù)可以擁有多個(gè)從數(shù)據(jù)庫(kù)。
Redis復(fù)制很簡(jiǎn)單易用,它通過(guò)配置允許slave Redis Servers或者M(jìn)aster Servers的復(fù)制品。接下來(lái)有幾個(gè)關(guān)于redis復(fù)制的非常重要特性:
一個(gè)Master可以有多個(gè)Slaves。
Slaves能通過(guò)和其他slave的鏈接,除了可以接受同一個(gè)master下面slaves的鏈接以外,還可以接受同一個(gè)結(jié)構(gòu)圖中的其他slaves的鏈接。
redis復(fù)制是在master段是非阻塞的,這就意味著master在同一個(gè)或多個(gè)slave端執(zhí)行同步的時(shí)候還可以接受查詢。
復(fù)制在slave端也是非阻塞的,假設(shè)你在redis.conf中配置redis這個(gè)功能,當(dāng)slave在執(zhí)行的新的同步時(shí),它仍可以用舊的數(shù)據(jù)信息來(lái)提供查詢,否則,你可以配置當(dāng)redis slaves去master失去聯(lián)系是,slave會(huì)給發(fā)送一個(gè)客戶端錯(cuò)誤。
為了有多個(gè)slaves可以做只讀查詢,復(fù)制可以重復(fù)2次,甚至多次,具有可擴(kuò)展性(例如:slaves對(duì)話與重復(fù)的排序操作,有多份數(shù)據(jù)冗余就相對(duì)簡(jiǎn)單了)。
通過(guò)復(fù)制可以避免master全量寫硬盤的消耗:只要配置 master 的配置文件redis.conf來(lái)“避免保存”(注釋掉所有”save”命令),然后連接一個(gè)用來(lái)持久化數(shù)據(jù)的slave即可。但是這樣要確保masters 不會(huì)自動(dòng)重啟(更多內(nèi)容請(qǐng)閱讀下段)
Redis復(fù)制配置
在Redis中使用復(fù)制功能非常容易,只需要在從數(shù)據(jù)庫(kù)的配置文件中加入“slaveof 主數(shù)據(jù)復(fù)制 主數(shù)據(jù)庫(kù)端口”即可。
主數(shù)據(jù)庫(kù)無(wú)需進(jìn)行任何配置。下面先來(lái)看看一個(gè)最簡(jiǎn)化的復(fù)制系統(tǒng),我們?cè)谝慌_(tái)服務(wù)器上啟動(dòng)兩個(gè)redis示例,監(jiān)聽(tīng)在不同的端口,其中一個(gè)作為主數(shù)據(jù)庫(kù),另一個(gè)作為從數(shù)據(jù)庫(kù)。
首先我們不加任何參數(shù)來(lái)啟動(dòng)一個(gè)redis實(shí)例作為主數(shù)據(jù)庫(kù):
$ redis-server --port 6379 &
該實(shí)例默認(rèn)監(jiān)聽(tīng)6379端口,然后加上slaveof參數(shù)啟動(dòng)另一個(gè)redis實(shí)例作為從數(shù)據(jù)庫(kù),并讓其監(jiān)聽(tīng)6380端口:
$ redis-server --port 6380 --slaveof 127.0.0.1 6379 &
查看一下實(shí)例的啟動(dòng)情況:
$ ps aux | grep redis
root 2886 0.0 0.0 38652 4448 pts/0 Sl 16:57 0:00 redis-server *:6379
root 2889 0.0 0.0 36604 4368 pts/0 Sl 16:57 0:00 redis-server *:6380
此時(shí)在主數(shù)據(jù)庫(kù)中的任何數(shù)據(jù)變化都會(huì)自動(dòng)同步到從數(shù)據(jù)庫(kù)中,我們打開(kāi)redis-cli實(shí)例A并連接到數(shù)據(jù)庫(kù):
$ redis-cli -p 6379
再打開(kāi)redis-cli實(shí)例B并連接到從數(shù)據(jù)庫(kù):
$ redis-cli -p 6380
這時(shí)我們使用INFO命令來(lái)分別在實(shí)例A和實(shí)例B中獲取replication的相關(guān)信息。
127.0.0.1:6379> INfo replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=266,lag=1
master_repl_offset:266
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:265
可以看到,實(shí)例A的角色(role)是master,即主數(shù)據(jù)庫(kù),同時(shí)已連接的從數(shù)據(jù)庫(kù)(connectd_slaves)的個(gè)數(shù)為1個(gè)。
同樣在實(shí)例B中獲取響應(yīng)的信息為:
127.0.0.1:6380> INfo replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_repl_offset:378
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
可以看到,實(shí)例B的role是slave,即從數(shù)據(jù)庫(kù),同時(shí)其主數(shù)據(jù)庫(kù)的地址為127.0.0.1,端口為6379。
然后我們?cè)趯?shí)例A中使用SET命令設(shè)置一個(gè)鍵的值:
127.0.0.1:6379> set foo bar
OK
此時(shí)在實(shí)例B中就可以獲得該值了:
127.0.0.1:6380> get foo
"bar"
證明兩個(gè)Redis實(shí)例的復(fù)制功能已經(jīng)可用了。默認(rèn)情況,從數(shù)據(jù)庫(kù)是只讀的,如果直接修改從數(shù)據(jù)庫(kù)的數(shù)據(jù)會(huì)出現(xiàn)錯(cuò)誤,如下:
127.0.0.1:6380> set foo hey
(error) READONLY You can't write against a read only slave.
但也可以通過(guò)設(shè)置從數(shù)據(jù)庫(kù)的配置文件中的slave-read-only=no,以使從數(shù)據(jù)庫(kù)可寫,但是因?yàn)閷?duì)從數(shù)據(jù)庫(kù)的任何更改都不會(huì)同步給任何其他數(shù)據(jù)庫(kù),并且一旦主數(shù)據(jù)庫(kù)中的更新了賭贏的數(shù)據(jù)就會(huì)覆蓋從數(shù)據(jù)庫(kù)中的改動(dòng),所以通常場(chǎng)景下不應(yīng)該設(shè)置從數(shù)據(jù)庫(kù)可寫,以免導(dǎo)致易被忽略的潛在應(yīng)用邏輯錯(cuò)誤。
配置多臺(tái)從數(shù)據(jù)庫(kù)的方法也一樣,在所有的從數(shù)據(jù)庫(kù)的配置文件中都加上salveof參數(shù)指向同一個(gè)主數(shù)據(jù)庫(kù)即可。除了通過(guò)配置文件或命令行參數(shù)設(shè)置slaveof參數(shù)外,還可以在運(yùn)行時(shí)使用slaveof命令修改,下面我們?cè)偬砑右粋€(gè)實(shí)例C(6381):
$ redis-server --port 6381 &
$ redis-cli -p 6381
127.0.0.1:6381> slaveof 127.0.0.1 6379
127.0.0.1:6381> get foo
"bar"
如果該數(shù)據(jù)庫(kù)已經(jīng)是其他主數(shù)據(jù)庫(kù)的從數(shù)據(jù)庫(kù)了,slaveof命令會(huì)停止和原來(lái)數(shù)據(jù)庫(kù)的同步轉(zhuǎn)而和新數(shù)據(jù)庫(kù)同步,此外對(duì)于從數(shù)據(jù)庫(kù)來(lái)說(shuō),還可以使用slaveof no one命令來(lái)使當(dāng)前數(shù)據(jù)庫(kù)停止接收其他數(shù)據(jù)庫(kù)的同步并轉(zhuǎn)換成為主數(shù)據(jù)庫(kù)。如下測(cè)試,在從庫(kù)實(shí)例C上寫入數(shù)據(jù)時(shí)時(shí)不允許的,然后使用slaveof no one將此數(shù)據(jù)庫(kù)轉(zhuǎn)換為主數(shù)據(jù)庫(kù),然后再寫入數(shù)據(jù)就沒(méi)有問(wèn)題了。一般用于但主節(jié)點(diǎn)掛掉的時(shí)候,立刻把從節(jié)點(diǎn)切換為主節(jié)點(diǎn)提供數(shù)據(jù)操作服務(wù)。
127.0.0.1:6381> set foo bar
(error) READONLY You can't write against a read only slave. 127.0.0.1:6381> SLAVEOF no one 5493:M 07 Aug 17:23:06.792 # Connection with master lost. 5493:M 07 Aug 17:23:06.792 * Caching the disconnected master state. 5493:M 07 Aug 17:23:06.792 * Discarding previously cached master state. 5493:M 07 Aug 17:23:06.792 * MASTER MODE enabled (user request from 'id=2 addr=127.0.0.1:40825 fd=6 name= age=348 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof') 2886:M 07 Aug 17:23:06.792 # Connection with slave 127.0.0.1:6381 lost. OK 127.0.0.1:6381> set foo bar OK
復(fù)制常用參數(shù)
slaveof
將當(dāng)前server做為slave,并為其指定master信息。
masterauth
以認(rèn)證的方式連接到master,如果master中使用了”密碼保護(hù)”,slave必須交付正確的授權(quán)密碼,才能連接成功?!眗equirepas”配置項(xiàng)指定了當(dāng)前server的密碼。此配置項(xiàng)中值需要和master機(jī)器的”requirepas”保持一致。此參數(shù)配置在slave端。
slave-serve-stale-data yes
如果當(dāng)前server是slave,那么當(dāng)slave與master失去通訊時(shí),是否繼續(xù)為客戶端提供服務(wù),”yes”表示繼續(xù),”no”表示終止。在”yes”情況下,slave繼續(xù)向客戶端提供只讀服務(wù),有可能此時(shí)的數(shù)據(jù)已經(jīng)過(guò)期。在”no”情況下,任何向此server發(fā)送的數(shù)據(jù)請(qǐng)求服務(wù)(包括客戶端和此server的slave)都將被告知”error”。
slave-read-only yes
slave是否為”只讀”,強(qiáng)烈建議為”yes”。
repl-ping-slave-period 10
slave向指定的master發(fā)送ping消息的時(shí)間間隔(秒),默認(rèn)為10。
repl-timeout 60
slave與master通訊中,最大空閑時(shí)間,默認(rèn)60秒,超時(shí)將導(dǎo)致連接關(guān)閉。
repl-disable-tcp-nodelay no
slave與master的連接,是否禁用TCP nodelay選項(xiàng)?!眣es”表示禁用,那么socket通訊中數(shù)據(jù)將會(huì)以packet方式發(fā)送(packet大小受到socket buffer限制),可以提高socket通訊的效率(tcp交互次數(shù)),但是小數(shù)據(jù)將會(huì)被buffer,不會(huì)被立即發(fā)送,對(duì)于接受者可能存在延遲。”no”表示開(kāi)啟tcp nodelay選項(xiàng),任何數(shù)據(jù)都會(huì)被立即發(fā)送,及時(shí)性較好,但是效率較低。建議為”no”。
slave-priority 100
適用Sentinel模塊(unstable,M-S集群管理和監(jiān)控),需要額外的配置文件支持。slave的權(quán)重值,默認(rèn)100。當(dāng)master失效后,Sentinel將會(huì)從slave列表中找到權(quán)重值最低(>0)的slave,并提升為master。如果權(quán)重值為0,表示此slave為”觀察者”,不參與master選舉。
了解Redis的復(fù)制原理
了解Redis復(fù)制的原理對(duì)運(yùn)維Redis過(guò)程中有很大的幫助,包括如何規(guī)劃節(jié)點(diǎn),如果處理節(jié)點(diǎn)故障等。下面介紹Redis實(shí)現(xiàn)復(fù)制的工程。
當(dāng)一個(gè)從數(shù)據(jù)庫(kù)啟動(dòng)后,會(huì)向主數(shù)據(jù)庫(kù)發(fā)送SYNC命令,同時(shí)主數(shù)據(jù)庫(kù)接收到SYNC命令后會(huì)開(kāi)始在后臺(tái)保存快照(即RDB持久化的過(guò)程),并將保存快照期間接收到的命令緩存起來(lái),當(dāng)快照完成后,Redis Master會(huì)將快照文件發(fā)送給從數(shù)據(jù)庫(kù),從數(shù)據(jù)庫(kù)收到后,會(huì)載入快照文件。之后Redis Master會(huì)以Redis命令協(xié)議的格式,將寫命令緩沖區(qū)中積累的所有內(nèi)容都發(fā)送給從服務(wù)器。以上過(guò)程稱為復(fù)制初始化,復(fù)制初始化結(jié)束后,主數(shù)據(jù)庫(kù)每當(dāng)收到寫命令時(shí)就會(huì)將命令同步給從數(shù)據(jù)庫(kù),從而保證主從數(shù)據(jù)庫(kù)數(shù)據(jù)一致。
你可以通過(guò)telnet命令來(lái)親自驗(yàn)證這個(gè)同步過(guò)程:首先連上一個(gè)正在處理命令請(qǐng)求的Redis服務(wù)器,然后向它發(fā)送SYNC命令,過(guò)一陣子,你將會(huì)看到telnet會(huì)話接收到服務(wù)器發(fā)來(lái)的大段數(shù)據(jù)(.rdb文件),之后還會(huì)看到,所有的服務(wù)器執(zhí)行過(guò)的寫命令,都會(huì)重新發(fā)送到telnet會(huì)話來(lái)。
當(dāng)主從數(shù)據(jù)庫(kù)之間的連接斷開(kāi)重連后,Redis 2.6以及之前的版本會(huì)重新進(jìn)行復(fù)制初始化(即主數(shù)據(jù)庫(kù)重新保存快照并傳送給從數(shù)據(jù)庫(kù)),即使從數(shù)據(jù)庫(kù)可以僅有幾條命令沒(méi)有收到,主數(shù)據(jù)庫(kù)也必須要將數(shù)據(jù)庫(kù)里的所有數(shù)據(jù)重新傳送給從數(shù)據(jù)庫(kù)。這使得主從數(shù)據(jù)庫(kù)斷線重連后的數(shù)據(jù)恢復(fù)過(guò)程效率很低下,在網(wǎng)絡(luò)環(huán)境不好的時(shí)候這一問(wèn)題尤其明顯,Redis 2.8版本的一個(gè)重要改進(jìn)就是斷線重連能夠支持有條件的增量數(shù)據(jù)傳輸,當(dāng)從數(shù)據(jù)庫(kù)重新連接上主數(shù)據(jù)庫(kù)后,主數(shù)據(jù)庫(kù)只需要將斷線期間執(zhí)行的命令傳送給從數(shù)據(jù)庫(kù),從而大大提高Redis復(fù)制的實(shí)用性。
增量復(fù)制的實(shí)現(xiàn),基于以下3點(diǎn):
1)從數(shù)據(jù)庫(kù)會(huì)存儲(chǔ)主數(shù)據(jù)庫(kù)的運(yùn)行ID(run id),每個(gè)Redis運(yùn)行實(shí)例均會(huì)擁有一個(gè)唯一的運(yùn)行ID,每當(dāng)實(shí)例重啟后,就會(huì)自動(dòng)生成一個(gè)新的運(yùn)行ID。
2)在復(fù)制同步階段,主數(shù)據(jù)庫(kù)每將一個(gè)命令傳送給從數(shù)據(jù)庫(kù)時(shí),都會(huì)同時(shí)把該命令存放到一個(gè)積壓隊(duì)列(backlog)中,并記錄下當(dāng)前積壓隊(duì)列中存放的命令的偏移量范圍。
3)同時(shí),從數(shù)據(jù)庫(kù)接收到主數(shù)據(jù)庫(kù)傳來(lái)的命令時(shí),會(huì)記錄下該命令的偏移量。
這三點(diǎn)是實(shí)現(xiàn)增量復(fù)制的基礎(chǔ),當(dāng)主從連接準(zhǔn)備就緒后,從數(shù)據(jù)庫(kù)會(huì)發(fā)送一條SYNC命令來(lái)告訴主數(shù)據(jù)庫(kù)可以開(kāi)始把所有數(shù)據(jù)同步過(guò)來(lái)了。而2.8版本之后,不再發(fā)送SYNC命令,取而代之的是發(fā)送PSYNC,格式為“PSYNC 主數(shù)據(jù)庫(kù)的運(yùn)行ID 斷開(kāi)前最新的命令偏移量”。主數(shù)據(jù)庫(kù)收到PSYNC命令后,會(huì)執(zhí)行以下判斷來(lái)決定此次重連是否可以執(zhí)行增量復(fù)制。
1)首先主數(shù)據(jù)庫(kù)會(huì)判斷從數(shù)據(jù)庫(kù)傳送來(lái)的運(yùn)行ID是否和自己的運(yùn)行ID相同,這一步驟的意義在于確保從數(shù)據(jù)庫(kù)之前確實(shí)是和自己同步的,以免從數(shù)據(jù)庫(kù)拿到錯(cuò)誤的數(shù)據(jù)(如主數(shù)據(jù)庫(kù)在斷連期間重啟過(guò),會(huì)造成數(shù)據(jù)的不一致性)。
2)然后判斷從數(shù)據(jù)庫(kù)最后同步成功的命令偏移量是否在積壓隊(duì)列中,如果在則可以執(zhí)行增量復(fù)制,并將積壓隊(duì)列中相應(yīng)的命令發(fā)送給從數(shù)據(jù)庫(kù)。
如果此次重連不滿足增量復(fù)制的條件,主數(shù)據(jù)會(huì)進(jìn)行一次全部同步(即與Redis 2.6的過(guò)程相同),大部分情況下,增量復(fù)制的過(guò)程對(duì)開(kāi)發(fā)者來(lái)說(shuō)是完全透明的,開(kāi)發(fā)者不需要關(guān)心增量復(fù)制的具體細(xì)節(jié),2.8版本的主數(shù)據(jù)庫(kù)也可以正常地和舊版本的從數(shù)據(jù)庫(kù)同步(通過(guò)接收SYNC命令),同樣2.8版本的從數(shù)據(jù)庫(kù)也可以與舊版本的主數(shù)據(jù)庫(kù)同步(通過(guò)發(fā)送SYNC命令),唯一需要開(kāi)發(fā)者設(shè)置的就是積壓隊(duì)列的大小了。
積壓隊(duì)列在本質(zhì)上是一個(gè)固定長(zhǎng)度的循環(huán)隊(duì)列,默認(rèn)情況下積壓隊(duì)列的大小為1MB,可以通過(guò)配置文件的repl-backlog-size選項(xiàng)來(lái)調(diào)整。很容易理解的是,積壓隊(duì)列越大,其允許的主從數(shù)據(jù)庫(kù)斷線的時(shí)間就越長(zhǎng)。根據(jù)主從數(shù)據(jù)庫(kù)之間的網(wǎng)絡(luò)狀態(tài),設(shè)置一個(gè)合理的積壓隊(duì)列很重要。因?yàn)榉e壓隊(duì)列存儲(chǔ)的內(nèi)容是命令本身,如 SET FOO BAR,所以估算積壓隊(duì)列的大小只需要估計(jì)主從數(shù)據(jù)庫(kù)斷線的時(shí)間中主從數(shù)據(jù)庫(kù)可能執(zhí)行的命令的大小即可。與積壓隊(duì)列相關(guān)的另一個(gè)配置選項(xiàng)是repl-backlog-ttl,即當(dāng)所有主從數(shù)據(jù)庫(kù)與主數(shù)據(jù)斷開(kāi)連接后,經(jīng)過(guò)多久時(shí)間可以釋放積壓隊(duì)列的內(nèi)存空間,默認(rèn)時(shí)間是1小時(shí)。
從數(shù)據(jù)庫(kù)持久化
另一個(gè)相對(duì)耗時(shí)的操作是持久化,為了提高性能,可以通過(guò)復(fù)制功能建立一個(gè)或多個(gè)從數(shù)據(jù)庫(kù),并在從數(shù)據(jù)庫(kù)中啟用持久化,同時(shí)在主數(shù)據(jù)庫(kù)禁用持久化,當(dāng)從數(shù)據(jù)庫(kù)崩潰重啟后主數(shù)據(jù)庫(kù)會(huì)自動(dòng)將時(shí)間同步過(guò)來(lái),所以無(wú)需擔(dān)心數(shù)據(jù)丟失。
然后當(dāng)主數(shù)據(jù)庫(kù)崩潰時(shí),情況就稍顯復(fù)雜了。手工通過(guò)從數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)主數(shù)據(jù)庫(kù)數(shù)據(jù)時(shí),需要嚴(yán)格按照以下兩步進(jìn)行:
1)在從數(shù)據(jù)庫(kù)中使用SLAVEOF NO ONE命令將從數(shù)據(jù)庫(kù)提升為主數(shù)據(jù)庫(kù)繼續(xù)服務(wù)。
2)啟動(dòng)之前崩潰的主數(shù)據(jù)庫(kù),然后使用SLAVEOF命令將其設(shè)置成新的主數(shù)據(jù)庫(kù)的從數(shù)據(jù)庫(kù),即可將數(shù)據(jù)同步回來(lái)。
注意,當(dāng)開(kāi)啟復(fù)制且主數(shù)據(jù)庫(kù)關(guān)閉持久化的時(shí)候,一定不要使用supervisor以及類似的進(jìn)程管理工具令主數(shù)據(jù)庫(kù)崩潰后自動(dòng)重啟。同樣當(dāng)主數(shù)據(jù)庫(kù)所在的服務(wù)器因故關(guān)閉時(shí),也要避免直接重新啟動(dòng)。這是因?yàn)楫?dāng)主數(shù)據(jù)庫(kù)重新啟動(dòng)后,因?yàn)闆](méi)開(kāi)持久化功能,所以數(shù)據(jù)庫(kù)中所有數(shù)據(jù)都被清空,這時(shí)從數(shù)據(jù)庫(kù)依然會(huì)從主數(shù)據(jù)庫(kù)中接收數(shù)據(jù),使得所有從數(shù)據(jù)庫(kù)也被清空,導(dǎo)致從數(shù)據(jù)庫(kù)的持久化失去意義。
無(wú)論哪種情況,手工維護(hù)從數(shù)據(jù)庫(kù)或主數(shù)據(jù)的重啟以及數(shù)據(jù)恢復(fù)都相對(duì)麻煩,好在Redis提供了一種自動(dòng)化方案哨兵來(lái)實(shí)現(xiàn)這一過(guò)程,避免了手工維護(hù)的麻煩和容易出錯(cuò)的問(wèn)題。
無(wú)硬盤復(fù)制
上面介紹了Redis復(fù)制的工作原理時(shí)介紹了復(fù)制是基于RDB方式的持久化實(shí)現(xiàn)的,即主數(shù)據(jù)庫(kù)端在后臺(tái)保存了RDB快照,從數(shù)據(jù)庫(kù)端則接收并載入快照文件,這樣的實(shí)現(xiàn)有點(diǎn)是可以顯著地簡(jiǎn)化邏輯,復(fù)用已有的代碼,但是缺點(diǎn)也很明顯。
1)當(dāng)主數(shù)據(jù)庫(kù)禁用RDB快照時(shí)(即刪除了所有的配置文件中的save語(yǔ)句),如果執(zhí)行了復(fù)制初始化操作,Redis依然會(huì)生成RDB快照,所以下次啟動(dòng)后主數(shù)據(jù)庫(kù)會(huì)以該快照恢復(fù)數(shù)據(jù)。因?yàn)閺?fù)制發(fā)生的時(shí)間不能確定,這使得恢復(fù)的數(shù)據(jù)可能是任何時(shí)間點(diǎn)的。
2)因?yàn)閺?fù)制初始化時(shí)需要在硬盤中創(chuàng)建RDB快照文件,所以如果硬盤性能很慢時(shí)這一過(guò)程會(huì)對(duì)性能產(chǎn)生影響。舉例來(lái)說(shuō),當(dāng)使用Redis做緩存系統(tǒng)時(shí),因?yàn)椴恍枰志没苑?wù)器的硬盤讀寫速度可能較差。但是當(dāng)該緩存系統(tǒng)使用一主多從的集群架構(gòu)時(shí),每次和從數(shù)據(jù)庫(kù)同步,Redis都會(huì)執(zhí)行一次快照,同時(shí)對(duì)硬盤進(jìn)行讀寫,導(dǎo)致性能下降。
因此從2.8.18版本開(kāi)始,Redis引入了無(wú)硬盤復(fù)制選項(xiàng),開(kāi)啟該選項(xiàng)時(shí),Redis在與從數(shù)據(jù)庫(kù)進(jìn)行復(fù)制初始化時(shí)將不會(huì)將快照內(nèi)容存儲(chǔ)到硬盤上,而是直接通過(guò)網(wǎng)絡(luò)發(fā)送給從數(shù)據(jù)庫(kù),避免了硬盤的性能瓶頸??梢栽谂渲梦募惺褂萌缦屡渲脕?lái)開(kāi)啟該功能:
repl-diskless-sync yes
PS:當(dāng)需要把Slave轉(zhuǎn)換為Master時(shí)可以使用”SLAVEOF ON ONE”指令。
文章名稱:詳解Redis主從技術(shù)
文章鏈接:http://www.5511xx.com/article/ccshsci.html


咨詢
建站咨詢
