站長資訊網
        最全最豐富的資訊網站

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

        ?

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

        ?

        前言

        ?

        咔咔整理了一個路線圖,打造一份面試寶典,準備按照這樣的路線圖進行編寫文章,后期發現沒有補充到的知識點在進行添加。也期待各位伙伴一起來幫助補充一下。評論區見哦!

        ?

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

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

        • 集群簡介
        • 集群作用
        • 配置集群
        • 手動、自動故障轉移
        • 故障轉移原理

        本文實現環境

        • centos 7.3
        • redis 4.0
        • redis工作目錄 /usr/local/redis
        • 所有操作均在虛擬機模擬進行

        一、集群簡介

        集群是為了解決主從復制中單機內存上限和并發問題,假如你現在的云服務內存為256GB,當達到這個內存時redis就沒辦法再提供服務,同時數據量能達到這個地步寫數據量也會很大,容易造成緩沖區溢出,造成從節點無限的進行全量復制導致主從無法正常工作。

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

        那么我們就需要把單機的主從改為多對多的方式并且所有的主節點都會連接在一起互相通信。這樣的方式既可以分擔單機內存,也可以分發請求,提高系統的可用性。

        如圖:當有大量請求寫入時,不再會單一的向一個主節點發送指令,而會把指令進行分流到各個主節點,達到分擔內存、避免大量請求的作用。

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

        二、集群作用

        • 分散單機的存儲能力,同時也可以很方便的實現擴展。
        • 分流單機的訪問請求
        • 提高系統的可用性

        如何理解提高系統的可用性這句話,我們看下圖,當master1宕機后對系統的影響不會那么大,仍然可以提供正常的服務。

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

        三、集群存儲結構

        1. 存儲結構

        單機的存儲是當用戶發起請求后直接把key存儲到自己的內存即可。面試問Redis集群,被虐的不行了......集群的存儲結構就沒有那么簡單了,首先當用戶發起一個key指令后需要做的事情。

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

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

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

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

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

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

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

        同樣減少一臺機器后會把去掉的槽在重新分配給其它現有的機器跟新增節點一樣,可以指定節點接收槽。

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

        2. 通訊設計

        集群中的每個節點會在一定的時期給其它節點發送ping消息,其它節點返回pong作為響應。經過一段時間后所有節點都會知道集群全部節點的槽信息。

        如下圖有三個節點,那么就會把16384個哈希槽分成三份。

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

        當用戶發起了一個key的請求,集群是如何處理請求的呢!

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

        如圖所示,用戶發起請求key,redis接收后計算key的槽位置,在根據槽位置找出對應的節點

        如果訪問的槽就在節點本身,那么就會直接返回key對應數據。

        否則會回復moved重定向錯誤, 并且給客戶端返回正確的節點。

        然后重發key指令

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

        四、配置集群

        1. 修改配置文件

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

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

        2. 構建6個節點的配置文件并全啟動

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

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

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

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

        3. 安裝ruby

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

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

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

        查看ruby和gem版本:ruby -v

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

        4. 啟動集群

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

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

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

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

        然后在執行gem install redis就OK面試問Redis集群,被虐的不行了......這時在回頭來執行./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集群,被虐的不行了......「信息解讀」

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

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

        5. 集群設置與獲取數據

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

        在進行設置值的時候提示說重定向到5798的這個槽面試問Redis集群,被虐的不行了......接下來進行獲取數據,會自動的切換節點。面試問Redis集群,被虐的不行了......

        五、故障轉移

        1. 集群從節點下線

        根據上文集群啟動信息知道端口6383是6379的從節點。

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

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

        「總結:從節點下線對集群沒有影響」面試問Redis集群,被虐的不行了......當端口6383上線后,所有的節點會把fail的標記清除面試問Redis集群,被虐的不行了......

        2. 集群主節點下線

        手動下線主節點6379,查看從節點6383日志信息

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

        直到時間到期后,開始故障轉移。

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

        會發現這里竟然存在四個主節點,但是其中一個主節點時下線狀態面試問Redis集群,被虐的不行了......「6379原主節點上線」

        6379上線后,同樣所有的節點也會清除fail信息。

        并且節點信息也會改變,此時的6379改變為6383的從節點。面試問Redis集群,被虐的不行了......

        3. 新增主節點

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

        執行add-node命令,第一個參數為新節點的ip+端口 第二個參數為已存在集群中的節點。根據下圖我們就可以看到新增的節點已經存在集群中了。

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

        執行命令./redis-trib.rb reshard 127.0.0.1:6385

        會提示轉移多少個哈希槽并填寫接收節點的id

        最后一步詢問是否從所有節點中轉移:咔咔使用的是all

        使用指令:cluster nodes查看,6385的這個節點就已經擁有三個范圍的哈希槽了面試問Redis集群,被虐的不行了......

        「主節點已經新增好了,接下來就需要給6385這個主節點配置一個從節點6386」

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

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

        4. 手動故障遷移

        當想對集群中的主節點進行升級的話可以手動執行故障轉移到從節點,避免集群可用性受影響。

        在從節點執行命令:cluster failover

        「執行過程」

        查看節點信息就可以看到6386這個節點已經成為了主機點。

        當給從節點發送cluster failover 指令后,從節點會給主節點發送CLUSTERMSG_TYPE_MFSTART包。從節點請求主節點停止訪問,從而對比兩者的數據偏移量達到一致。

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

        六、故障轉移原理篇

        上文中我們測試了故障轉移,主節點下線后從節點變為主節點,接下來剖析這個過程。

        1. 故障發現到確認

        集群中的每個節點會定期的給其它節點發送ping消息,接收方用pong作為回復。

        如果在cluster-node-timeout的時間內ping消息一直失敗,則會把接收方的節點標記為pfail狀態也就是主觀下線。

        這個下線狀態是不是很熟悉。沒錯,這個跟哨兵判斷主節點是否異常有點相似。當一個哨兵發現主節點有問題時也會標記主節點客觀下線(s_down)。 突然發現跑題了,尷尬…….

        面試問Redis集群,被虐的不行了......在提一下哨兵,當一個哨兵認為主節點異常后標記主觀下線,但是其它哨兵怎么能會同意,不能你說什么就是什么。都會去嘗試連接異常的主節點,當半數以上的哨兵都認為主節點異常后會直接讓其主節點客觀下線。

        同樣集群也不會因為一個節點判斷其狀態為下線就行的,節點直接通過Gossip消息傳播,集群中節點會不斷收集故障節點的下線反饋并且存儲到本地的故障節點下線報告中。當有半數以上的集群主節點都標記為主觀下線后改變狀態為客觀下線。

        最后向集群廣播一條fail消息,通知所有節點將故障節點標記為客觀下線。

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

        2. 故障恢復(從節點從此翻身奴隸把歌唱)

        當故障節點被定義為客觀下線后,故障節點的所有從節點承擔故障恢復的責任。

        故障恢復是從節點通過定時任務發現自己的主機點客觀下線后就會執行故障恢復流程。

        「1. 資格檢查」

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

        「2. 準備選舉時間」

        先說說為什么這里會有一個準備選舉時間。

        資格檢查過后存在多個從節點,那么就需要使用不同的延遲選舉時間來支持優先級。這里的優先級就是 以復制偏移量為基準,偏移量越大與故障主節點的延遲越小,那么就更有機會擁有替換主節點的機會。

        主要的作用就是確保數據一致性最好的節點優先發起選舉

        「3.選舉投票」

        redis集群的投票機制沒有采用從節點進行領導選舉,這點切記不要跟哨兵搞混了。集群的投票機制都是持有槽的主機點進行投票的。

        故障節點的從節點會廣播一個FAILOVER_AUTH_REQUEST 數據包給所有的持有槽的主節點請求投票。

        當主節點回復FAILOVER_AUTH_ACK投票后在NODE_TIMEOUT * 2的這段時間不能給其它的從節點投票

        從節點獲取到半數以上的投票后就會進行故障恢復階段

        「4. 故障轉移」

        選舉成功的從節點取消復制變為主節點

        刪除故障節點的槽,并且將故障節點的槽委托到自己身上

        向集群廣播自己的pong消息,通知主機點的改變和接管了故障節點的槽信息。

        你們想要的ssh的背景!!!

        一篇利用倆個夜晚才弄完的redis哨兵文章,結果你們的關注點卻不在文章本身,啊!小編心很痛

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

        ?

        堅持學習、堅持寫博、堅持分享是咔咔從業以來一直所秉持的信念。希望在偌大互聯網中咔咔的文章能帶給你一絲絲幫助。我們下期再見。

        ?

        推薦:《redis教程》

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 久久永久免费人妻精品下载| 国产精品水嫩水嫩| 亚洲日韩精品一区二区三区| 99久久99久久久精品齐齐| 合区精品中文字幕| 大胸国产精品视频| 91视频国产精品| 久久99精品国产麻豆| 真实国产乱子伦精品一区二区三区| 韩国三级中文字幕hd久久精品| 欧美精品华人在线| 国产91大片精品一区在线观看| 老司机午夜精品视频资源| 在线精品亚洲| 欧美精品一区二区在线精品 | 国产亚洲精品激情都市| 亚洲精品欧美综合| 久久国产精品一区二区| 99久久人妻无码精品系列| 久久久国产乱子伦精品作者| 亚洲精品国产精品乱码视色| 亚洲精品tv久久久久久久久久| 久久激情亚洲精品无码?V| 国产精品久久久久久久午夜片 | 国产精品免费网站| 蜜臀久久99精品久久久久久| 四虎永久在线精品国产免费| 国产精品亚洲午夜一区二区三区 | 国产精品久久久久9999| 国产精品扒开腿做爽爽爽视频 | 国产精品成人不卡在线观看| 2021最新国产精品网站| 国产成人精品999在线观看| 国语精品一区二区三区| 国产精品亚洲一区二区三区在线 | 久久综合国产乱子伦精品免费 | 亚洲国产高清精品线久久| 亚洲国产精品专区在线观看 | 色妞ww精品视频7777| 久久精品国产99久久无毒不卡| 国产在线精品无码二区|