`
wbj0110
  • 浏览: 1610065 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

使用Redis bitmaps进行快速、简单、实时统计

阅读更多

原文:Fast, easy, realtime metrics using Redis bitmaps

 (http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/

 

 

    getspool.com的重要统计数据是实时计算的。Redis的bitmap让我们可以实时的进行类似的统计,并且极其节省空间。在模拟1亿2千8百万用户的模拟环境下,在一台MacBookPro上,典型的统计如“日用户数”(dailyunique users) 的时间消耗小于50ms, 占用16MB内存。Spool现在还没有1亿2千8百万用户,但是我们的方案可以应对这样的规模。我们想分享这是如何做到的,也许能帮到其它创业公司。

 

   

Bitmap以及Redis Bitmaps快速入门(Crash Course on Bitmap and Redis Bitmaps)

Bitmap(即Bitset)

    Bitmap是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset),在bitmap上可执行AND,OR,XOR以及其它位操作。

 

 

位图计数(Population Count)

 

    位图计数统计的是bitmap中值为1的位的个数。位图计数的效率很高,例如,一个bitmap包含10亿个位,90%的位都置为1,在一台MacBook Pro上对其做位图计数需要21.1ms。SSE4甚至有对整形(integer)做位图计数的硬件指令。

 

 

Redis Bitmaps

    Redis允许使用二进制数据的Key(binary keys) 和二进制数据的Value(binary values)。Bitmap就是二进制数据的value。Redis的 setbit(key, offset, value)操作对指定的key的value的指定偏移(offset)的位置1或0,时间复杂度是O(1)。

 

 

一个简单的例子:日活跃用户

    为了统计今日登录的用户数,我们建立了一个bitmap,每一位标识一个用户ID。当某个用户访问我们的网页或执行了某个操作,就在bitmap中把标识此用户的位置为1。在Redis中获取此bitmap的key值是通过用户执行操作的类型和时间戳获得的。

 

   

    这个简单的例子中,每次用户登录时会执行一次redis.setbit(daily_active_users, user_id, 1)。将bitmap中对应位置的位置为1,时间复杂度是O(1)。统计bitmap结果显示有今天有9个用户登录。Bitmap的key是daily_active_users,它的值是1011110100100101。

   

    因为日活跃用户每天都变化,所以需要每天创建一个新的bitmap。我们简单地把日期添加到key后面,实现了这个功能。例如,要统计某一天有多少个用户至少听了一个音乐app中的一首歌曲,可以把这个bitmap的redis key设计为play:yyyy-mm-dd-hh。当用户听了一首歌曲,我们只是简单地在bitmap中把标识这个用户的位置为1,时间复杂度是O(1)。

 

[java] view plaincopy
 
  1. Redis.setbit(play:yyyy-mm-dd, user_id, 1)  

 

    今天听过歌曲的用户就是key是play:yyyy-mm-dd的bitmap的位图计数。如果要按周或月统计,只要对这周或这个月的所有bitmap求并集,得出新的bitmap,在对它做位图计数。



 

    利用这些bitmap做其它复杂的统计也非常容易。例如,统计11月听过歌曲的高级用户(premium user):

(play:2011-11-01∪ play:2011-11-02∪ … ∪ play:2011-11-30)∩premium:2011-11

 

 

1亿2千8百万用户的性能比较(Performance comparison using 128 million users)

    下面的表格显示了在1亿2千8百万用户上完成的时间粒度为1天,一周,一个月的用户统计的时间消耗比较。

 

Period Time(ms)
Daily 50.2
Weekly 392.0
Monthly 1624.8

 

 

 

优化(Optimizations)

    前面的例子中,我们把日统计,周统计,月统计缓存到Redis,以加快统计速度。

   

    这是一种非常灵活的方法。这样进行缓存的额外红利是可以进行更多的统计,如每周活跃的手机用户—求手机用户的bitmap与周活跃用户的交集。或者,如果要统计过去n天的活跃用户数,缓存的日活跃用户使这样的统计变得简单——从cache中获取过去n-1天的日活跃用户bitmap和今天的bitmap,对它们做并集(Union),时间消耗是50ms。

 

 

示例代码(SampleCode)

下面的Java代码用来统计某个用户操作在某天的活跃用户。

 

[java] view plaincopy
 
  1. import redis.clients.jedis.Jedis;  
  2. import java.util.BitSet;  
  3. ...  
  4.     Jedis redis = new Jedis("localhost");  
  5.     ...  
  6.     public int uniqueCount(String action, String date) {  
  7.         String key = action + ":" + date;  
  8.         BitSet users = BitSet.valueOf(redis.get(key.getBytes()));  
  9.         return users.cardinality();  
  10.     }     

 

 

下面的Java代码用来统计某个用户操作在一个指定多个日期的活跃用户。

[java] view plaincopy
 
  1. import redis.clients.jedis.Jedis;  
  2. import java.util.BitSet;  
  3. ...  
  4.     Jedis redis = new Jedis("localhost");  
  5.     ...  
  6.     public int uniqueCount(String action, String... dates) {  
  7.         BitSet all = new BitSet();  
  8.         for (String date : dates) {  
  9.             String key = action + ":" + date;  
  10.             BitSet users = BitSet.valueOf(redis.get(key.getBytes()));  
  11.             all.or(users);  
  12.         }  
  13.         return all.cardinality();  
  14.     }  

 

References:

[1] Redis setbit command http://redis.io/commands/setbit

分享到:
评论

相关推荐

    C#操作Redis明细内容 C#调用redis c#使用redis业务 C# Redis操作类 C#中Redis封装的类 C#

    谈下你对 Redis 的了解? 1)Redis是一种基于键值对的NoSQL数据库(非关系型数据库);是一个key-value存储系统 2)高性能、可靠性 Redis将数据存储在内存中,读写性能高;Redis提供了 RDB和AOF持久化,可将内存...

    redis 使用说明 redis 使用说明

    Redis 使用说明 Redis 是一个开源的、基于内存的数据存储系统,支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等。Redis 提供了丰富的命令来操作这些数据结构,满足各种应用场景的需求。 Redis 概述和...

    Redis全套学习笔记-带章节目录-114页.pdf

    * Bitmaps:Bitmaps是Redis的一种数据类型,使用setbit命令设置某个偏移量的值,getbit命令获取某个偏移位的值。 * HyperLoglog:HyperLoglog是Redis的一种数据类型,使用pfadd命令添加多个元素,pfcount命令统计...

    使用Go与redis构建有趣的应用

    在线用户统计器可以利用Redis的计数器功能,实时追踪网站或应用中的用户活动情况,为运营决策提供数据支持。自动补完程序可以通过构建高效的搜索索引,提升用户体验,加快信息检索速度。 总之,Go语言和Redis的组合...

    redis 离线集群redis5.0以上版本

    Redis提供了监控和统计信息,可以通过`INFO`命令获取。同时,可以配置日志级别,以便在出现问题时获取更详细的日志信息。 10. **最佳实践**: 在部署和运维Redis集群时,需要遵循一些最佳实践,如合理规划槽的数量...

    利用Redis统计网站在线活跃用户的方法

    标题中的“利用Redis统计网站在线活跃用户的方法”指的是使用Redis这一内存数据存储系统来实时跟踪并统计网站的活跃用户数量。Redis支持多种数据结构,其中一种是基于字符串的位操作,即Bitmaps,这对于统计在线用户...

    redisStudy.zip

    加分项:另外redis还对这几种数据结构做了扩展,如GEO对位置计算,hyperLogLog做统计,bitmaps:redis底层存储value值都是存储的二进制数据,redis提供bitmaps(位图)可以直接访问或修改底层存储的二进制数据 ...

    redis-2.4.16.tar.gz

    Redis作为一个内存数据结构存储系统,支持多种数据结构,如字符串(strings)、哈希表(hashes)、集合(sets)、有序集合(sorted sets)以及位图(bitmaps)。它以纯C语言编写,运行速度快,数据持久化能力强,并...

    Redis全套学习笔记

    Redis 安装简单,可以通过源码编译或使用包管理器安装。启动Redis有前台和后台两种方式,后台启动更常见。Redis 可通过`redis-cli`命令行工具进行交互,提供一系列命令用于操作数据库。 2. Redis 数据类型: - **...

    redis最新3.0版本

    6. **Bits per value (Bitmaps)**: Redis 3.0增强了Bitmaps功能,可以高效地处理位级别的操作,如设置、清除或检查特定位,这对于跟踪用户活动、状态标记等场景非常有用。 7. **地理空间索引`: Redis 3.0添加了`GEO...

    60道关于Redis的常见面试题.pdf

    你平时使用哪些工具来进行 Redis 性能监控? - **监控工具**: - `redis-cli`:官方命令行工具,可用于监控和管理Redis。 - `Redis Insight`:图形化界面工具,方便查看Redis状态。 - **诊断问题**: - 查看`...

    Redis笔记.md

    8. **性能测试**:使用`redis-benchmark`工具进行性能测试,评估Redis在特定环境下的性能表现。 以上步骤覆盖了从安装到配置再到测试的完整流程,为初学者提供了全面的指导。通过这些内容的学习和实践,可以帮助...

    redis2.8稳定版本

    - **Bitmaps扩展**:在2.8版本中,Redis增强了位图操作,支持`BITCOUNT`命令统计指定范围内的1的个数,以及`BITPOS`查找第一个0或1的位置,这在处理用户在线状态、地理位置等场景下非常实用。 - **HyperLogLog...

    大数据之Redis笔记.pdf

    在数据存储方面,Redis的应用场景包括会话存储、消息队列系统、网站访问统计、实时系统指标、地理信息的处理等。 Redis之所以能处理高并发请求而不会导致数据库连接异常,是因为它采用了非阻塞I/O多路复用机制。...

    Redis的基础实战

    可以从简单的缓存操作开始,逐步探索更复杂的使用场景,如使用Redis实现分布式锁、发布订阅系统等。此外,了解Redis的性能优化策略,如调整配置参数、内存管理等也是必要的。 总结来说,“Redis实战”这本书将引导...

    新浪微博开放平台中的Redis实践.pdf

    在微博开放平台中,Redis作为一种内存中的数据结构存储...在微博=feed+关系+数字的模型中,Redis的实践贯穿了信息流(feed)、社交关系(关系)和数字统计(数字)的各个层面,从而保证了平台的快速响应和高效运行。

    redis使用场景及数据结构.docx

    ### Redis使用场景与内部数据结构详解 #### 一、Redis使用场景 Redis 是一款非常流行的开源内存数据库系统,因其高性能和灵活性而被广泛应用于多种场景之中。以下是一些常见的使用场景: 1. **缓存**: - **本地...

    Redis配置详解和企业级项目应用架构

    Redis提供的客户端工具`redis-cli`可以帮助开发者进行命令行交互,进行数据操作和调试。此外,Redis支持通过输入`help <command>`或者`help @<group>`来获取特定命令的帮助信息,极大地便利了开发人员的学习和使用...

Global site tag (gtag.js) - Google Analytics