摘要:面試官要不你來講講你最近在看的點(diǎn)唄可以拉出來一起討論下今天我也不知道要問什么候選者最近在看相關(guān)的內(nèi)容面試官嗯,我記得已經(jīng)問過的基礎(chǔ)和持久化了面試官要不你來講講你公司的是什么架構(gòu)的咯候選者我前公司的架構(gòu)是分片集群,使用的是層來對(duì)進(jìn)行分流到不同
面試官:要不你來講講你最近在看的點(diǎn)唄?可以拉出來一起討論下(今天我也不知道要問什么)
候選者:最近在看「Redis」相關(guān)的內(nèi)容
面試官:嗯,我記得已經(jīng)問過Redis的基礎(chǔ)和持久化了
面試官:要不你來講講你公司的Redis是什么架構(gòu)的咯?
候選者:我前公司的Redis架構(gòu)是「分片集群」,使用的是「Proxy」層來對(duì)Key進(jìn)行分流到不同的Redis服務(wù)器上
候選者:支持動(dòng)態(tài)擴(kuò)容、故障恢復(fù)等等...
面試官:那你來聊下Proxy層的架構(gòu)和基本實(shí)現(xiàn)原理?
候選者:抱歉,這塊由中間件團(tuán)隊(duì)負(fù)責(zé),具體我也沒仔細(xì)看過
候選者:...
面試官:....
候選者:不過,我可以給你講講現(xiàn)有常見開源的Redis架構(gòu)(:
面試官:那只能這樣了,好吧,你開始吧
候選者:那我從基礎(chǔ)講起吧?
候選者:在之前提到了Redis有持久化機(jī)制,即便Redis重啟了,可以依靠RDB或者AOF文件對(duì)數(shù)據(jù)進(jìn)行重新加載
候選者:但在這時(shí),只有一臺(tái)Redis服務(wù)器存儲(chǔ)著所有的數(shù)據(jù),此時(shí)如果Redis服務(wù)器「暫時(shí)」沒辦法修復(fù)了,那依賴Redis的服務(wù)就沒了
候選者:所以,為了Redis「高可用」,現(xiàn)在基本都會(huì)給Redis做「備份」:多啟一臺(tái)Redis服務(wù)器,形成「主從架構(gòu)」
候選者:「從服務(wù)器」的數(shù)據(jù)由「主服務(wù)器」復(fù)制過去,主從服務(wù)器的數(shù)據(jù)是一致的
候選者:如果主服務(wù)器掛了,那可以「手動(dòng)」把「從服務(wù)器」升級(jí)為「主服務(wù)器」,縮短不可用時(shí)間
面試官:那「主服務(wù)器」是如何把自身的數(shù)據(jù)「復(fù)制」給「從服務(wù)器」的呢?
候選者:「復(fù)制」也叫「同步」,在Redis使用的是「PSYNC」命令進(jìn)行同步,該命令有兩種模型:完全重同步和部分重同步
候選者:可以簡單理解為:如果是第一次「同步」,從服務(wù)器沒有復(fù)制過任何的主服務(wù)器,或者從服務(wù)器要復(fù)制的主服務(wù)器跟上次復(fù)制的主服務(wù)器不一樣,那就會(huì)采用「完全重同步」模式進(jìn)行復(fù)制
候選者:如果只是由于網(wǎng)絡(luò)中斷,只是「短時(shí)間」斷連,那就會(huì)采用「部分重同步」模式進(jìn)行復(fù)制
候選者:(假如主從服務(wù)器的數(shù)據(jù)差距實(shí)在是過大了,還是會(huì)采用「完全重同步」模式進(jìn)行復(fù)制)
面試官:那「同步」的原理過程可以稍微講下嘛?
候選者:嗯,沒問題的
候選者:主服務(wù)器要復(fù)制數(shù)據(jù)到從服務(wù)器,首先是建立Socket「連接」,這個(gè)過程會(huì)干一些信息校驗(yàn)啊、身份校驗(yàn)啊等事情
候選者:然后從服務(wù)器就會(huì)發(fā)「PSYNC」命令給主服務(wù)器,要求同步(這時(shí)會(huì)帶「服務(wù)器ID」RUNID和「復(fù)制進(jìn)度」offset參數(shù),如果從服務(wù)器是新的,那就沒有)
候選者:主服務(wù)器發(fā)現(xiàn)這是一個(gè)新的從服務(wù)器(因?yàn)閰?shù)沒帶上來),就會(huì)采用「完全重同步」模式,并把「服務(wù)器ID」(runId)和「復(fù)制進(jìn)度」(offset)發(fā)給從服務(wù)器,從服務(wù)器就會(huì)記下這些信息。
面試官:嗯...
候選者:隨后,主服務(wù)器會(huì)在后臺(tái)生成RDB文件,通過前面建立好的連接發(fā)給從服務(wù)器
候選者:從服務(wù)器收到RDB文件后,首先把自己的數(shù)據(jù)清空,然后對(duì)RDB文件進(jìn)行加載恢復(fù)
候選者:這個(gè)過程中,主服務(wù)器也沒閑著(繼續(xù)接收著客戶端的請(qǐng)求)
面試官:嗯...
候選者:主服務(wù)器把生成RDB文件「之后修改的命令」會(huì)用「buffer」記錄下來,等到從服務(wù)器加載完RDB之后,主服務(wù)器會(huì)把「buffer」記錄下的命令都發(fā)給從服務(wù)器
候選者:這樣一來,主從服務(wù)器就達(dá)到了數(shù)據(jù)一致性了(復(fù)制過程是異步的,所以數(shù)據(jù)是『最終一致性』)
面試官:嗯...
面試官:那「部分重同步」的過程呢?
候選者:嗯,其實(shí)就是靠「offset」來進(jìn)行部分重同步。每次主服務(wù)器傳播命令的時(shí)候,都會(huì)把「offset」給到從服務(wù)器
候選者:主服務(wù)器和從服務(wù)器都會(huì)將「offset」保存起來(如果兩邊的offset存在差異,那么說明主從服務(wù)器數(shù)據(jù)未完全同步)
候選者:從服務(wù)器斷連之后,就會(huì)發(fā)「PSYNC」命令給主服務(wù)器,同樣也會(huì)帶著RUNID和offset(重連之后,這些信息還是存在的)
面試官:嗯...
候選者:主服務(wù)器收到命令之后,看RUNID是否能對(duì)得上,對(duì)得上,說明這可能以前就復(fù)制過一部分了
候選者:接著檢查該「offset」是否在主服務(wù)器記錄的offset還存在
候選者:(這里解釋下,因?yàn)橹鞣?wù)器記錄offset使用的是一個(gè)環(huán)形buffer,如果該buffer滿了,會(huì)覆蓋以前的記錄)
候選者:如果找到了,那就把從缺失的一部分offer開始,把對(duì)應(yīng)的修改命令發(fā)給從服務(wù)器
候選者:如果從環(huán)形buffer沒找到,那只能使用「完全重同步」模式再次進(jìn)行主從復(fù)制了
面試官:主從復(fù)制這塊我了解了,那你說到現(xiàn)在,Redis主庫如果掛了,你還是得「手動(dòng)」將從庫升級(jí)為主庫啊
面試官:你知道有什么辦法能做到「自動(dòng)」進(jìn)行故障恢復(fù)嗎?
候選者:必須的啊,接下來就到了「哨兵」登場(chǎng)了
面試官:開始你的表演吧。
候選者:「哨兵」干的事情主要就是:監(jiān)控(監(jiān)控主服務(wù)器的狀態(tài))、選主(主服務(wù)器掛了,在從服務(wù)器選出一個(gè)作為主服務(wù)器)、通知(故障發(fā)送消息給管理員)和配置(作為配置中心,提供當(dāng)前主服務(wù)器的信息)
候選者:可以把「哨兵」當(dāng)做是運(yùn)行在「特殊」模式下的Redis服務(wù)器,為了「高可用」,哨兵也是集群架構(gòu)的。
候選者:首先它需要跟Redis主從服務(wù)器創(chuàng)建對(duì)應(yīng)的連接(獲取它們的信息)
候選者:每個(gè)哨兵不斷地用ping命令看主服務(wù)器有沒有下線,如果主服務(wù)器在「配置時(shí)間」內(nèi)沒有正常響應(yīng),那當(dāng)前哨兵就「主觀」認(rèn)為該主服務(wù)器下線了
候選者:其他「哨兵」同樣也會(huì)ping該主服務(wù)器,如果「足夠多」(還是看配置)的哨兵認(rèn)為該主服務(wù)器已經(jīng)下線,那就認(rèn)為「客觀下線」,這時(shí)就要對(duì)主服務(wù)器執(zhí)行故障轉(zhuǎn)移操作。
面試官:嗯...
候選者:「哨兵」之間會(huì)選出一個(gè)「領(lǐng)頭」,選出領(lǐng)頭的規(guī)則也比較多,總的來說就是先到先得(哪個(gè)快,就選哪個(gè))
候選者:由「領(lǐng)頭哨兵」對(duì)已下線的主服務(wù)器進(jìn)行故障轉(zhuǎn)移
面試官:嗯...
候選者:首先要在「從服務(wù)器」上挑選出一個(gè),來作為主服務(wù)器
候選者:(這里也挑選講究,比如:從庫的配置優(yōu)先級(jí)、要判斷哪個(gè)從服務(wù)器的復(fù)制offset最大、RunID大小、跟master斷開連接的時(shí)長...)
候選者:然后,以前的從服務(wù)器都需要跟新的主服務(wù)器進(jìn)行「主從復(fù)制」
候選者:已經(jīng)下線的主服務(wù)器,再次重連的時(shí)候,需要讓他成為新的主服務(wù)器的從服務(wù)器
面試官:嗯...我想問問,Redis在主從復(fù)制的和故障轉(zhuǎn)移的過程中會(huì)導(dǎo)致數(shù)據(jù)丟失嗎
候選者:顯然是會(huì)的,從上面的「主從復(fù)制」流程來看,這個(gè)過程是異步的(在復(fù)制的過程中:主服務(wù)器會(huì)一直接收請(qǐng)求,然后把修改命令發(fā)給從服務(wù)器)
候選者:假如主服務(wù)器的命令還沒發(fā)完給從服務(wù)器,自己就掛掉了。這時(shí)候想要讓從服務(wù)器頂上主服務(wù)器,但從服務(wù)器的數(shù)據(jù)是不全的(:
候選者:還有另一種情況就是:有可能哨兵認(rèn)為主服務(wù)器掛了,但真實(shí)是主服務(wù)器并沒有掛( 網(wǎng)絡(luò)抖動(dòng)),而哨兵已經(jīng)選舉了一臺(tái)從服務(wù)器當(dāng)做是主服務(wù)器了,此時(shí)「客戶端」還沒反應(yīng)過來,還繼續(xù)寫向舊主服務(wù)器寫數(shù)據(jù)
候選者:等到舊主服務(wù)器重連的時(shí)候,已經(jīng)被納入到新主服務(wù)器的從服務(wù)器了...所以,那段時(shí)間里,客戶端寫進(jìn)舊主服務(wù)器的數(shù)據(jù)就丟了
候選者:上面這兩種情況(主從復(fù)制延遲&&腦裂),都可以通過配置來「盡可能」避免數(shù)據(jù)的丟失
候選者:(達(dá)到一定的閾值,直接禁止主服務(wù)器接收寫請(qǐng)求,企圖減少數(shù)據(jù)丟失的風(fēng)險(xiǎn))
面試官:要不再來聊聊Redis分片集群?
候選者:嗯...分片集群說白了就是往每個(gè)Redis服務(wù)器存儲(chǔ)一部分?jǐn)?shù)據(jù),所有的Redis服務(wù)器數(shù)據(jù)加起來,才組成完整的數(shù)據(jù)(分布式)
候選者:要想組成分片集群,那就需要對(duì)不同的key進(jìn)行「路由」(分片)
候選者:現(xiàn)在一般的路由方案有兩種:「客戶端路由」(SDK)和「服務(wù)端路由」(Proxy)
候選者:客戶端路由的代表(Redis Cluster),服務(wù)端路由的代表(Codis)
面試官:要不來詳細(xì)講講它們的區(qū)別唄?
候選者:今天有點(diǎn)兒困了,要不下次唄?
本文總結(jié):
Redis實(shí)現(xiàn)高可用:
主從復(fù)制原理:
哨兵機(jī)制:
數(shù)據(jù)丟失:
歡迎關(guān)注我的微信公眾號(hào)【Java3y】來聊聊Java面試,對(duì)線面試官系列持續(xù)更新中!
【對(duì)線面試官-移動(dòng)端】系列 一周兩篇持續(xù)更新中!
【對(duì)線面試官-電腦端】系列 一周兩篇持續(xù)更新中!
原創(chuàng)不易??!求三連??!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/123762.html
摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對(duì)象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對(duì)象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對(duì)象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
閱讀 2970·2021-11-22 15:25
閱讀 2251·2021-11-18 10:07
閱讀 1057·2019-08-29 15:29
閱讀 483·2019-08-29 13:25
閱讀 1514·2019-08-29 12:58
閱讀 3210·2019-08-29 12:55
閱讀 2923·2019-08-29 12:28
閱讀 514·2019-08-29 12:16