首先,HyperLogLog与布隆过滤器都是针对大数据统计存储应用场景下的知名算法。

HyperLogLog是在大数据的情况下关于数据基数的空间复杂度优化实现,布隆过滤器是在大数据情况下关于检索一个元素是否在一个集合中的空间复杂度优化后的实现。

在传统的数据量比较低的应用服务中,我们要实现数据基数和数据是否存在分析的功能,通常是简单的把所有数据存储下来,直接count一下就是基数了,而直接检索一个元素是否在一个集合中也很简单。

但随着数据量的急剧增大,传统的方式已经很难达到工程上的需求。过大的数据量无论是在存储还是在查询方面都存在巨大的挑战,无论我们是用位存储还是树结构存储等方式来优化,都没法达到大数据时代的要求或者是性价比太低。

于是HyperLogLog与布隆过滤器这两个算法就很好的派上了用场。他们的使用可以极大的节约存储空间,作为代价,则是牺牲了一个小概率的准确性,这可以很好的达到工程上的需求,对于那些要求准确度没那么高,但数据量巨大的需求是非常合适的。

HyperLogLog原理

最直白的解释是,给定一个集合 S,对集合中的每一个元素,我们做一个哈希,假设生成一个 16 位的比特串,从所有生成的比特串中挑选出前面连续 0 次数最多的比特串,假设为 0000000011010110,连续 0 的次数为 8,因此我们可以估计该集合 S 的基数为 2^9。当然单独用这样的单一估计偶然性较大,导致误差较大,因此在实际的 HyperLogLog 算法中,采取分桶平均原理了来消除误差。(这段话引用了 HyperLogLog 原理  中的描述,还有一些细节实现 感兴趣可阅读 https://blockchain.iethpay.com/hyperloglog-theory.html)

特点:实现牺牲了一定的准确度(在一些场景下是可以忽略的),但却实现了空间复杂度上的极大的压缩,可以说是性价比很高的。

虽然基数不完全准确,但是可以符合,随着数量的递增,基数也是递增的。

布隆过滤器原理

布隆过滤器(Bloom Filter)的核心实现是一个超大的位数组和几个哈希函数。假设位数组的长度为m,哈希函数的个数为k,以上图为例,具体的操作流程:假设集合里面有3个元素{x, y, z},哈希函数的个数为3。首先将位数组进行初始化,将里面每个位都设置为0。对于集合里面的每一个元素,将元素依次通过3个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为1。查询W元素是否存在集合中的时候,同样的方法将W通过哈希映射到位数组上的3个点。如果3个点的其中有一个点不为1,则可以判断该元素一定不存在集合中。反之,如果3个点都为1,则该元素可能存在集合中。注意:此处不能判断该元素是否一定存在集合中,可能存在一定的误判率。可以从图中可以看到:假设某个元素通过映射对应下标为4,5,6这3个点。虽然这3个点都为1,但是很明显这3个点是不同元素经过哈希得到的位置,因此这种情况说明元素虽然不在集合中,也可能对应的都是1,这是误判率存在的原因。(这段话与图片引用于 布隆过滤器(Bloom Filter)的原理和实现  中的描述,还有一些细节实现 感兴趣可阅读 https://www.cnblogs.com/cpselvis/p/6265825.html)

特点:巧妙的使用hash算法和bitmap位存储的方式,极大的节约了空间。

由于主要用的是hash算法的特点,所有满足和hash算法相同的规则:当过滤器返回 true时(表示很有可能该值是存在的),有一定概率是误判的,即可能不存在;当过滤器返回false时(表示确定不存在),是可以完全相信的。

我们换个数据的角度来看规则:当数据添加到布隆过滤器中时,对该数据的查询一定会返回true;当数据没有插入过滤器时,对该数据的查询大部分情况返回false,但有小概率返回true,也就是误判。

   我们知道它最终满足的规则和hash的规则是一致的,只是组合了多个hash,使用了bitmap来存储,大大优化了存储的空间和判断的效率。

redis中的HyperLogLog

在redis中对HyperLogLog 的支持早在2.8.9的时候就有了。它的操作非常简单

  • PFADD  给HyperLogLog添加值
  • PFCOUNT 获取基数
  • PFMERGE 合并两个HyperLogLog数据(完美合并,分别添加和统一添加的结果是一致的)

redis中的布隆过滤器

在redis中的布隆过滤器的支持是在redis4.0后支持插件的情况下,通过插件的方式实现的 ,redis的布隆过滤器插件地址:https://github.com/RedisLabsModules/rebloom

它的操作也很简单,以下为几个主要命令,其它命令请参考文档 https://github.com/RedisLabsModules/rebloom/blob/master/docs/Bloom_Commands.md

BF.RESERVE {key} {error_rate} {size}   创建一个布隆过滤器   key为redis存储键值,error_rate 为错误率(大于0,小于1),size为预计存储的数量(size是比较关键的,需要根据自己的需求情况合理估计,设置太小的话会增大错误率,设置太大会占用过多不必要的空间)
BF.ADD {key} {item}  添加值到布隆过滤器中(当过滤器不存在的时候会,会以默认值自动创建一个,建议最好提前创建好)  key为redis存储键值,item为值(如需要添加多个,请使用BF.MADD 可同时添加多个)
BF.EXISTS {key} {item}  判断值是否存在过滤器中  true(表示很可能存在) false (表示绝对不存在)

参考文章:

https://blockchain.iethpay.com/hyperloglog-theory.html   hyperloglog原理

https://www.cnblogs.com/cpselvis/p/6265825.html   布隆过滤器原理

http://redisdoc.com/hyperloglog/index.html   redis的hyperloglog的使用

https://github.com/RedisLabsModules/rebloom/blob/master/docs/Bloom_Commands.md  redis的布隆过滤器的使用

 

浅谈redis的HyperLogLog与布隆过滤器的更多相关文章

  1. $.ajax()方法详解 ajax之async属性 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )

    $.ajax()方法详解   jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Str ...

  2. Python 基于python+mysql浅谈redis缓存设计与数据库关联数据处理

    基于python+mysql浅谈redis缓存设计与数据库关联数据处理 by:授客  QQ:1033553122 测试环境 redis-3.0.7 CentOS 6.5-x86_64 python 3 ...

  3. Redis解读(4):Redis中HyperLongLog、布隆过滤器、限流、Geo、及Scan等进阶应用

    Redis中的HyperLogLog 一般我们评估一个网站的访问量,有几个主要的参数: pv,Page View,网页的浏览量 uv,User View,访问的用户 一般来说,pv 或者 uv 的统计 ...

  4. 浅谈redis和memcached的区别

    缓存技术方面说到redis大家必然会联想到memcached,了解它们的人应该都知道以下几点吧 redis与 memcached相比,redis支持key-value数据类型,同事支持list.set ...

  5. 浅谈Redis数据库的键值设计(转)

    丰富的数据结构使得redis的设计非常的有趣.不像关系型数据库那样,DEV和DBA需要深度沟通,review每行sql语句,也不像memcached那样,不需要DBA的参与.redis的DBA需要熟悉 ...

  6. 浅谈Redis及其安装配置

    一.Redis的介绍 二.Redis的安装配置 三.Redis的配置文件说明 四.Redis的简单操作 简介: Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型. ...

  7. 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )

    很多小伙伴没接触过Redis,以至于去学习的时候感觉云里雾里的,就有一种:教程随你出,懂了算我输的感觉. 每次听圈内人在谈论的时候总是插不上话,小编就偷偷去了解了一下,也算是初入门径. 然后就整理了一 ...

  8. 浅谈Redis之慢查询日志

    首先我们需要知道redis的慢查询日志有什么用?日常在使用redis的时候为什么要用慢查询日志? 第一个问题: 慢查询日志是为了记录执行时间超过给定时长的redis命令请求 第二个问题: 让使用者更好 ...

  9. 浅谈REDIS数据库的键值设计(转)

    add by zhj: 关系数据库表的一条记录可以映射成Redis中的一个hash类型,其实数据库记录本来就是键值对.这样,要比本文中的键设计用更少的键,更节省内存,因为每个键除了它的键值占用内存外, ...

随机推荐

  1. [C++ Primer Plus] 第10章、对象和类(一)程序清单——辨析三个const

    程序清单10.1+10.2+10.3 头文件stock.h #ifndef STOCK00_H_ //先测试x是否被宏定义过 #define STOCK00_H_ //如果没有宏定义,就宏定义x并编译 ...

  2. bzoj 1283 序列 - 费用流

    题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求选出一些数使得原序列中每$m$个连续的数中不超过$K$个被选走.问最大的可能的和. 感觉建图好妙啊.. 考虑把问题转化成选$m$次数,每次 ...

  3. JS(JavaScript)的初了解8(更新中···)

    1.函数都有返回值…… 而方法的本质也是函数,所以也有返回值. Document.getElementById() 返回的是获取的标签 getElementsByClassName()和getElem ...

  4. TCP 传输控制协议

    开头先说几个协议: IP:网际协议 TCP:传输控制协议 Http:超文本传输协议 AMQP:高级消息队列协议 一:TCP是什么? TCP(Transmission Control Protocol ...

  5. 蚂蚁风险大脑亮相ATEC城市峰会:为数字经济时代做好“安全守护”

    2019年1月4日,以“数字金融新原力(The New Force of Digital Finance)”为主题的蚂蚁金服ATEC城市峰会在上海隆重举行.大会聚焦金融数字化转型,分享新技术的发展趋势 ...

  6. .net core json序列化 long类型转化成字符串

    实现类 using System; using System.ComponentModel; using System.Linq; using Newtonsoft.Json; namespace H ...

  7. Linux(例如CentOS 7)打开TCP 22端口,基于SSH协议

    SSH 为 Secure Shell 的缩写,由 IETF 的网络工作小组(Network Working Group)所制定:SSH 为建立在应用层和传输层基础上的安全协议.SSH 是目前较可靠,专 ...

  8. 分布式拒绝服务攻击(DDoS:Distributed Denial of Service)

    DDoS攻击通过大量合法的请求占用大量网络资源,以达到瘫痪网络的目的. 指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高拒绝服务攻击的威力. ...

  9. Oracle 动态sql

    静态SQL是前置编译绑定,动态SQL是后期执行时才编译绑定. 场景: 动态SQL适用于表名及查询字段名未知的情况.在已知查询字段名及表名的情况下,使用动态SQL(字符串拼接方式)会增加硬解析的开销,在 ...

  10. Spring Boot属性文件配置文档(全部)

    This sample file is meant as a guide only. Do not copy/paste the entire content into your applicatio ...