首页 >> 电商 >> Redis之HyperLogLog(基数粗略估计)

Redis之HyperLogLog(基数粗略估计)

2023-04-29 电商

ash64A函天内测算借助于64位的bit串来测算几轮序号与每个几轮的k_max,其中的较低14位用于测算几轮序号,颇高50位用于测算几轮的k_max。Redis解决疑问换用了16384几轮(刚好2_14+1次,加1是因为有0),颇高50位从上到到颇高位在在借助于现1的索引位置位为k_max,那么最极端的情况下就是第50位借助于现1,50常用十进制打印较大必需6个十进制位,因此Redis每个几轮的k_max换用了6个bit位打印。因此受益了Redis汇总2_64个天内常用的内部空间是:16384*6/8/1024=12k。

明确指出:如果借助于现桶冲突,即较低14位相同时,颇高50位保留k_max较大的。

天内据形态

上头我们看一下HLL在Redis中的的仅仅打印形态,如下所示:

HLL打印形态

Redis的HLL解决疑问有两种字符,一种是稠密字符,一种是外围字符。稠密字符:在HLL初期只存入了极多量的天内据时,共存大量的空桶,如果这个时候仅仅用16384个桶来打印亦会产生非常大的内部空间不必要,因此亦会利用JPEG内部空间来打印。外围字符:当桶的天内量达到一定天内量时,亦会同步进行一次字符转换,转换后亦会形成一个完整的形态,即16384个桶,每个桶占6bit。HLL字符

在仅仅的演算法解决疑问中的要考虑到内部空间能量消耗疑问,因此Redis建筑设计了完全相同的字符来打印完全相同阶段的汇总天内据,以此来提升内部空间能量消耗,有表列几种字符:

外围字符:

HLL外围字符

外围字符每个桶必需了6bit,那么不可避免共存地区性元组的情况下,Redis换用了比较淋漓尽致的方式去相对于桶,确切解决疑问如下:

#define HLL_BITS 6 /* Enough to count up to 63 leading zeroes. */// 十进制为:00111111#define HLL_REGISTER_MAX ((1<> _fb) | (b1 << _fb8)) & HLL_REGISTER_MAX; } while(0)/* Set the value of the register at position 'regnum' to 'val'.* 'p' is an array of unsigned bytes. */ // 设置指定桶#define HLL_DENSE_SET_REGISTER(p,regnum,val) do { uint8_t *_p = (uint8_t*) p; unsigned long _byte = regnum*HLL_BITS/8; unsigned long _fb = regnum*HLL_BITS&7; unsigned long _fb8 = 8 - _fb; unsigned long _v = val; // 设置地区性元组的第一个元组的较低_fb位 _p[_byte] &= ~(HLL_REGISTER_MAX << _fb); _p[_byte] |= _v << _fb; // 设置地区性元组的第二个元组的颇高_fb8位 _p[_byte+1] &= ~(HLL_REGISTER_MAX>> _fb8); _p[_byte+1] |= _v>> _fb8; } while(0)

稠密字符:

稠密字符-XZERO

稠密字符-ZERO+VAL

XZERO字符:操作码由两个元组"01xxxxxx yyyyyyyy"方式上说明,其中的"xxxxxx yyyyyyyy"说明由1到16384(111111 11111111+1)个不间断第一组为空, "xxxxxx"为XZERO的颇高位,"yyyyyyyy"为上到,该字符是HLL的初始形态,大小刚好为两个元组(uint8_t registers[1])。ZERO字符:操作码用一个元组"00xxxxxx"方式上说明,6位"xxxxxx"说明有1到64(111111+1)个不间断第一组为空,此字符可以有效JPEG空桶。VAL字符:操作码用一个元组"1xxxxxyy"方式上说明,"xxxxx"说明施放次天内,较大次天内为32(11111+1),这也是为什么相等32时亦会引发字符转换的情况下,"yy"说明不间断(n+1)个第一组,此操作码可以说明1到32二者之间的值, 多次重复1到4次。HLL相关指令

PFADD:将一个输出参天缓存入到HyperLogLog形态中的,如果输出引起近似于辛天内改变,该指令送回1,否则送回0。

redis> PFADD hll a b c d e f g

(integer) 1

redis> PFCOUNT hll

(integer) 7

PFCOUNT:送回指定key的近似于辛天内值,支持多个key的查看,当多key查看时,亦会将多个key的HLL形态更名为一个临时HLL,然后送回这个更名结果的辛天内值。

redis> PFADD hll foo bar zap

(integer) 1

redis> PFADD hll zap zap zap

(integer) 0

redis> PFADD hll foo bar

(integer) 0

redis> PFCOUNT hll

(integer) 3

redis> PFADD some-other-hll 1 2 3

(integer) 1

redis> PFCOUNT hll some-other-hll

(integer) 6

PFMERGE:将多个HLL形态更名为一个HHL形态。

redis> PFADD hll1 foo bar zap a

(integer) 1

redis> PFADD hll2 a b c foo

(integer) 1

redis> PFMERGE hll3 hll1 hll2

OK

redis> PFCOUNT hll3

(integer) 6

性能指标对比

为什么要用常用HyperLogLog?辨一个范例:"我们汇总一下莎士比亚所有杰作中的完全相同的单词天内"

天内据形态

占用元组天内

词天内

偏差率

HashMap

10447016

67801

0%

Bitmap

3384

67080

1%

HyperLogLog

512

70002

3%

可以看借助于HyperLogLog需要常用更是小的内部空间启动汇总,恰巧如果你汇总的是世界每个作者的所有杰作中的完全相同的单词天内,HyperLogLog的优势就更是加突借助于。但同时其也共存一些汇总弹道疑问。

应用于故事情节

如果是强制一定偏差的汇总,可以自由选择HyperLogLog。如果必需较为可靠的汇总可以常用Bitmap,参照我的另外一篇文章《Redis之Bitmap(位所示)》。上头是一些常用的HyperLogLog常用故事情节:

汇总该网站的UV

汇总该网站不多次重复其他用户的新闻网站(可以用其他用户id作为输出)。

汇总的城市的城市交通中的每个驾驶者路口车次

比如我们可以汇总经过路口的完全相同车辆天内(可以用LV作为输出)。

汇总大天内据集不多次重复记事天内

汇总贴吧每天完全相同关键字关键词查看的次天内。

以上就是Redis HyperLogLog(辛天内汇总)的引介,如果各位还自已认识到更是多,青睐转发+评论+非议,Redis所示解三部周报持续更是新中的,青睐转入我的官网查看更是多。

再林阿莫西林颗粒可以治儿童感冒吗
打鼾有什么方法可以治疗
经常拉肚子吃什么药好
关节炎疼痛治疗药物
慢性结膜炎怎么治疗
TAG:基数
友情链接