题目求助|这方法谁看得懂,请大佬讲解一下
404
2021.07.15
2021.07.15
发布于 未知归属地

我们通常使用的md5是32位的hexString(16进制字符),它的空间是128bit,这个量级太大了,我们需要存储的是百亿级,大约是33bit(2的33次方),所以我们需要有一种机制计算出合适位数的散列,而且为了节约内存,我们需要利用全部字符类型(ASCII码在0~127之间)来填充,而不用HexString,这样Key的长度可以缩短到一半。

下面是具体的实现方式

public static byte [] getBucketId(byte [] key, Integer bit) {

MessageDigest mdInst = MessageDigest.getInstance("MD5");

mdInst.update(key);

byte [] md = mdInst.digest();

byte [] r = new byte[(bit-1)/7 + 1];// 因为一个字节中只有7位能够表示成单字符,ascii码是7位

int a = (int) Math.pow(2, bit%7)-2;

md[r.length-1] = (byte) (md[r.length-1] & a);

System.arraycopy(md, 0, r, 0, r.length);

for(int i=0;i<r.length;i++) {

if(r[i]<0) r[i] &= 127;

}

return r;

}
参数bit决定了最终BucketId空间的大小,空间大小集合是2的整数幂次的离散值。这里解释一下为何一个字节中只有7位可用,是因为redis存储key时需要是ASCII(0~127),而不是byte array。如果规划百亿级存储,计划每个桶分担10个kv,那么我们只需2^30=1073741824的桶个数即可,也就是最终key的个数

评论 (0)