大家好呀,我是 31 歲、愛喝奶茶、愛寫 bug、愛分享技術的小米同學

今天繼續給大家講一個我親身經歷的——被 Redis Cluster 當場“拷打”的面試故事。

事情是這樣的。

開局:我滿懷自信進場,結果第一問就被“擊倒”

那天我穿着我最喜歡的“小恐龍衞衣”,滿懷信心走進一家互聯網公司的會議室。

面試官看了我一眼,笑了一下,説:“你寫 Java,這幾年應該用過 Redis 吧?”

我心裏説:那必須哇!緩存我天天寫,Redis 我恨不得能揹着跑。

結果他下一句:

“那説説 Redis Cluster 是怎麼回事?slot 分片是什麼?為什麼 16384?集羣怎麼保證高可用?腦裂怎麼解決?Java 程序用 Redis Cluster 要注意什麼?Multi-key 操作是不是支持?”

我當場:???

這哪是一個問題,這是整個 Redis Cluster 全家桶啊!但作為一個“技術博主小米”,我當然不能慫。

於是這個故事,今天我就用最輕鬆的方式,全部講給你聽。

Redis Cluster 是什麼?我用一個快遞站點的故事解釋

我跟面試官説:“要是讓我用一句話講,它就是 Redis 的分佈式集羣解決方案。”

為了讓對方覺得我不是背書,我給他講了個故事:

想象 Redis 是一個快遞站點,一個站點最多隻能送這麼多包裹。

當包裹越來越多時,就要建更多快遞站點,並且把包裹按照一定規則分到不同站點存放。

而 Redis Cluster 就是——

把所有鍵按 slot 分片,分到多個節點上,每個節點就像一個快遞分站,負責一部分包裹(key)。

面試官點點頭。我繼續説:

Redis Cluster 主要解決兩個問題:

數據分片——怎麼把數據分散到多個節點?

高可用——一個節點掛了怎麼辦?服務是否還能繼續?

Redis Cluster 兩者都解決了。於是我們來説重頭戲:slot。

16384 個 slot 是怎麼回事?我用紅包分配來解釋

我繼續講故事:

你想象一下,你是個超有錢的人,想拆分 16384 個紅包,

然後把它們分別塞到各個“紅包袋”(Redis 節點)裏面。

每個紅包袋負責固定數量的紅包。

客户端只要知道一個 key 的 slot 落在哪個紅包袋,就能準確找到它的值。

這時候面試官忍不住笑了:“這麼解釋不錯,你講具體一點。”

於是我(小米)就把關鍵點講出來:為什麼是 16384?

因為:

  • 槽位越多,集羣越均勻,遷移成本越低
  • 16384 是 2^14,足夠均勻,又不會使節點處理 slot 消息太慢
  • Redis 作者 antirez 考慮了性能和可維護性,最終定這個值

slot 怎麼算?

Redis 用 CRC16:slot = CRC16(key) % 16384

這個公式我沒背,但意思我説對了。面試官點點頭——表示我過關了第一輪。

Cluster 的主從結構:我用“備胎節點”把面試官逗笑了

接着他問:“分片之後怎麼保證高可用?”

我説:“Redis Cluster 每個主節點(master)都會掛一個備胎(slave)。”

面試官樂了:“備胎聽上去不錯,你繼續説。”

我繼續把故事説完整:

每個 master 負責部分 slot

每個 slave 複製對應 master 的數據

當 master 掉線後

集羣會自動把它的 slave 扶正變成新的 master

整個過程不會讓業務停頓

用圖來説就是:

別再被問住!Redis Cluster 一文徹底講透(Java 面試必背)_Java

這就是 Redis Cluster 高可用的基礎。這些內容面試官繼續滿意地點頭。

故障檢測:Redis Cluster 的“自我修復能力”

面試官緊接着問:“那 Redis 怎麼知道哪個節點掛了?”

我立刻説:

Redis Cluster 有 gossip 協議 + 心跳機制

每個節點都會與其它節點發送 ping/pong:

別再被問住!Redis Cluster 一文徹底講透(Java 面試必背)_Redis_02

  • 如果某節點連續幾次沒有響應,它就會被標記為:pfail(疑似宕機)
  • 再進一步,大部分節點都認為它掛了,就會變成:fail(正式宕機)
  • 這時 slave 就會被推舉為新的 master。

這一段講完後,面試官又點頭了,感覺我已經拿到 70 分了。

真正難點:Redis Cluster 如何選舉新主節點?

他接着問:“那 slave 是怎麼被選舉成 master 的?”

我説:選舉和 Raft 一樣嗎?不是!

Redis Cluster 的 slave 選舉邏輯更輕量。核心規則:

  • 延遲最小的 slave 優先:數據最接近最新 master
  • 複製 offset 最大者優先:意味着數據同步最完整
  • 如果有多個候選人,節點 ID 小的優先:其實是為了 deterministic

我用一句話總結:

Redis Cluster 的主從切換依賴“誰的數據最新,誰最早同步”,不是像 Raft 那樣玩投票競選,而是更簡單直接。

大坑:Redis Cluster 不支持 multi-key 操作?!

講完這些,面試官突然問:

“那 Redis Cluster 支持 multi-key 事務嗎?”

我深吸一口氣:終於來了。我跟他説:

答案是:不支持跨 slot 的 multi-key。

比如:MSET a 1 b 2,如果 a 和 b 的 slot 不同:會被拒絕

面試官點點頭。我繼續講重點:如何讓多個 key 在同一個 slot?

Redis 提供 hash tag,比如:

別再被問住!Redis Cluster 一文徹底講透(Java 面試必背)_Java_03

因為 {order} 是相同的,所以它們會被 hash 到同一個 slot,multi-key 就能成立了。

面試官笑得更開心了:“你這講得很完整。”

防止腦裂(split-brain):Redis Cluster 的隱藏絕招

我以為面試結束了,但沒想到對方又問關鍵問題:

“Redis Cluster 怎麼避免腦裂?如果 master 和 slave 網絡分區怎麼辦?”

我繼續講故事:

當 master 被一部分節點認為掛了,而它自己其實還活着,這就是腦裂的前奏。Redis Cluster 的解決方式是:

至少半數 master 節點認為某 master fail 後,才會觸發故障轉移,避免單節點誤判。

而且 master 還能用:cluster-node-timeout,避免長時間收不到心跳的節點“誤以為”對方已掛。

Java 程序如何連接 Redis Cluster?

最後面試官問:“那 Java 用 Redis Cluster,需要注意什麼?”

我果斷説:

1、要用支持 cluster 的客户端

  • JedisCluster
  • Lettuce ClusterClient

2、客户端會自動完成 MOVED 重試

  • 也就是當 key 被遷移時,Redis 會返回:MOVED 1234 10.10.1.3:7001,客户端會自動重定向。

3、最好開啓連接池,多節點連接池,否則容易卡死

4、關閉 Pipeline 和事務(cluster 中不推薦)

5、key 一定要用 hash tag,否則多 key 操作經常失敗

6、業務層注意熱點 key,集羣再分片,也扛不住單節點打滿。

這些都是 Java 場景真正會遇到的問題。面試官非常滿意,讓我回去等消息。

總結:Redis Cluster 面試必背七大點

我最後在文章裏幫你總結一下:

Redis Cluster 七大面試必答項:

Redis Cluster 是 Redis 的分佈式分片 + 高可用方案

使用 16384 slot 分片

slot = CRC16(key) % 16384

主從結構,每個 master 對應若干 slave

故障檢測:gossip + pfail/fail

主從切換:slave 根據 offset 領先度自動晉升

不支持跨 slot 的 multi-key;用 hash tag 解決

面試官一般就考這些。

END

面試結束後我去樓下買了杯奶茶。那天不是我運氣好,而是我真的把 Redis Cluster 學明白了。

如果你準備 Java 社招,這篇文章就是你對 Redis Cluster 最完整的一份“通關手冊”。

我是小米,一個喜歡分享技術的31歲程序員。如果你喜歡我的文章,歡迎關注我的微信公眾號“軟件求生”,獲取更多技術乾貨!