一次失敗的面試,複習一次一致性雜湊演算法

2021-09-26 19:55:31 字數 3080 閱讀 4678

於是呢,煙哥提前十分鐘在公司裡頭找了乙個廁所的坑位,然後進去隨手一鎖門….(以下省略10000字)…

唉…我竟然…

我竟然…

我竟然又帶薪上廁所了,而且上了一小時!我有罪!

額,是這樣的,大廠的廁所是有雅間的。所以環境還馬馬虎虎,鼻子還是正常的!

ok,交待完背景,然後開始我們的主題!

全域性session

當時的情形是這樣的,先介紹一下自己的專案。然後介紹完專案背景以後,因為有乙個登陸模組。於是乎有了如下問題

面試官:「先說說全域性session幹嘛用的,你們那邊全域性session是怎麼做的?」

這個問題還是很容易的。因為乙個應用通常有多台伺服器,在登陸成功後,session只會在其中某一台儲存。需要想辦法讓多台伺服器都識別到這個session,因此才有了這個全域性session的概念。我們用的是後端統一儲存的策略,有專門的使用者管理系統,上面儲存著使用者資訊以及session狀態。

煙哥注:目前業內在解決全域性sesssion上無外乎四種方法

(1)服務端自己進行同步,例如早期的專案,大概是07年那會的(我司老古董專案啊),那會tomcat的集群能力不行。用的是weblogic伺服器,使用的就是weblogic的session複製功能。

(2)客戶端儲存法,將session儲存到瀏覽器cookie中,每次http請求都帶session。這裡摸著良心坦白說,該方案從沒用過,安全性太差。

(3)反向**hash一致性,不需要修改應用**。修改nginx的配置,保證同乙個ip的請求落在同乙個web-server上即可。

(4)後端統一儲存,後端統一找乙個中介軟體將session存起來即可,這個中介軟體是資料庫或者快取。

面試官:「那你知道這個平台裡session怎麼管理的麼?」

必須不知道啊!對我們來說該平台只是乙個黑盒,會調介面即可。

於是乎,乙個讓我頭疼的問題出現了!

面試官:「如果讓你設計這樣乙個平台,管理這些session,你會怎麼設計?」

用redis來儲存session,用sessionid作為key,用session當value進行儲存。

ok,這時我頭腦浮現的架構是這樣的

面試官:「如果redis掛了呢?」

咦,這個時候,我突然懵了。面試官到底想問我什麼?難道掛了,不是redis從伺服器頂上麼?這個問題莫非有什麼玄機?

然後我是這樣答的。

一般情況,主redis掛了,由從redis頂上。如果redis某個slot的主從節點全掛了,

那麼我們在rediscluster中有乙個配置叫

cluster-require-full-coverage

當cluster-require-full-coverage為no時,表示當負責乙個插槽的主庫下線且沒有相應的從庫進行故障恢復時,集群仍然可用。但是該槽的相關命令不可用。

當cluster-require-full-coverage為yes時,表示當負責乙個插槽的主庫下線且沒有相應的從庫進行故障恢復時,集群不可用。

該值預設值為yes,也就是集群處於不可用的狀態。

這個時候,可能出現了網路中斷!

面試官:「你的意思是,redis掛了,整個集群資料就不可用了?」

我回答嗯嗯,是的!

這個時候,面試官

面試官:「你不知道一致性雜湊演算法麼?回去了解一下!」

然後我突然懵了。原來是我想太多,他這樣問完,我才get到他問的點。

煙哥注:所以我才說這個面試我有點失敗,和面試官不在乙個頻道上。如果是現場面,可以現場畫圖,則不會出現這種問題!

面試官想到的架構應該是這樣的

上圖中,由於有4臺伺服器(排除從庫),因此公式為hash(sessionid) % 4 = 2 ,可知定位到了第2號伺服器。

但是呢,普通的如果4臺快取伺服器已經不能滿足我們的快取需求,那麼我們應該怎麼做呢?很簡單,多增加幾台快取伺服器不就行了!

假設:我們增加了一台快取伺服器,那麼快取伺服器的數量就由4臺變成了5臺。那麼原本hash(sessionid) % 4 = 2 的公式就變成了hash(sessionid) % 5 = ?, 可想而知這個結果肯定不是2的,這種情況帶來的結果就是當伺服器數量變動時,所有快取的位置都要發生改變!

於是乎,他才想引我去答一致性雜湊演算法!總之,該死的破網路!導致兩邊不在乙個頻道上!

一致性雜湊

既然都提到了一致性雜湊演算法了,就當複習一下吧~~

一致性雜湊演算法的精髓只有乙個:對2^32次方取模。

我們將二的三十二次方想象成乙個圓,這個圓上的數字就是即0~(2^32)-1。

如下圖所示

這時候有三颱快取伺服器a、b、c。

我們hash(伺服器a的ip位址) % 2^32

插播一下,寫到這裡,這裡我又想起一道題了!

有哪些常見的hash演算法啊?

ok,先繼續我們的話題。經過上面的運算,我們算出的結果一定是乙個0到232-1之間的乙個整數,我們就用算出的這個整數,代表伺服器a,既然這個整數肯定處於0到232-1之間,那麼,上圖中的hash環上必定有乙個點與這個整數對應,我們使用這個整數代表伺服器a,那麼,伺服器a就可以對映到這個環上。

同理進行

hash(伺服器b的ip位址) % 2^32

hash(伺服器c的ip位址) % 2^32

於是,得到了下面這一張圖

那麼,我們要用伺服器儲存session,那麼我們用sessionid做key,進行如下運算

hash(sessionid) % 2^32

得到的乙個環上的值。那我們怎麼知道session被存到哪個伺服器上呢,ok,順時針方向找到的第乙個伺服器就是。如下圖所示

假設,我們現在有四個session,分別進行對映運算後得到如下的環

這麼做的好處?

使用一致性演算法後,當伺服器b移除的時候,伺服器b上的資料會順時針移動到伺服器c上去。從而避免了當伺服器數量發生改變當時候,所有的session都失效。

如下所示

虛擬槽的應用?

真實世界中,伺服器可能對映的並不均勻。這就導致了資料可能是下面這樣的,大量的資料在a伺服器上,導致資料不均勻

為了解決這個問題,我們給a、b、c三颱伺服器引入虛擬節點。如下圖所示(圖中黃色節點為虛擬節點)

如圖所示,2號session和3號session對映到了虛擬b節點,就會儲存到真實的b節點上。通過引入虛擬節點的方式,實現資料的均勻分配!

一次失敗的面試

做任何毫不費力的事情,都是在浪費時間,忘記這是哪本書裡看到的了,到了30歲的年紀,越來越有感觸,記錄失敗的面試,順便祭奠一下被我揮霍掉的這5年。前提 公司從事的行業就不透露了,主要從事一些內部專案,如流程管理,原素材管理等。專案很多,但都不是很大,工作壓力不是很大,只要多了解業務,思路清晰,很多任務...

記一次失敗的面試

面試崗位 遊戲開發 經歷 1 首先上來寫一段 題目要求按給一段字串,按空格劃分從後往前輸出 其實還簡單的,上來一問專業有點虛,直接按最直觀地方式解決問題,分割存在乙個vector中再反向輸出 然後考官問有沒有空間複雜度o 1 的方法,這時候才反應過來,可以從後向前遍歷,遇到空格,輸出乙個單詞,以此類...

一次失敗的面試經歷

昨天久違的去參加了一次.net core 後端開發的面試,由於和之前的面試經歷差異較大,所以記錄下來讓自己警惕一些。回到面試的話題,筆試完了,進入第一步技術面試,面試官是個看上去很年輕的小夥子,上來翻閱了我的簡歷和筆試題大體翻閱了一下,除了告訴了我泛型排序以外,問了我兩個問題 1 net frame...