一致性哈希算法相關問題

一致性哈希算法相關問題

老師 這邊演算法的部分有些地方我不是很確定觀念是否正確 不是很懂 思考整理了以後 想請老師指點迷津一下 萬分感謝


*在route(int hashId, List<Server> addressList) function裡

  1. 由url得到的hashId要再做一次我們自己訂的hash是不是因為要和server和其虛擬節點採用一樣的hash算法之後才有辦法排序比較大小 所以才必須再hash一次?

  2. 透過 for 0~7 long hash = hash(e.getId() + i) 虚化若干个服务节点到环上 這種方式 會不會讓同一server的節點和其虛擬節點都在圓環上同一區?還是因為下面hash function有先做過MD5了 所以可以避免掉這問題?

*在long hash(String key) function裡

  1. hashCode & 0xffffffffL 這邊需要 & 0xffffffffL 是不是因為一制性哈希本身能容納的就是32位的long整數範圍?

  2. 這邊要先取md5是不是也是有一部分是為了上面問題2提到的讓同一server的節點和其虛擬節點 不會 都在圓環上同一區?

  3. 最下面圖這段code是不是因為一制性哈希本身能容納的就是32位的long整數,所以透過這段產生一個32位的hashcode?重點只是在產生一個32位的整數?就算想把digest[2]和digest[0]左移的位數互換也ok?

  4. 但最下面圖這段code如果是為了產生一個32位的整數,我有點不太懂,因為我的理解是最高位應該是只有一個char digest[2]的8位再左移16位,也就是24位?

    是為了最高位bit不能是1(負數)的關係麼?

    這樣做最高位的8bit是不是always是0?

    還是這邊是我完全理解錯誤?如果是的話,這邊這樣設計的原因和準則是什麼?再請老師指點一下

hashCode = (() (digest[] & << ))
        | (() (digest[] & << ))
        | (() (digest[] & ))




正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

3回答
zhouywjava 2021-09-06 11:12:22

4. 我也觉得是24位。然后高8位是0 。最后一步与 32个 1 做与操作只是为了将24位格式化为32 位 。也就是说这个hash 有参与计算的只是 digest 的前面3个byte。 不过我觉得 咱们用 前面N 个byte 也可以吧,反正最后一句都会格式化为32位。

姚半仙 2020-10-23 23:37:10
  1. 是的,里层的确实是要采用一样的hash算法

  2. 这个是极简版的一致性哈希,只是为了演示算法思想,简单把server放到环上,但是没有很好的控制散列。会存在你说的情况

*在long hash(String key) function裡

  1. 只取long值低32位数的意思

  2. 是的,尽可能增大散列度,但不是完全间隔相等的一致性哈熟悉

  3. 是的,只要32位就可以再多不要,移动位数不要随便换,不然前面&补码要变

  4. 这段hash移位没有什么特殊意义,只是增加散列的同时,同方法最后一个32位16进制数与操作,保证即便64位数字也永远是个只有低32位的正数

  • 提问者 pinkyTseng #1
    十分感謝老師詳細的解答 這幾天在趕東西和進度 雖然老師回復當天我就看過並想過了 但還沒整理回覆 先前我說的好像有點錯誤 long應該是64位才對,明白只取32位的用意,只剩原本的2個問題和新增的小問題再和老師您確認下,萬分感謝老師 *在long hash(String key) function裡 3.本來的hashCode是不是可由 long hashCode = ((long) (digest[2] & 0xFF << 16)) | ((long) (digest[1] & 0xFF << 8)) | ((long) (digest[0] & 0xFF)); 改成 long hashCode = ((long) (digest[0] & 0xFF << 16)) | ((long) (digest[1] & 0xFF << 8)) | ((long) (digest[2] & 0xFF)); 也ok? 移動位數一樣 只是將位移的2個不同byte互換 4.上面本來的那段code如果是為了產生一個32位的整數,我有點不太懂,因為我的理解是最高位應該是只有一個char digest[2]的8位再左移16位,也就是24位? 是為了最高位bit不能是1(負數)的關係麼? 這樣做最高位的8bit是不是always是0? 如果是這樣分布的點應該會全部集中在右半圓? 5.還有個新增的小問題是 (long) (digest[2] & 0xFF << 16) 是不是該改成 (long) ((digest[2] & 0xFF) << 16)? 另外兩個也是要加上() 我跑原本的寫法會顯示 long d2=(long) (digest[2] & 0xFF << 16); Integer.toBinaryString(digest[2] & 0xFF) == 11001010 Long.toBinaryString(d2) == 111111110000000000000000 => 預期應該是 110010100000000000000000才對吧?
    2020-11-01 12:00:33
姚半仙 2020-10-22 22:51:48

我都忘了当时写的啥了,等我翻下源码

  • 提问者 pinkyTseng #1
    好的 萬分感謝老師^^
    2020-10-23 00:30:40
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师