redis主从、哨兵、集群概念
關(guān)于redis主從、哨兵、集群的介紹網(wǎng)上很多,這里就不贅述了。
一、主從
通過(guò)持久化功能,Redis保證了即使在服務(wù)器重啟的情況下也不會(huì)損失(或少量損失)數(shù)據(jù),因?yàn)槌志没瘯?huì)把內(nèi)存中數(shù)據(jù)保存到硬盤(pán)上,重啟會(huì)從硬盤(pán)上加載數(shù)據(jù)。 
 。但是由于數(shù)據(jù)是存儲(chǔ)在一臺(tái)服務(wù)器上的,如果這臺(tái)服務(wù)器出現(xiàn)硬盤(pán)故障等問(wèn)題,也會(huì)導(dǎo)致數(shù)據(jù)丟失。為了避免單點(diǎn)故障,通常的做法是將數(shù)據(jù)庫(kù)復(fù)制多個(gè)副本以部署在不同的服務(wù)器上,這樣即使有一臺(tái)服務(wù)器出現(xiàn)故障,其他服務(wù)器依然可以繼續(xù)提供服務(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ù)分為兩類(lèi),一類(lèi)是主數(shù)據(jù)庫(kù)(master),另一類(lèi)是從數(shù)據(jù)庫(kù)[1] (slave)。主數(shù)據(jù)庫(kù)可以進(jìn)行讀寫(xiě)操作,當(dāng)寫(xiě)操作導(dǎo)致數(shù)據(jù)變化時(shí)會(huì)自動(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ù),而一個(gè)從數(shù)據(jù)庫(kù)只能擁有一個(gè)主數(shù)據(jù)庫(kù)。
主從數(shù)據(jù)庫(kù)的配置
master? slave 
 主不用配置,從redis的conf文件加入 slaveof ip port 就可以了 
 或者從redis啟動(dòng)時(shí)? redis-server --port 6380 --slaveof 127.0.0.1 6379 
 ??? 從數(shù)據(jù)庫(kù)一般是只讀,可以改為可寫(xiě),但寫(xiě)入的數(shù)據(jù)很容易被主同步?jīng)],所以還是只讀就可以。 
 也可以在運(yùn)行是使用slaveof ip port命令,停止原來(lái)的主,切換成剛剛設(shè)置的主? slaveof no one會(huì)把自己變成主 
復(fù)制原理
當(dāng)從數(shù)據(jù)庫(kù)啟動(dòng)時(shí),會(huì)向主數(shù)據(jù)庫(kù)發(fā)送sync命令,主數(shù)據(jù)庫(kù)接收到sync后開(kāi)始在后臺(tái)報(bào)錯(cuò)快照rdb,在保存快照期間受到的命名緩存起來(lái),當(dāng)快照完成時(shí),主數(shù)據(jù)庫(kù)會(huì)將快照和緩存的命令一塊發(fā)送給從。復(fù)制初始化結(jié)束。
 之后,主每受到1個(gè)命令就同步發(fā)送給從。 
 當(dāng)出現(xiàn)斷開(kāi)重連后,2.8之后的版本會(huì)將斷線期間的命令傳給重?cái)?shù)據(jù)庫(kù)。增量復(fù)制 
主從復(fù)制是樂(lè)觀復(fù)制,當(dāng)客戶端發(fā)送寫(xiě)執(zhí)行給主,主執(zhí)行完立即將結(jié)果返回客戶端,并異步的把命令發(fā)送給從,從而不影響性能。也可以設(shè)置至少同步給多少個(gè)從主才可寫(xiě)。 
 無(wú)硬盤(pán)復(fù)制:如果硬盤(pán)效率低將會(huì)影響復(fù)制性能,2.8之后可以設(shè)置無(wú)硬盤(pán)復(fù)制,repl-diskless-sync yes 
二、哨兵
當(dāng)主數(shù)據(jù)庫(kù)遇到異常中斷服務(wù)后,開(kāi)發(fā)者可以通過(guò)手動(dòng)的方式選擇一個(gè)從數(shù)據(jù)庫(kù)來(lái)升格為主數(shù)據(jù)庫(kù),以使得系統(tǒng)能夠繼續(xù)提供服務(wù)。然而整個(gè)過(guò)程相對(duì)麻煩且需要人工介入,難以實(shí)現(xiàn)自動(dòng)化。 為此,Redis 2.8中提供了哨兵工具來(lái)實(shí)現(xiàn)自動(dòng)化的系統(tǒng)監(jiān)控和故障恢復(fù)功能。
 哨兵的作用就是監(jiān)控redis主、從數(shù)據(jù)庫(kù)是否正常運(yùn)行,主出現(xiàn)故障自動(dòng)將從數(shù)據(jù)庫(kù)轉(zhuǎn)換為主數(shù)據(jù)庫(kù)。
顧名思義,哨兵的作用就是監(jiān)控Redis系統(tǒng)的運(yùn)行狀況。它的功能包括以下兩個(gè)。
??? (1)監(jiān)控主數(shù)據(jù)庫(kù)和從數(shù)據(jù)庫(kù)是否正常運(yùn)行。 
 ??? (2)主數(shù)據(jù)庫(kù)出現(xiàn)故障時(shí)自動(dòng)將從數(shù)據(jù)庫(kù)轉(zhuǎn)換為主數(shù)據(jù)庫(kù)。
 可以用info replication查看主從情況 
 例子: 
 1主2從? 1哨兵,可以用命令起也可以用配置文件里 
 可以使用雙哨兵,更安全, 
 redis-server --port 6379 
 redis-server --port 6380 --slaveof 192.168.0.167 6379 
 redis-server --port 6381 --slaveof 192.168.0.167 6379
 redis-sentinel sentinel.conf 
 哨兵配置文件 
 ??? sentinel.conf 
 ??????? sentinel monitor mymaster 192.168.0.167 6379 1? 
其中mymaster表示要監(jiān)控的主數(shù)據(jù)庫(kù)的名字,可以自己定義一個(gè)。這個(gè)名字必須僅由大小寫(xiě)字母、數(shù)字和“.-_”這 3 個(gè)字符組成。后兩個(gè)參數(shù)表示主數(shù)據(jù)庫(kù)的地址和端口號(hào),這里我們要監(jiān)控的是主數(shù)據(jù)庫(kù)6379。
 注意:
??? 1、使用時(shí)不能用127.0.0.1,需要用真實(shí)IP,不然java程序通過(guò)哨兵會(huì)連到j(luò)ava程序所在的機(jī)器(127.0.0.1 )
??? 2、配置哨兵監(jiān)控一個(gè)系統(tǒng)時(shí),只需要配置其監(jiān)控主數(shù)據(jù)庫(kù)即可,哨兵會(huì)自動(dòng)發(fā)現(xiàn)所有復(fù)制該主數(shù)據(jù)庫(kù)的從數(shù)據(jù)庫(kù)
?
這樣哨兵就能監(jiān)控主6379和從6380、6381,一旦6379掛掉,哨兵就會(huì)在2個(gè)從中選擇一個(gè)作為主,根據(jù)優(yōu)先級(jí)選,如果一樣就選個(gè)id小的,當(dāng)6379再起來(lái)就作為從存在。
 
主從切換過(guò)程:
(1)????? slave leader升級(jí)為master 
 (2)????? 其他slave修改為新master的slave 
 (3)????? 客戶端修改連接 
 (4)????? 老的master如果重啟成功,變?yōu)樾耺aster的slave
 哨兵監(jiān)控1主2從,停掉主,哨兵會(huì)選出1個(gè)從作為主,變成1主1從。然而當(dāng)我把原來(lái)的主再起來(lái),它不會(huì)作為從,只是個(gè)獨(dú)立的節(jié)點(diǎn)。
如果在新的主剛被選出來(lái)時(shí),我把原來(lái)的主起來(lái),它就能成為新主的從節(jié)點(diǎn)。 
 如果在新的主選出來(lái)過(guò)一會(huì)再起原來(lái)的主,就不能成為新主的從節(jié)點(diǎn) 
 或者在老的主起來(lái)后,重啟哨兵也能把它變成從,哨兵配置文件里有,哨兵會(huì)執(zhí)行“+convert-to-slave” 
這很奇怪,我也沒(méi)弄明白是怎么回事。
 
三、集群
即使使用哨兵,redis每個(gè)實(shí)例也是全量存儲(chǔ),每個(gè)redis存儲(chǔ)的內(nèi)容都是完整的數(shù)據(jù),浪費(fèi)內(nèi)存且有木桶效應(yīng)。為了最大化利用內(nèi)存,可以采用集群,就是分布式存儲(chǔ)。即每臺(tái)redis存儲(chǔ)不同的內(nèi)容,
 共有16384個(gè)slot。每個(gè)redis分得一些slot,hash_slot = crc16(key) mod 16384 找到對(duì)應(yīng)slot,鍵是可用鍵,如果有{}則取{}內(nèi)的作為可用鍵,否則整個(gè)鍵是可用鍵
 集群至少需要3主3從,且每個(gè)實(shí)例使用不同的配置文件,主從不用配置,集群會(huì)自己選。
修改每個(gè)實(shí)例的配置文件:
??? cluster-enabled yes? --開(kāi)啟集群
??? cluster-config-file nodes-6382.conf --集群配置文件名,每個(gè)實(shí)例配置的要不同,redis會(huì)根據(jù)文件名自動(dòng)新建
用集群工具創(chuàng)建集群:
我們可以用集群工具進(jìn)行集群,該工具是redis源碼包中,用ruby編寫(xiě),所以需要先安裝ruby。
1、安裝rubygems
??? yum install ruby 
 ??? yum install rubygems? 
 ??? gem install redis 
?
2、把6個(gè)redis實(shí)例都起來(lái),每個(gè)實(shí)例的集群都打開(kāi)。
3、redis安裝目錄的src執(zhí)行./redis-trib.rb create --replicas 1 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385
提示信息如下
[java] view plain copy輸入yes,這樣集群就建立了。
登錄任一臺(tái)redis,執(zhí)行 info cluster,提示cluster_enabled:1
集群過(guò)程:
首先redis-trib.rb會(huì)以客戶端的形式嘗試連接所有的節(jié)點(diǎn),并發(fā)送PING命令以確定節(jié)點(diǎn)能夠正常服務(wù)。如果有任何節(jié)點(diǎn)無(wú)法連接,則創(chuàng)建失敗。同時(shí)發(fā)送 INFO 命令獲取每個(gè)節(jié)點(diǎn)的運(yùn)行ID以及是否開(kāi)啟了集群功能(即cluster_enabled為1)。 準(zhǔn)備就緒后集群會(huì)向每個(gè)節(jié)點(diǎn)發(fā)送 CLUSTER MEET命令,格式為 CLUSTER MEET ip port,這個(gè)命令用來(lái)告訴當(dāng)前節(jié)點(diǎn)指定ip和port上在運(yùn)行的節(jié)點(diǎn)也是集群的一部分,從而使得6個(gè)節(jié)點(diǎn)最終可以歸入一個(gè)集群。
然后redis-trib.rb會(huì)分配主從數(shù)據(jù)庫(kù)節(jié)點(diǎn),分配的原則是盡量保證每個(gè)主數(shù)據(jù)庫(kù)運(yùn)行在不同的IP地址上,同時(shí)每個(gè)從數(shù)據(jù)庫(kù)和主數(shù)據(jù)庫(kù)均不運(yùn)行在同一IP地址上,以保證系統(tǒng)的容災(zāi)能力
3主3從,當(dāng)1個(gè)主故障,大家會(huì)給對(duì)應(yīng)的從投票,把從立為主,若沒(méi)有從數(shù)據(jù)庫(kù)可以恢復(fù)則redis集群就down了。
客戶端連接:
使用redis-cli -c -p 任意一個(gè)端口
總結(jié)
以上是生活随笔為你收集整理的redis主从、哨兵、集群概念的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 面试经历---UC(2016年01月11
- 下一篇: 持续交付2.0(一至三章)
