Redis实现唯一计数的3种方法分享
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/121.html?1455855118
唯一计数是网站系统中十分常见的一个功能特性,例如网站需要统计每天访问的人数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 多万用户的一天访问计数情况。涉及的命令如下:#p#分页标题#e#
代码如下:
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 提供的这三种唯一计数方式各有优劣,可以充分满足不同情况下的计数
Redis实现唯一计数的3种方法分享的更多相关文章
- Python中模拟enum枚举类型的5种方法分享
这篇文章主要介绍了Python中模拟enum枚举类型的5种方法分享,本文直接给出实现代码,需要的朋友可以参考下 以下几种方法来模拟enum:(感觉方法一简单实用) 复制代码代码如下: # way1 ...
- debian7更换gcc版本的二种方法分享
debian7更换gcc版本的二种方法分享 最近在编译qt,之前用的是debian6,gcc版本是gcc-4.4,当使用debian7时,编译遇到了很多跟debian6不一样的问题,debian7 ...
- Mysql按条件计数的几种方法
最近在给某网站的后台添加一系列的统计功能,遇到很多需要按条件计数的情况.尝试了几种方法,下面简要记录,供大家参考. 问题描述 为使讨论简单易懂,我将问题稍作简化,去掉诸多的背景. 从前有一个皇帝,他有 ...
- iOS获取设备唯一标识的8种方法
8种iOS获取设备唯一标识的方法,希望对大家有用. UDID UDID(Unique Device Identifier),iOS 设备的唯一识别码,是一个40位十六进制序列(越狱的设备通过某些工具可 ...
- python中统计计数的几种方法
以下实例展示了 count() 方法的使用方法: 1 2 3 4 5 6 # !/usr/bin/python3 T = (123, 'Google', 'Runoob', 'Taobao', 1 ...
- 监控Redis集群,有两种方法
前提条件 redis集群:已搭建三主三从(三台主机) prometheus.grafana已安装 三台主机ip: 192.168.0.39,192.168.0.164,192.168.0.68 第一种 ...
- mssql sqlserver 将字段null(空值)值替换为指定值的三种方法分享
摘要: 下文将分享两种将字段中null值替换为指定值的方法分享,如下所示: 实验环境:sqlserver 2008 R2 例: )) go insert into test(info)values(' ...
- 【python】Python中给List添加元素的4种方法分享
List 是 Python 中常用的数据类型,它一个有序集合,即其中的元素始终保持着初始时的定义的顺序(除非你对它们进行排序或其他修改操作). 在Python中,向List添加元素,方法有如下4种方法 ...
- ipa包如何打包?ios打包ipa的四种方法分享
今天带来的内容是ios打包ipa的四种方法.总结一下,目前.app包转为.ipa包的方法有以下几种,下面一起来看看吧! 1.Apple推荐的方式,即实用xcode的archive功能 Xco ...
随机推荐
- linux下svn常用命令
(如果是第一次提交文件,很可能会出现“svn:'.'不是工作副本”,即当前目录不是工作副本,这个时候需要用到import: eg:svn import . url) 1.将文件checkout到本地目 ...
- bootstrap 模态框禁用空白处点击关闭
bootstrap 3 模态框为信息编辑窗口,默认点击空白处会自动关闭,但是有的时候这个功能需要关闭,比如编辑信息,一不小心点击了空白处,那就要重新编辑了. bootstrap 3 模态框禁用空白处点 ...
- 站内信对话列表sql语句
- UnicodeEncodeError: 'ascii' codec can't encode characters in position问题的解决办法
今天刚开始用ulipad写python代码 代码如下 #! /usr/bin/env python#coding=utf-8a = int(raw_input('请输入一个数:'))if a<1 ...
- 一个日期的下一个星期五 next_date
select next_day('18-5月-2001','星期五') nxt_day from dual;
- IT小喇叭,关注于移动互联网创新、创业的科技媒体
IT小喇叭(itxiaolaba.cn),成立于2015年6月,成都芮嘉科技有限公司旗下品牌.主要负责媒体资源整合,媒体渠道接入,产品宣传,资源整合.对接等,是企业产品宣传,品牌营销的首选. 通过近一 ...
- PSP&进度条
11号 类别 开始时间 结束时间 间隔 净时间 燃尽图 8::00 8:20 0 20分钟 站立会议 8:20 8:50 0 30分钟 读构建之法 9:20 13:20 120分钟 120分钟 四人小 ...
- 爬虫爬数据时,post数据乱码解决办法
最近在写一个爬虫,目标网站是:http://zx.bjmemc.com.cn/,可能是为了防止被爬取数据,它给自身数据加了密.用谷歌自带的抓包工具也不能捕获到数据.于是下了Fiddler. F ...
- maven 简介
本书代码下载 大家可以从我的网站下载本书的代码:http://www.juvenxu.com/mvn-in-action/,也可以通过我的网站与我取得联系,欢迎大家与我交流任何关于本书的问题和关于Ma ...
- CCNA第四章第五章Cisco的IOS与SDM及其管理考试要点学习笔记
1. IOS的用户界面 Cisco互联网操作系统(IOS)是思科路由器和大多数交换机的核心,它是一个可以提供路由,交换,网络互联以及远程通信功能的专有内核. Cisco路由器的IOS软件 ...