引言:對(duì)于使用Redis服務(wù)器存儲(chǔ)數(shù)據(jù)的大型網(wǎng)站來(lái)說(shuō),如果僅僅使用一臺(tái)Redis服務(wù)器的話,不僅數(shù)據(jù)存儲(chǔ)速度得不到保證,而且存在很大的風(fēng)險(xiǎn),一旦該機(jī)出現(xiàn)問(wèn)題(例如數(shù)據(jù)丟失,磁盤損壞等),就會(huì)對(duì)網(wǎng)站運(yùn)行造成不利影響。搭建Redis服務(wù)器集群,可以很好的解決該問(wèn)題。如果主服務(wù)器宕機(jī),只需簡(jiǎn)單修改Redis配置文件,就可以讓從服務(wù)器擔(dān)當(dāng)數(shù)據(jù)管理任務(wù)。
從運(yùn)維角度上看,需要了解Redis的持久化概念。持久化指的是將數(shù)據(jù)存儲(chǔ)到斷電后不會(huì)丟失的設(shè)備中,例如將內(nèi)存中的數(shù)據(jù)保存到硬盤中等。Redis支持RDB和AOF兩種持久化方式。對(duì)于前者來(lái)說(shuō),是基于內(nèi)存快照的持久化方式,其工作原理是每隔幾分鐘或者幾次寫操作后,在某一瞬間從內(nèi)存DUMP數(shù)據(jù)形成RDB文件,并將其壓縮保存到指定的目錄。因?yàn)槠浯鎯?chǔ)的是整體內(nèi)存鏡像數(shù)據(jù),所以在恢復(fù)時(shí)速度很快。RDB的配置信息保存在“redis.conf”文件中。
執(zhí)行“vim redis.conf”命令,其中的“save 900 1”行表示在 900秒內(nèi),如果有1條寫入則產(chǎn)生快照。
“save 300 1000”行的作用是如果300秒內(nèi)有1000次數(shù)據(jù)寫入則產(chǎn)生快照。“save 60 10000”行的作用是如果在60秒內(nèi)有10000次數(shù)據(jù)寫入則產(chǎn)生快照。如果將以上三行配置全部屏蔽,則禁用RBD快照功能。
“stop-writes-onbgsave-error”行的作用是當(dāng)后臺(tái)備份進(jìn)程出錯(cuò)時(shí),主進(jìn)程是否停止寫入,“yes”表示確認(rèn),“no”表示否認(rèn)。
“rdbcompression”行的作用是是否對(duì)導(dǎo)出的rdb文件進(jìn)行壓縮。
“Rdbchecksum”行的作用是當(dāng)導(dǎo)入rbd鏡像進(jìn)行數(shù)據(jù)恢復(fù)時(shí),是否檢驗(yàn)rdb的完整性。
“dbfilename”行的作用是指定導(dǎo)出的rdb文件名,“dir”行的作用是指定rdb文件的存儲(chǔ)路徑,默認(rèn)放置在當(dāng)前路徑。當(dāng)Redis服務(wù)器運(yùn)行出現(xiàn)故障時(shí)(例如斷電等),當(dāng)重啟Redis服務(wù)時(shí),其會(huì)自動(dòng)從RDB文件中恢復(fù)數(shù)據(jù)。
使用RDB快照實(shí)現(xiàn)數(shù)據(jù)持久化,存在一個(gè)明顯的問(wèn)題。因?yàn)槠渲荒茉谥付ǖ臅r(shí)間間隔內(nèi)對(duì)從內(nèi)存中DUMP數(shù)據(jù)形成RDB鏡像文件,如果在前一個(gè)快照完成但后一個(gè)快照沒(méi)有創(chuàng)建之間突然斷電,這期間的數(shù)據(jù)顯然無(wú)法保存。
為了實(shí)現(xiàn)更加精細(xì)的持久化,Redis提供了AOF日志記錄功能,可以將所有的操作命令記錄下來(lái)形成日志文件,這樣即使Redis出現(xiàn)異常情況,也可以利用日志進(jìn)行數(shù)據(jù)的快速恢復(fù)。當(dāng)然,RDB和AOF兩種方案可以并存。
執(zhí)行“vim redis.conf”命令,將“appendonly”行的值設(shè)置為“yes”,表示啟用AOF功能,在“appendfilename”欄中可以更改日志文件存儲(chǔ)路徑。在“appendfsync”欄中設(shè)置同步方式,設(shè)置為“always”,表示將每一個(gè)命令都立即同步到aof日志中。設(shè)置為“everysec”表示每秒同步一次,設(shè)置為“no”,表示將入同步工作交給操作系統(tǒng)處理,由操作系統(tǒng)判斷緩沖區(qū)大小并統(tǒng)一寫入到aof日志文件中,其特點(diǎn)是同步頻率低但速度快。
在“no-appendfsync-onrewrite”欄中設(shè)置當(dāng)正在導(dǎo)出rdb快照的過(guò)程中是否停止同步aof日志,在“autoaof-rewrite-percentage 100”欄中設(shè)置aof日志重寫條件,如果當(dāng)前的aof文件大小比上次重寫時(shí)的大小增長(zhǎng)率100%時(shí),則執(zhí)行重寫操作。
重寫是指把內(nèi)存中的數(shù)據(jù),逆化成命令寫入到aof日志中。之所執(zhí)行重寫,為的是避免在aof日志中存儲(chǔ)大量的冗余數(shù)據(jù)。例如對(duì)某個(gè)變量累加了100次,如果執(zhí)行重寫操作,則只記錄最有一次計(jì)算結(jié)果。利用重寫機(jī)制,可以大大減小aof文件的體積。在“auto-aofrewrite-min-size”欄中設(shè)置執(zhí)行重寫操作時(shí),aof的最小體積。默認(rèn)為64MB,即當(dāng)aof文件大于64MB時(shí),必須執(zhí)行重寫操作。
當(dāng)啟動(dòng)AOF日志記錄功能后,當(dāng)Rides服務(wù)出現(xiàn)異常,當(dāng)重啟Redis服務(wù)后,可以發(fā)現(xiàn)數(shù)據(jù)得到很好的恢復(fù)。同RDB快照機(jī)制相比,AOF的數(shù)據(jù)恢復(fù)速度較慢,因?yàn)镽DB是數(shù)據(jù)的內(nèi)存映射,直接載入到內(nèi)存,而aof是命令記錄需要逐條執(zhí)行。
一般來(lái)說(shuō),Redis群集結(jié)構(gòu)包括星形和線形等類型。對(duì)于前者來(lái)說(shuō),多臺(tái)Slave服務(wù)器共同為一臺(tái)Master服務(wù)器提供服務(wù)。對(duì)于后者來(lái)說(shuō),多臺(tái)Slave服務(wù)器之間也存在著從屬關(guān)系,例如當(dāng) Master宕 機(jī) 后,Slave1服務(wù)器可以變?yōu)橹鞣?wù)器,Slave2自動(dòng)變?yōu)槠鋸姆?wù)器。
要想搭建Redis集群,必須了解集群的主從通信原理,即主動(dòng)服務(wù)器之間是如何進(jìn)行同步的。當(dāng)Slave服務(wù)器啟動(dòng)后,確定了其從屬的Master服務(wù)器,其會(huì)自動(dòng)連接到Master主機(jī),并發(fā)出同步請(qǐng)求,Master主機(jī)通過(guò)Dump操作從內(nèi)存中抓取RDB鏡像,并將其該RDB鏡像傳送給Slave主機(jī),Slave主機(jī)直接在內(nèi)存中恢復(fù)該鏡像,這樣兩者的內(nèi)存數(shù)據(jù)實(shí)現(xiàn)了同步。
當(dāng) 然,Master主 機(jī) 的Redis中的命令和數(shù)據(jù)是不斷變化的,這些數(shù)據(jù)會(huì)緩存到內(nèi)存中的AOF隊(duì)列中,之后將AOF數(shù)據(jù)同步到Slave主機(jī)上。這樣,就實(shí)現(xiàn)了主從復(fù)制操作。以后當(dāng)Mater主機(jī)數(shù)據(jù)發(fā)生變動(dòng)后,就會(huì)通過(guò)ReplicationFeedSlaves進(jìn)程通知Slave主機(jī)及時(shí)進(jìn)行同步。
在本例中,使用了星形的群集結(jié)構(gòu),一臺(tái)名為Master的服務(wù)器,兩臺(tái)名稱分別為Slave1和Slave2的從服務(wù)器。在這三臺(tái)主機(jī)上都安裝好Redis。
在Slave1上 執(zhí) 行“vim redis.conf” 命 令,打開(kāi)其配置文件,在其中的“dbfilename”欄中可以更改RDB文件的存儲(chǔ)路徑。刪除“slave of
因?yàn)閯?chuàng)建RDB快照比較消耗IO資源,既然Slave1已經(jīng)默認(rèn)開(kāi)啟了創(chuàng)建RDB快照的功能,Slave2就沒(méi)有必要執(zhí)行相同的操作了。這樣,兩臺(tái)從服務(wù)器就配置完成了。對(duì)于Master服務(wù)器來(lái)說(shuō),執(zhí)行“vim redis.conf”命令,按照同樣的方法,禁用RDB功能,因?yàn)閯?chuàng)建RDB快照的功能已經(jīng)交由Slave1完成。在主從服務(wù)器上分別執(zhí)行“./bin/redisserver redis.conf”命令,來(lái)啟動(dòng)Redis服務(wù)。這樣,Redis群集就已經(jīng)開(kāi)始運(yùn)作了。之后可以對(duì)其進(jìn)行測(cè)試,在Master上 執(zhí) 行“./bin/redis-cli”命令,連接完成后,執(zhí)行“set name xxx”命令,創(chuàng)建一個(gè)Key變量。當(dāng)連接到上述Slave服務(wù)器,執(zhí)行“keys *”命令,可以發(fā)現(xiàn)上面建立的Key值。
但是,當(dāng)試圖在從服務(wù)器上對(duì)指定的Key值進(jìn)行修改時(shí),系統(tǒng)會(huì)顯示“(error)Readonly You cant’t write against a read only slave”內(nèi)容,禁止執(zhí)行寫操作,防止主從服務(wù)器之間出現(xiàn)數(shù)據(jù)不一致的情況。由此看出,Redis群集的搭建可謂簡(jiǎn)單,對(duì)于Master服務(wù)器來(lái)說(shuō),可以關(guān)閉RDB快照功能,將數(shù)據(jù)備份工作交給從服務(wù)器完成,可以根據(jù)需要開(kāi)啟AOF日志功能。
對(duì)于Slave從服務(wù)器來(lái)說(shuō),需要聲明其從屬身份,針對(duì)某個(gè)Slave主機(jī)開(kāi)啟RDB快照功能,并將其設(shè)置為只讀功能。
為了提高安全性,可以根據(jù)需要為群集配置密碼。其方法是在主從服務(wù)器上分別打開(kāi)Redis配置文件,將其中的“requirepass foobared”行前面的“#”符號(hào)刪除,激活其密碼保護(hù)功能,將默認(rèn)的“foobared”的密碼修改為所需的密碼。
設(shè)置了密碼后,當(dāng)連接到主Redis服務(wù)器后,需要執(zhí)行“Auth xxxx”命令,其中的“xxxx”表示具體的密碼,授權(quán)通過(guò)后,才可以執(zhí)行各種指令。對(duì)于從服務(wù)器來(lái)說(shuō),則直接使用該密碼和主服務(wù)器進(jìn)行通訊。
對(duì)于Redis群集來(lái)說(shuō),其實(shí)際上是存在某些缺陷的。即當(dāng)Slave主機(jī)因?yàn)楦鞣N原因和主服務(wù)器斷開(kāi)后,當(dāng)其再次連接Master主機(jī)時(shí),都要再次通過(guò)Dump操作從Master主機(jī)內(nèi)存中抓取RDB鏡像,并將其該RDB鏡像傳送給Slave主機(jī),Slave主機(jī)直接在內(nèi)存中恢復(fù)該鏡像。同時(shí)將Master主機(jī)上AOF數(shù)據(jù)同步到Slave主機(jī)上。
在這種情況下,不要將所有的Slave服務(wù)器全部啟動(dòng)起來(lái),否則很可能導(dǎo)致Master主機(jī)的IO吞吐量劇增,處理方法是分時(shí)逐臺(tái)啟動(dòng)Slave服務(wù)器,以降低Master主機(jī)的工作壓力。