这篇文章主要介绍了Redis实现唯一计数的3种方法分享,本文讲解了基于SET、基于 bit、基于 HyperLogLog三种方法,需要的朋友可以参考下

唯一计数是网站系统中十分常见的一个功能特性,例如网站需要统计每天访问的人数 unique visitor (也就是 UV)。计数问题很常见,但解决起来可能十分复杂:一是需要计数的量可能很大,比如大型的站点每天有数百万的人访问,数据量相当大;二是通常还希望扩展计数的维度,比如除了需要每天的 UV,还想知道每周或每月的 UV,这样导致计算十分复杂。

在关系数据库存储的系统里,实现唯一计数的方法就是 select count(distinct <item_id>),它十分简单,但是如果数据量很大,这个语句执行是很慢的。用关系数据库另外一个问题是插入数据性能也不高。

Redis 解决这类计数问题得心应手,相比关系数据库速度更快,消耗资源更少,甚至提供了 3 种不同的方法。

1.基于 set

Redis 的 set 用于保存唯一的数据集合,通过它可以快速判断某一个元素是否存在于集合中,也可以快速计算某一个集合的元素个数,另外和可以合并集合到一个新的集合中。涉及的命令如下:

复制代码 代码如下:

SISMEMBER key member  # 判断 member 是否存在
SADD key member # 往集合中加入 member
SCARD key # 获取集合元素个数

基于 set 的方法简单有效,计数精确,适用面广,易于理解,它的缺点是消耗资源比较大(当然比起关系数据库是少很多的),如果元素个数很大(比如上亿的计数),消耗内存很恐怖。

2.基于 bit

Redis 的 bit 可以用于实现比 set 内存高度压缩的计数,它通过一个 bit 1 或 0 来存储某个元素是否存在信息。例如网站唯一访客计数,可以把 user_id 作为 bit 的偏移量 offset,设置为 1 表示有访问,使用 1 MB的空间就可以存放 800 多万用户的一天访问计数情况。涉及的命令如下:

复制代码 代码如下:

SETBIT key offset value  # 设置位信息
GETBIT key offset # 获取位信息
BITCOUNT key [start end] # 计数
BITOP operation destkey key [key ...] # 位图合并

基于 bit 的方法比起 set 空间消耗小得多,但是它要求元素能否简单映射为位偏移,适用面窄了不少,另外它消耗的空间取决于最大偏移量,和计数值无关,如果最大偏移量很大,消耗内存也相当可观。

3.基于 HyperLogLog

实现超大数据量精确的唯一计数都是比较困难的,但是如果只是近似的话,计算科学里有很多高效的算法,其中 HyperLogLog Counting 就是其中非常著名的算法,它可以仅仅使用 12 k左右的内存,实现上亿的唯一计数,而且误差控制在百分之一左右。涉及的命令如下:

复制代码 代码如下:

PFADD key element [element ...]  # 加入元素
PFCOUNT key [key ...] # 计数
这种计数方法真的很神奇,我也没有彻底弄明白,有兴趣可以深入研究相关文章。

redis 提供的这三种唯一计数方式各有优劣,可以充分满足不同情况下的计数要求。

4. 基于bloomfilter

BloomFilter是利用类似位图或者位集合数据结构来存储数据,利用位数组来简洁的表示一个集合,并且能够快速的判断一个元素是不是已经存在于这个集合。虽然BloomFilter不是100%准确,但是可以通过调节参数,使用Hash函数的个数,位数组的大小来降低失误率。这样调节完全可以把失误率降低到接近于0。可以满足大部分场景了。

redis使用布隆过滤器需要安装插件:centos中安装redis插件bloom-filter

Redis去重方法的更多相关文章

  1. redis安装方法

    redis安装方法1.通过lnmp一键安装包,然后执行./addons.sh install redis2.yum -y install redis3.wget http://redis.google ...

  2. 让php Session 存入 redis 配置方法

    首先要做的就是安装redis 安装方法:http://redis.io/download Installation Download, extract and compile Redis with: ...

  3. JS实现数组去重方法总结(六种方法)

    方法一: 双层循环,外层循环元素,内层循环时比较值 如果有相同的值则跳过,不相同则push进数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Array. ...

  4. mssql sqlserver 三种数据表数据去重方法分享

    摘要: 下文将分享三种不同的数据去重方法数据去重:需根据某一字段来界定,当此字段出现大于一行记录时,我们就界定为此行数据存在重复. 数据去重方法1: 当表中最在最大流水号时候,我们可以通过关联的方式为 ...

  5. JS实现数组去重方法大总结

    js数组根据对象中的元素去重: var arr2 = [ { name: "name1", num: "1" }, { name: "name2&qu ...

  6. JavaScript 数组去重方法总结

    1.遍历数组法: 这应该是最简单的去重方法(实现思路:新建一新数组,遍历数组,值不在新数组就加入该新数组中) // 遍历数组去重法 function unique(arr){ var _arr = [ ...

  7. JS实现数组去重方法整理

    前言 我们先来看下面的例子,当然来源与网络,地址<删除数组中多个不连续的数组元素的正确姿势> 我们现在将数组中所有的‘ a’ 元素删除: var arr = ['a', 'a', 'b', ...

  8. Python 三种过滤去重方法

    SET集合去重 set(1,1,2) REDIS去重 布隆过滤器

  9. python scrapy爬虫数据库去重方法

    1. scrapy对request的URL去重 yield scrapy.Request(url, self.parse, dont_filter=False) 注意这个参数:dont_filter= ...

随机推荐

  1. switchery插件:多个按钮,用jquery进行切换

    单个按钮可以参照这个链接https://blog.csdn.net/u012233776/article/details/53305846 多个按钮时, html中其中想操作这个按钮开启与关闭 < ...

  2. 解决dede编辑器不能保存word文档样式问题

    ckeditor在dede里不能保存样式,试过多种解决办法都还是没有解决.最终将编辑器换成FCK得到解决. 第一步:下载FCK编辑器 下载地址: 链接: http://pan.baidu.com/s/ ...

  3. contos 安装 nginx

    参考链接https://blog.csdn.net/u011159417/article/details/80081992 https://blog.csdn.net/wangxy_job/artic ...

  4. centos7.0 能ping通ip 无法ping通域名处理方法

    第一步: 检查 vi   /etc/sysconfig/network-scripts/ifcfg-eth0 查看网卡配置里的dns是否与 vi  /etc/resolv.conf 的 nameser ...

  5. 如何使用云效Flow做质量检测,保障高质量的交付速度

    使用云效Flow做质量检测,保障高质量的交付速度,云效「Flow」 提供代码扫描. 安全扫描和各种自动化测试能力,支持人工测试卡点.自动化验证卡点等多种质量红线,确保业务质量.云效流水线 Flow 流 ...

  6. docker之swarm容器部署及运维

    1.概念 Docker Swarm 是 Docker 的集群管理工具.它将 Docker 主机池转变为单个虚拟 Docker 主机. Docker Swarm 提供了标准的 Docker API,所有 ...

  7. VulnHub 实战靶场Breach-1.0

    相比于CTF题目,Vulnhub的靶场更贴近于实际一些,而且更加综合考察了知识.在这里记录以下打这个靶场的过程和心得. 测试环境 Kali linux IP:192.168.110.128 Breac ...

  8. Java秘诀!Java逻辑运算符介绍

    运算符丰富是 Java 语言的主要特点之一,它提供的运算符数量之多,在高级语言中是少见的. Java 语言中的运算符除了具有优先级之外,还有结合性的特点.当一个表达式中出现多种运算符时,执行的先后顺序 ...

  9. CF193D Two Segments (线段树+dp)(外加两个扩展题)

    大概算是个系列整理 (最强版是模拟赛原题)) 首先,我们先来看这个题目. QWQ一开始是毫无头绪,除了枚举就是枚举 首先,我们可以枚举一个右端点,然后算一下当前右端点的答案 我们令\(f[l,r]\) ...

  10. PTA数据结构 习题2.8 输出全排列 (20分)

    习题2.8 输出全排列 (20分) 请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间. 输入格式: 输入给出正整数n(<10 ...