亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長資訊網(wǎng)
    最全最豐富的資訊網(wǎng)站

    面試問Redis集群,被虐的不行了……

    ?

    哨兵主要針對單節(jié)點(diǎn)故障無法自動恢復(fù)的解決方案,集群主要針對單節(jié)點(diǎn)容量、并發(fā)問題、線性可擴(kuò)展性的解決方案。本文使用官方提供的redis cluster。文末有你們想要的設(shè)置ssh背景哦!

    ?

    前言

    ?

    咔咔整理了一個路線圖,打造一份面試寶典,準(zhǔn)備按照這樣的路線圖進(jìn)行編寫文章,后期發(fā)現(xiàn)沒有補(bǔ)充到的知識點(diǎn)在進(jìn)行添加。也期待各位伙伴一起來幫助補(bǔ)充一下。評論區(qū)見哦!

    ?

    面試問Redis集群,被虐的不行了......
    在這里插入圖片描述

    本文主要圍繞如下幾個方面介紹集群

    • 集群簡介
    • 集群作用
    • 配置集群
    • 手動、自動故障轉(zhuǎn)移
    • 故障轉(zhuǎn)移原理

    本文實(shí)現(xiàn)環(huán)境

    • centos 7.3
    • redis 4.0
    • redis工作目錄 /usr/local/redis
    • 所有操作均在虛擬機(jī)模擬進(jìn)行

    一、集群簡介

    集群是為了解決主從復(fù)制中單機(jī)內(nèi)存上限和并發(fā)問題,假如你現(xiàn)在的云服務(wù)內(nèi)存為256GB,當(dāng)達(dá)到這個內(nèi)存時redis就沒辦法再提供服務(wù),同時數(shù)據(jù)量能達(dá)到這個地步寫數(shù)據(jù)量也會很大,容易造成緩沖區(qū)溢出,造成從節(jié)點(diǎn)無限的進(jìn)行全量復(fù)制導(dǎo)致主從無法正常工作。

    面試問Redis集群,被虐的不行了......
    在這里插入圖片描述

    那么我們就需要把單機(jī)的主從改為多對多的方式并且所有的主節(jié)點(diǎn)都會連接在一起互相通信。這樣的方式既可以分擔(dān)單機(jī)內(nèi)存,也可以分發(fā)請求,提高系統(tǒng)的可用性。

    如圖:當(dāng)有大量請求寫入時,不再會單一的向一個主節(jié)點(diǎn)發(fā)送指令,而會把指令進(jìn)行分流到各個主節(jié)點(diǎn),達(dá)到分擔(dān)內(nèi)存、避免大量請求的作用。

    那么指令是如何進(jìn)行分流存儲的呢!我們就需要到集群存儲結(jié)構(gòu)中一探究竟。面試問Redis集群,被虐的不行了......

    二、集群作用

    • 分散單機(jī)的存儲能力,同時也可以很方便的實(shí)現(xiàn)擴(kuò)展。
    • 分流單機(jī)的訪問請求
    • 提高系統(tǒng)的可用性

    如何理解提高系統(tǒng)的可用性這句話,我們看下圖,當(dāng)master1宕機(jī)后對系統(tǒng)的影響不會那么大,仍然可以提供正常的服務(wù)。

    這個時候就會有人問了,當(dāng)master1宕機(jī)后集群這個時候怎么工作呀!這個問題會在下文的故障轉(zhuǎn)移來給你解答。并且在原理篇會對這個問題進(jìn)行詳解面試問Redis集群,被虐的不行了......

    三、集群存儲結(jié)構(gòu)

    1. 存儲結(jié)構(gòu)

    單機(jī)的存儲是當(dāng)用戶發(fā)起請求后直接把key存儲到自己的內(nèi)存即可。面試問Redis集群,被虐的不行了......集群的存儲結(jié)構(gòu)就沒有那么簡單了,首先當(dāng)用戶發(fā)起一個key指令后需要做的事情。

    • 通過CRC16(key)會計(jì)算出來一個值
    • 用這個值取模16384,會得到一個值,我們就先認(rèn)為是28
    • 這個值28就是key保存的空間位置

    那么現(xiàn)在問題來了,這個key到底應(yīng)該存儲在那個redis存儲空間里邊呢!面試問Redis集群,被虐的不行了......

    其實(shí)redis在集群啟動后就已經(jīng)把存儲空間劃分了16384份,每臺主機(jī)保存一部分。

    這里需要注意的是我給每個redis存儲空間里邊的編號就相當(dāng)于一個小的存儲空間(專業(yè)術(shù)語“哈希槽”),你可以理解為一棟樓里邊的編號,一棟樓就是redis的整個存儲空間,每個房子的編號就相當(dāng)于一個存儲空間,這個存儲空間會有一定的區(qū)域來保存對應(yīng)的key,并非上圖取模后的位置。

    箭頭指向的28是指的28會存儲在這個區(qū)域里,這個房子有可能會存儲29、30、31等。

    面試問Redis集群,被虐的不行了......此時問題來了,如果新增、減少一臺機(jī)器后怎么辦呢!看圖說話,能用圖說明盡量不去用文字。

    在新增一臺機(jī)器后,會從其他三個存儲空間中拿出一定的槽分配給新的機(jī)器。這里可以自己設(shè)置想給新的機(jī)器放多少個槽。

    同樣減少一臺機(jī)器后會把去掉的槽在重新分配給其它現(xiàn)有的機(jī)器跟新增節(jié)點(diǎn)一樣,可以指定節(jié)點(diǎn)接收槽。

    所謂的增節(jié)點(diǎn)或去節(jié)點(diǎn)就是改變槽所存儲的位置不同。面試問Redis集群,被虐的不行了......了解了集群的存儲結(jié)構(gòu)后,我們就需要在對另一個問題進(jìn)行說明了,集群是如何設(shè)計(jì)內(nèi)部通訊呢!來了一個值,獲取一個key,去哪拿數(shù)據(jù),跟著這個問題我們看下文。

    2. 通訊設(shè)計(jì)

    集群中的每個節(jié)點(diǎn)會在一定的時期給其它節(jié)點(diǎn)發(fā)送ping消息,其它節(jié)點(diǎn)返回pong作為響應(yīng)。經(jīng)過一段時間后所有節(jié)點(diǎn)都會知道集群全部節(jié)點(diǎn)的槽信息。

    如下圖有三個節(jié)點(diǎn),那么就會把16384個哈希槽分成三份。

    分別為0-5500、5501-11000、11001-16384

    當(dāng)用戶發(fā)起了一個key的請求,集群是如何處理請求的呢!

    下圖的黑框代表這集群所有節(jié)點(diǎn)的槽信息,里邊還有很多其它信息。面試問Redis集群,被虐的不行了......

    如圖所示,用戶發(fā)起請求key,redis接收后計(jì)算key的槽位置,在根據(jù)槽位置找出對應(yīng)的節(jié)點(diǎn)

    如果訪問的槽就在節(jié)點(diǎn)本身,那么就會直接返回key對應(yīng)數(shù)據(jù)。

    否則會回復(fù)moved重定向錯誤, 并且給客戶端返回正確的節(jié)點(diǎn)。

    然后重發(fā)key指令

    面試問Redis集群,被虐的不行了......
    在這里插入圖片描述

    四、配置集群

    1. 修改配置文件

    面試問Redis集群,被虐的不行了......只需要注意咔咔圈中的配置信息即可

    • cluster-enabled yes:開啟集群模式
    • cluster-config-file nodes-6379.conf:集群配置文件
    • clustre-node-timeout 10000:節(jié)點(diǎn)超時時間,這里為了方便測試設(shè)置為10s
    面試問Redis集群,被虐的不行了......
    在這里插入圖片描述

    2. 構(gòu)建6個節(jié)點(diǎn)的配置文件并全啟動

    咔咔給大家提供一個命令可以很方便的替換文件sed 's/6379/6380/g' 6379-redis.conf > 6380-redis.conf

    按照這樣的方式創(chuàng)建出來6個不同端口的配置文件

    面試問Redis集群,被虐的不行了......隨便打開一個配置文件查看,檢測是否替換成功面試問Redis集群,被虐的不行了......為了查看日志信息方便,全部使用前臺啟動。并且查看服務(wù)是否都正常啟動,執(zhí)行命令ps -ef | grep redis

    可以看到啟動后多了個cluster標(biāo)識,代表著都是集群的一個節(jié)點(diǎn)。面試問Redis集群,被虐的不行了......所有節(jié)點(diǎn)啟動完成,集群啟動的指令需要基于ruby(咔咔使用redis版本為4.0)。接下來一起安裝

    3. 安裝ruby

    執(zhí)行命令wget https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.gz

    解壓:tar -xvzf ruby-2.7.1.tar.gz 根據(jù)自己下載的版本來解壓

    安裝:./configure | make | make install這三個指令一氣呵成。

    查看ruby和gem版本:ruby -v

    面試問Redis集群,被虐的不行了......
    在這里插入圖片描述

    4. 啟動集群

    集群的執(zhí)行命令在/usr/local/redis/src/redis-trib.rb

    注意如果需要直接使用redis-trib.rb命令,需要ln到bin目錄下,否則就必須使用./redis-trib.rb的方式。

    如果按照步驟走,這里會出現(xiàn)一個錯誤面試問Redis集群,被虐的不行了......執(zhí)行gem install redis很不幸的是在這里也會出現(xiàn)錯誤。面試問Redis集群,被虐的不行了......隨后需要安裝yum install zlib-develyum install openssl-devel

    安裝完成后,在/ruby-2.7.1/ext/openssl/ruby-2.7.1/ext/zlib 分別執(zhí)行ruby extconf.rb并且執(zhí)行make | make install

    然后在執(zhí)行gem install redis就OK面試問Redis集群,被虐的不行了......這時在回頭來執(zhí)行./redis-trib.rb create --replicas 1 127.0.0.1:6379 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面試問Redis集群,被虐的不行了......「信息解讀」

    創(chuàng)建集群,并且給6個節(jié)點(diǎn)分配哈希槽,后三個節(jié)點(diǎn)配置為前三個節(jié)點(diǎn)的從節(jié)點(diǎn)面試問Redis集群,被虐的不行了......顯示每個節(jié)點(diǎn)的哈希槽信息和節(jié)點(diǎn)ID,最后一步需要輸入yes面試問Redis集群,被虐的不行了......來到data目錄下查看配置文件的變化。配置文件主要信息是每個主節(jié)點(diǎn)分的槽面試問Redis集群,被虐的不行了......面試問Redis集群,被虐的不行了......「查看主機(jī)點(diǎn)的運(yùn)行日志」

    這里給的主要信息cluster status changed:ok 集群狀態(tài)正常面試問Redis集群,被虐的不行了......

    5. 集群設(shè)置與獲取數(shù)據(jù)

    當(dāng)直接設(shè)置數(shù)據(jù)會報錯,并且把name這個key進(jìn)行轉(zhuǎn)化后的槽位置為5798 并且給出了ip地址和端口號。面試問Redis集群,被虐的不行了......需要使用命令redis-cli -c

    在進(jìn)行設(shè)置值的時候提示說重定向到5798的這個槽面試問Redis集群,被虐的不行了......接下來進(jìn)行獲取數(shù)據(jù),會自動的切換節(jié)點(diǎn)。面試問Redis集群,被虐的不行了......

    五、故障轉(zhuǎn)移

    1. 集群從節(jié)點(diǎn)下線

    根據(jù)上文集群啟動信息知道端口6383是6379的從節(jié)點(diǎn)。

    接下來就是讓6383下線查看6379的日志信息。

    6379會報出連接6383丟失,并且給上標(biāo)記fail,表示不可用。這個時候集群還是正常工作的。

    「總結(jié):從節(jié)點(diǎn)下線對集群沒有影響」面試問Redis集群,被虐的不行了......當(dāng)端口6383上線后,所有的節(jié)點(diǎn)會把fail的標(biāo)記清除面試問Redis集群,被虐的不行了......

    2. 集群主節(jié)點(diǎn)下線

    手動下線主節(jié)點(diǎn)6379,查看從節(jié)點(diǎn)6383日志信息

    此時的6383節(jié)點(diǎn)會持續(xù)連接6379共計(jì)10次。那為什么是10次呢! 是根據(jù)我們配置的參數(shù)cluster-node-timeout 10來決定的,這里給我們一個信息就是一秒連接一次

    直到時間到期后,開始故障轉(zhuǎn)移。

    這時6383在故障轉(zhuǎn)移選舉中勝任,翻身奴隸把歌唱,成為了主節(jié)點(diǎn)。面試問Redis集群,被虐的不行了......此時在查看一下集群的節(jié)點(diǎn)信息,命令cluster nodes。

    會發(fā)現(xiàn)這里竟然存在四個主節(jié)點(diǎn),但是其中一個主節(jié)點(diǎn)時下線狀態(tài)面試問Redis集群,被虐的不行了......「6379原主節(jié)點(diǎn)上線」

    6379上線后,同樣所有的節(jié)點(diǎn)也會清除fail信息。

    并且節(jié)點(diǎn)信息也會改變,此時的6379改變?yōu)?383的從節(jié)點(diǎn)。面試問Redis集群,被虐的不行了......

    3. 新增主節(jié)點(diǎn)

    在新增倆個端口6385和6386面試問Redis集群,被虐的不行了......執(zhí)行新增命令./redis-trib.rb add-node 127.0.0.1:6385 127.0.0.1:6379,這里發(fā)送的就是meet消息

    執(zhí)行add-node命令,第一個參數(shù)為新節(jié)點(diǎn)的ip+端口 第二個參數(shù)為已存在集群中的節(jié)點(diǎn)。根據(jù)下圖我們就可以看到新增的節(jié)點(diǎn)已經(jīng)存在集群中了。

    「注意:雖說6385已經(jīng)成為集群中的節(jié)點(diǎn)了,但是跟其它節(jié)點(diǎn)有區(qū)別。它沒有數(shù)據(jù),也就是沒有哈希槽」面試問Redis集群,被虐的不行了......接下來我們就需要把集群中的某些哈希槽分配到這個新節(jié)點(diǎn)上,分配結(jié)束后這個節(jié)點(diǎn)才會成為真正意義上的主節(jié)點(diǎn)

    執(zhí)行命令./redis-trib.rb reshard 127.0.0.1:6385

    會提示轉(zhuǎn)移多少個哈希槽并填寫接收節(jié)點(diǎn)的id

    最后一步詢問是否從所有節(jié)點(diǎn)中轉(zhuǎn)移:咔咔使用的是all

    使用指令:cluster nodes查看,6385的這個節(jié)點(diǎn)就已經(jīng)擁有三個范圍的哈希槽了面試問Redis集群,被虐的不行了......

    「主節(jié)點(diǎn)已經(jīng)新增好了,接下來就需要給6385這個主節(jié)點(diǎn)配置一個從節(jié)點(diǎn)6386」

    命令:./redis-trib.rb add-node --slave --master-id dcc0ec4d0c932ac5c35ae76af4f9c5d27a422d9f 127.0.0.1:6386 127.0.0.1:6385

    master-id是6385的id,第一個參數(shù)為新節(jié)點(diǎn)的ip+端口 第二個為指定的主節(jié)點(diǎn)ip+端口面試問Redis集群,被虐的不行了......

    4. 手動故障遷移

    當(dāng)想對集群中的主節(jié)點(diǎn)進(jìn)行升級的話可以手動執(zhí)行故障轉(zhuǎn)移到從節(jié)點(diǎn),避免集群可用性受影響。

    在從節(jié)點(diǎn)執(zhí)行命令:cluster failover

    「執(zhí)行過程」

    查看節(jié)點(diǎn)信息就可以看到6386這個節(jié)點(diǎn)已經(jīng)成為了主機(jī)點(diǎn)。

    當(dāng)給從節(jié)點(diǎn)發(fā)送cluster failover 指令后,從節(jié)點(diǎn)會給主節(jié)點(diǎn)發(fā)送CLUSTERMSG_TYPE_MFSTART包。從節(jié)點(diǎn)請求主節(jié)點(diǎn)停止訪問,從而對比兩者的數(shù)據(jù)偏移量達(dá)到一致。

    這時客戶端不會連接我們淘汰的主節(jié)點(diǎn),同時主節(jié)點(diǎn)向從節(jié)點(diǎn)發(fā)送復(fù)制偏移量,從節(jié)點(diǎn)得到復(fù)制偏移量后故障轉(zhuǎn)移開始,接著通知主節(jié)點(diǎn)進(jìn)行配置切換,當(dāng)客戶端在舊的master上解鎖后重新連接到新的主節(jié)點(diǎn)上。面試問Redis集群,被虐的不行了......

    六、故障轉(zhuǎn)移原理篇

    上文中我們測試了故障轉(zhuǎn)移,主節(jié)點(diǎn)下線后從節(jié)點(diǎn)變?yōu)橹鞴?jié)點(diǎn),接下來剖析這個過程。

    1. 故障發(fā)現(xiàn)到確認(rèn)

    集群中的每個節(jié)點(diǎn)會定期的給其它節(jié)點(diǎn)發(fā)送ping消息,接收方用pong作為回復(fù)。

    如果在cluster-node-timeout的時間內(nèi)ping消息一直失敗,則會把接收方的節(jié)點(diǎn)標(biāo)記為pfail狀態(tài)也就是主觀下線。

    這個下線狀態(tài)是不是很熟悉。沒錯,這個跟哨兵判斷主節(jié)點(diǎn)是否異常有點(diǎn)相似。當(dāng)一個哨兵發(fā)現(xiàn)主節(jié)點(diǎn)有問題時也會標(biāo)記主節(jié)點(diǎn)客觀下線(s_down)。 突然發(fā)現(xiàn)跑題了,尷尬…….

    面試問Redis集群,被虐的不行了......在提一下哨兵,當(dāng)一個哨兵認(rèn)為主節(jié)點(diǎn)異常后標(biāo)記主觀下線,但是其它哨兵怎么能會同意,不能你說什么就是什么。都會去嘗試連接異常的主節(jié)點(diǎn),當(dāng)半數(shù)以上的哨兵都認(rèn)為主節(jié)點(diǎn)異常后會直接讓其主節(jié)點(diǎn)客觀下線。

    同樣集群也不會因?yàn)橐粋€節(jié)點(diǎn)判斷其狀態(tài)為下線就行的,節(jié)點(diǎn)直接通過Gossip消息傳播,集群中節(jié)點(diǎn)會不斷收集故障節(jié)點(diǎn)的下線反饋并且存儲到本地的故障節(jié)點(diǎn)下線報告中。當(dāng)有半數(shù)以上的集群主節(jié)點(diǎn)都標(biāo)記為主觀下線后改變狀態(tài)為客觀下線。

    最后向集群廣播一條fail消息,通知所有節(jié)點(diǎn)將故障節(jié)點(diǎn)標(biāo)記為客觀下線。

    例如:節(jié)點(diǎn)A發(fā)送ping到節(jié)點(diǎn)B通信異常后標(biāo)記節(jié)點(diǎn)B為pfail,之后節(jié)點(diǎn)A會繼續(xù)給節(jié)點(diǎn)C發(fā)送ping并且攜帶節(jié)點(diǎn)B的pfail信息然后節(jié)點(diǎn)C將節(jié)點(diǎn)B的故障保存到下線報告中。當(dāng)下線報告數(shù)量大于有哈希槽主節(jié)點(diǎn)的一半數(shù)量以上后就會嘗試客觀下線。

    2. 故障恢復(fù)(從節(jié)點(diǎn)從此翻身奴隸把歌唱)

    當(dāng)故障節(jié)點(diǎn)被定義為客觀下線后,故障節(jié)點(diǎn)的所有從節(jié)點(diǎn)承擔(dān)故障恢復(fù)的責(zé)任。

    故障恢復(fù)是從節(jié)點(diǎn)通過定時任務(wù)發(fā)現(xiàn)自己的主機(jī)點(diǎn)客觀下線后就會執(zhí)行故障恢復(fù)流程。

    「1. 資格檢查」

    所有的從節(jié)點(diǎn)都會進(jìn)行檢查與主節(jié)點(diǎn)最后的連接時間,斷線時間大于cluster-node-time*cluster-slave-validity-factor時不具備故障轉(zhuǎn)移的資格。

    「2. 準(zhǔn)備選舉時間」

    先說說為什么這里會有一個準(zhǔn)備選舉時間。

    資格檢查過后存在多個從節(jié)點(diǎn),那么就需要使用不同的延遲選舉時間來支持優(yōu)先級。這里的優(yōu)先級就是 以復(fù)制偏移量為基準(zhǔn),偏移量越大與故障主節(jié)點(diǎn)的延遲越小,那么就更有機(jī)會擁有替換主節(jié)點(diǎn)的機(jī)會。

    主要的作用就是確保數(shù)據(jù)一致性最好的節(jié)點(diǎn)優(yōu)先發(fā)起選舉

    「3.選舉投票」

    redis集群的投票機(jī)制沒有采用從節(jié)點(diǎn)進(jìn)行領(lǐng)導(dǎo)選舉,這點(diǎn)切記不要跟哨兵搞混了。集群的投票機(jī)制都是持有槽的主機(jī)點(diǎn)進(jìn)行投票的。

    故障節(jié)點(diǎn)的從節(jié)點(diǎn)會廣播一個FAILOVER_AUTH_REQUEST 數(shù)據(jù)包給所有的持有槽的主節(jié)點(diǎn)請求投票。

    當(dāng)主節(jié)點(diǎn)回復(fù)FAILOVER_AUTH_ACK投票后在NODE_TIMEOUT * 2的這段時間不能給其它的從節(jié)點(diǎn)投票

    從節(jié)點(diǎn)獲取到半數(shù)以上的投票后就會進(jìn)行故障恢復(fù)階段

    「4. 故障轉(zhuǎn)移」

    選舉成功的從節(jié)點(diǎn)取消復(fù)制變?yōu)橹鞴?jié)點(diǎn)

    刪除故障節(jié)點(diǎn)的槽,并且將故障節(jié)點(diǎn)的槽委托到自己身上

    向集群廣播自己的pong消息,通知主機(jī)點(diǎn)的改變和接管了故障節(jié)點(diǎn)的槽信息。

    你們想要的ssh的背景?。。?/span>

    一篇利用倆個夜晚才弄完的redis哨兵文章,結(jié)果你們的關(guān)注點(diǎn)卻不在文章本身,?。⌒【幮暮芡?/p>

    為了滿足大家的要求,咔咔忍痛說一下如何設(shè)置亮瞎的背景。面試問Redis集群,被虐的不行了......咔咔使用的工具是xsheel面試問Redis集群,被虐的不行了......打開工具選擇選項(xiàng)面試問Redis集群,被虐的不行了......接著到查看有個窗口透明就可以設(shè)置xsheel透明了。面試問Redis集群,被虐的不行了......對嘍!你想的沒錯這就是桌面背景,是不是準(zhǔn)備開始設(shè)置去了。那設(shè)置完了回來再把文章看完好嗎?咔咔也需要各路大神給予技術(shù)點(diǎn)補(bǔ)充和辨錯。

    ?

    堅(jiān)持學(xué)習(xí)、堅(jiān)持寫博、堅(jiān)持分享是咔咔從業(yè)以來一直所秉持的信念。希望在偌大互聯(lián)網(wǎng)中咔咔的文章能帶給你一絲絲幫助。我們下期再見。

    ?

    推薦:《redis教程》

    贊(0)
    分享到: 更多 (0)
    網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號