<p id="m2nkj"><option id="m2nkj"><big id="m2nkj"></big></option></p>
    <strong id="m2nkj"></strong>
    <ruby id="m2nkj"></ruby>

    <var id="m2nkj"></var>
  • 一致性哈希,原來(lái)這么多學(xué)問(wèn)!

    共 2628字,需瀏覽 6分鐘

     ·

    2021-08-16 07:02

    面試中一致性哈希算法被問(wèn)到的概率非常大,本文將從如下三個(gè)方面探探一致性哈希算法,讓大家輕松應(yīng)對(duì)面試,并且說(shuō)出與眾不同的答案。


    • 一致性哈希算法經(jīng)典使用場(chǎng)景

    • 一致性哈希算法通常不適合用于服務(wù)類負(fù)載均衡

    • 面試應(yīng)對(duì)之策

    1、一致性哈希算法經(jīng)典使用場(chǎng)景


    在數(shù)據(jù)庫(kù)存儲(chǔ)領(lǐng)域如果單表數(shù)據(jù)量很大,通常會(huì)采用分庫(kù)分表,在緩存領(lǐng)域同樣需要分庫(kù),下面以一個(gè)非常常見(jiàn)的Redis分庫(kù)架構(gòu)為例進(jìn)行闡述。

    將上述3個(gè)Redis節(jié)點(diǎn)稱之為分片,每一個(gè)節(jié)點(diǎn)存儲(chǔ)部分?jǐn)?shù)據(jù),需要使用負(fù)載均衡算法,將數(shù)據(jù)盡量分?jǐn)偟礁鱾€(gè)節(jié)點(diǎn),充分發(fā)揮分布式的優(yōu)勢(shì),提升系統(tǒng)緩存訪問(wèn)的性能。

    在分布緩存領(lǐng)域,對(duì)數(shù)據(jù)存在新增與查詢,即數(shù)據(jù)通過(guò)路由算法存儲(chǔ)在某一個(gè)節(jié)點(diǎn)后,查詢時(shí)需要盡量路由到同一個(gè)節(jié)點(diǎn),否則會(huì)出現(xiàn)查詢未命中緩存的情況,這也是與分布式服務(wù)調(diào)用領(lǐng)域的負(fù)載算法一個(gè)不同點(diǎn)。

    分布式緩存存儲(chǔ)類領(lǐng)域的負(fù)載均衡算法通常會(huì)使用某一個(gè)字段當(dāng)分片鍵,在進(jìn)行負(fù)載之前先求出分片字段對(duì)應(yīng)的 HashCode,然后與當(dāng)前的節(jié)點(diǎn)數(shù)取模。即 hashcode(分片鍵) % 節(jié)點(diǎn)總數(shù)(分片總數(shù))

    1.1 分布式緩存領(lǐng)域上述算法的弊端

    先哈希再取模實(shí)現(xiàn)起來(lái)簡(jiǎn)單高效,但在分布式緩存領(lǐng)域存在一個(gè)致命的痛點(diǎn),對(duì)擴(kuò)容、縮容不友好,會(huì)降低緩存的命中率。

    因擴(kuò)容引起的數(shù)據(jù)命中率問(wèn)題示意圖如下:


    例如當(dāng)前集群中由 3 個(gè)節(jié)點(diǎn)存儲(chǔ),現(xiàn)在向集群中寫入 6 個(gè)數(shù)據(jù),其分片鍵的 hashcode 為 1-6,數(shù)據(jù)的分布情況如上述所示。

    但由于隨著業(yè)務(wù)的急劇增長(zhǎng),3 臺(tái) redis 已經(jīng)無(wú)法滿足業(yè)務(wù)的需求,項(xiàng)目組決定對(duì)其進(jìn)行擴(kuò)容,從原先的 3 臺(tái)擴(kuò)容到 4 臺(tái),這個(gè)時(shí)候項(xiàng)目組嘗試去緩存中查找 k1, k2, k3, k4, k5, k6 時(shí)會(huì)出現(xiàn)什么問(wèn)題?

    根據(jù) hashcode 再取模的方式,由于數(shù)量從3臺(tái)到4臺(tái),經(jīng)路由算法路由后,k4 會(huì)嘗試從 3.169 的機(jī)器去查找,但對(duì)應(yīng)的數(shù)據(jù)卻存儲(chǔ)在 3.166 上,以上面 6 個(gè)key的命中來(lái)看,只有 50% 的命中率,擴(kuò)容后帶來(lái)緩存穿透,大量數(shù)據(jù)進(jìn)入穿透到后臺(tái)數(shù)據(jù)庫(kù)。

    面對(duì)上述問(wèn)題第一種解決方案:成倍擴(kuò)容。將原來(lái)的 3 個(gè)節(jié)點(diǎn)數(shù)量翻倍,新增加的第一臺(tái)數(shù)據(jù)來(lái)源于第一臺(tái),以此類推,第 6 臺(tái)的數(shù)據(jù)來(lái)源于第 3 臺(tái),這樣 k6 經(jīng)過(guò)新的負(fù)載均衡算法會(huì)落到第 6 臺(tái),避免了緩存穿透

    成倍擴(kuò)容能有效解決擴(kuò)容后帶來(lái)的緩存穿透問(wèn)題,但這樣做會(huì)造成資源的浪費(fèi),有沒(méi)有其他更好的方法呢?

    一致性哈希算法閃亮登場(chǎng)。

    1.2 一致性哈希算法

    一致性哈希算法的設(shè)計(jì)理念如下圖所示:

    首先將哈希值映射到 0 ~ 2 的 32 次方的一個(gè)圓中,然后將實(shí)際的物理節(jié)點(diǎn)的IP地址或取其可以表示一個(gè)節(jié)點(diǎn)的 hash 值,放入到 hash 環(huán)中。

    然后對(duì)需要插入的數(shù)據(jù)先求哈希,再順時(shí)針沿著哈希環(huán),找到第一個(gè)實(shí)際節(jié)點(diǎn),數(shù)據(jù)將存儲(chǔ)到該實(shí)際節(jié)點(diǎn)上。

    擴(kuò)容后的示例圖:


    從中可以看到受影響的范圍能控制在兩個(gè)節(jié)點(diǎn)的 hashcode 之間的部分?jǐn)?shù)據(jù),比起先哈希再取模,其未命中率將會(huì)得到極大的影響。

    但一致性哈希算法要得到較好的效果,取決于各個(gè)實(shí)體節(jié)點(diǎn)在哈希環(huán)的分布情況,是否能分散,例如如下分布則會(huì)大打折扣:


    這種情況會(huì)造成數(shù)據(jù)分布不均衡,為了解決數(shù)據(jù)很可能分布不均勻的情況,對(duì)一致性哈希算法,提出了改進(jìn),引入了虛擬節(jié)點(diǎn)的,可以設(shè)置一個(gè)哈希環(huán)中存在多少個(gè)虛擬節(jié)點(diǎn),然后將虛擬節(jié)點(diǎn)映射到實(shí)體節(jié)點(diǎn),從而解決數(shù)據(jù)分布不均衡的問(wèn)題。


    這樣通過(guò)為不同的的實(shí)際節(jié)點(diǎn)映射到多個(gè)虛擬節(jié)點(diǎn),實(shí)現(xiàn)數(shù)據(jù)的均勻分布,并且擴(kuò)容或縮容時(shí)并不會(huì)出現(xiàn)大面積的緩存穿透。

    溫馨提示:上述的映射只是一個(gè)理想狀態(tài),其核心思路是為每一個(gè)實(shí)體節(jié)點(diǎn)創(chuàng)建多個(gè)虛擬節(jié)點(diǎn),并且核心虛擬節(jié)點(diǎn)的Hash值越分散越好。

    大家可以思考一下,如何用JAVA來(lái)實(shí)現(xiàn)一致性哈希算法?

    一致性哈希算法的兩個(gè)關(guān)鍵:

    • 順時(shí)針選擇節(jié)點(diǎn)

      可以使用TreeMap,一來(lái)具備排序功能,天然提供了相應(yīng)的方法獲取順時(shí)針的一個(gè)元素。TreeMap 的 ceilingEntry()方法用于返回與大于或等于給定鍵元素(ele)的最小鍵元素鏈接的鍵值對(duì)。

    • 虛擬節(jié)點(diǎn)如何生成分散的哈希值

      生成分散的哈希值,通常可以基于md5來(lái)實(shí)現(xiàn)。


    2、一致性哈希算法被 “濫用”


    一致性哈希算法在面對(duì)分布式緩存有著得天獨(dú)厚的優(yōu)勢(shì),因?yàn)樗漠a(chǎn)生就是為了解決分布式緩存擴(kuò)容、縮容帶來(lái)的緩存穿透問(wèn)題。但現(xiàn)在一致性在分布式服務(wù)調(diào)用的負(fù)載算法竟然也提供了一致性哈希算法的實(shí)現(xiàn)。

    在Dubbo中為了實(shí)現(xiàn)客戶端在服務(wù)調(diào)用時(shí)對(duì)服務(wù)提供者進(jìn)行負(fù)載均衡,官方也提供了一致性哈希算法;

    在RocketMQ集群消費(fèi)模式時(shí)消費(fèi)隊(duì)列的負(fù)載均衡機(jī)制竟然也實(shí)現(xiàn)了一致性哈希算法。

    但我覺(jué)得一致性哈希算法在這些領(lǐng)域完全無(wú)法發(fā)揮其他優(yōu)勢(shì),比輪循、加權(quán)輪循、隨機(jī)、加權(quán)隨機(jī)算法等負(fù)載均衡算法相比,實(shí)現(xiàn)復(fù)雜,性能低下,運(yùn)維管理復(fù)雜

    因?yàn)樵诜?wù)調(diào)用等負(fù)載均衡算法,多次服務(wù)調(diào)用之間關(guān)聯(lián)性不太強(qiáng),在服務(wù)端擴(kuò)容、縮容后,對(duì)于客戶端來(lái)說(shuō)其實(shí)并不關(guān)心路由到哪臺(tái)服務(wù)器,其關(guān)心的是能否返回一臺(tái)服務(wù)器即可。

    3、面試應(yīng)對(duì)之策


    在面試過(guò)程中,遇到一致性哈希算的時(shí)候,盡量能從其使用場(chǎng)景:分布式緩存負(fù)載均衡,特別是突出擴(kuò)容、縮容能有效避免緩存穿透的問(wèn)題。同時(shí)需要闡述一致性哈希算法的缺陷以及其應(yīng)對(duì)策略(虛擬節(jié)點(diǎn))。

    聊的差不多可以順便提一下閱讀過(guò)一致性哈希算法的源碼:強(qiáng)調(diào)TreeMap與虛擬節(jié)點(diǎn)哈希值的生成方法。

    最后可以嘗試引導(dǎo)面試官聊聊現(xiàn)在一致性哈希算法有點(diǎn)被濫用的嫌疑,在輕松愉快的討論中與面試交流技術(shù),面試官好評(píng)度蹭蹭往上漲。

    本文就介紹到這里了,麻煩點(diǎn)亮在看,點(diǎn)贊、轉(zhuǎn)發(fā)、留言是對(duì)我最大的鼓勵(lì)。


    精彩熱文TOP3

    10年IT老兵給職場(chǎng)新人的一些建議
    程序員如何提高影響力

    優(yōu)秀程序員必備技能之如何高效閱讀源碼

    這篇文章出自好基友丁哥,他出版了《RocketMQ 技術(shù)內(nèi)幕》一書,榮獲 RocketMQ 官方社區(qū)優(yōu)秀布道師,在 MQ 領(lǐng)域有著較大的影響力,他將他日均千億級(jí)消息的 MQ 運(yùn)維經(jīng)驗(yàn)整理成了電子書,關(guān)注下方公眾號(hào)回復(fù) RMQPDF 即可免費(fèi)獲取。

    下面是丁哥的個(gè)人微信號(hào),有任何中間件有關(guān)的技術(shù)問(wèn)題,可以撩他討論。


    瀏覽 55
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    <p id="m2nkj"><option id="m2nkj"><big id="m2nkj"></big></option></p>
    <strong id="m2nkj"></strong>
    <ruby id="m2nkj"></ruby>

    <var id="m2nkj"></var>
  • 天天天干天天天日 | 操B美女 操B免费 | 你懂的网址在线观看 | 国产三级网站 | 3级片在线播放 | 国产精品 - 色哟哟 | 91人妻爽 | 91成人在线免费视频 | 天天爽天天操 | 亚洲精品h |