V2EX 首页   注册   登录
 huangz 最近的时间轴更新
huangz's repos on GitHub
C · 3149 人关注
redis-3.0-annotated
带有详细注释的 Redis 3.0 代码(annotated Redis 3.0 source code)。
C · 1823 人关注
annotated_redis_source
带有详细注释的 Redis 2.6 源码
HTML · 1142 人关注
redis
《Redis Command Reference》全文的中文翻译版。
TeX · 987 人关注
redisbook
《Redis 设计与实现》(网络版)的书稿源码
Haskell · 925 人关注
real-world-haskell-cn
《Real World Haskell》中文翻译项目
C · 132 人关注
blog
我的个人博客。
HTML · 103 人关注
clojure_api_cn
Clojure API 文档的中文翻译版
C · 92 人关注
reading_redis_source
Redis 源码阅读
HTML · 89 人关注
cngolib.com
Go 标准库中文文档
Python · 56 人关注
ooredis
基于 redis-py 之上的一个 Mapper ,让你以更 pythonic 的方式来操作 Redis 。
C · 41 人关注
note
我的个人笔记。
HTML · 40 人关注
pgsqlcn
《PostgreSQL手册》中文翻译项目
Python · 33 人关注
redisbook1e-gallery
《Redis 设计与实现》图片集 & 图片源码
HTML · 31 人关注
DisqueBook
《Disque 使用教程》
CSS · 17 人关注
der
《Redis 设计与实现》所使用的 sphinx 样式。
Python · 14 人关注
A-Gentle-Introduction-To-Haskell-Chinese-Edition
Haskell官方教程的中文翻译版。
Python · 13 人关注
postgresql-doc-cn
PostgreSQL 数据库中文手册
Python · 8 人关注
redis_cookbook
自己撰写的一些关于Redis用例的文章,目前停滞中。。。
Ruby · 6 人关注
redis_lock_algorithm
使用 redis 构造锁
Go · 5 人关注
2017-guangzhou-gopher-meetup
这是我在 2017 年 9 月 9 日广州 Gopher meetup 演讲时的演讲稿以及代码,演讲视频请见:http://www.itdks.com/dakashuo/new/eventlist/detail/1262 ,其他演讲者的演讲稿请见:https://github.com/gopherchina/meetup/tree/master/Guangzhou/20170909
Python · 5 人关注
real_world_haskell_note
《Real World Haskell》的读书笔记。
4 人关注
redis-cheatsheet
《Redis 命令速查表》
3 人关注
gwpcn-translation-manuscript
《Go Web 编程》的翻译手稿集。
C · 2 人关注
experiment-redis
Redis fork for experiment propose / 实验用 Redis 。
JavaScript · 2 人关注
homepage
个人主页
Clojure · 1 人关注
autistic
Autistic 是一个用 Neo4j 实现基本社交关系的库。
Python · 1 人关注
gist
主要用来存放一些临时使用的小脚本。
Python · 1 人关注
ooredis_doc
OORedis 项目的文档
JavaScript · 1 人关注
RedisGuide-website
《Redis使用教程》一书的读者服务网站。
HTML · 0 人关注
gwpcn.com
《Go web 编程》读者服务网站。

huangz

  •   V2EX 第 3333 号会员,加入于 2010-11-30 12:51:15 +08:00
    huangz 最近回复了
    2016-08-13 13:19:19 +08:00
    回复了 Livid 创建的主题 Redis 关于用 Redis 做在线人数统计
    Livid 的这个思路很有趣!

    最近我也在研究这方面的问题,提供一些备选方案让大家参考。


    方案 1 :使用有序集合
    --------------------------------------

    每当用户上线时,执行以下操作:

    ZADD("online_users", <user_id>, <current_timestamp>)

    想要知道有多少人在指定的时间区间(比如一天或者一周)内上线过,那么可以使用时间区间的起始时间戳和结束时间戳作为参数,调用 ZCOUNT 命令:

    ZCOUNT("oneline_users", <start_timestamp>, <end_timestamp>)

    判断用户的 session 是否过期可以通过以下方法:

    user_online_timestamp = ZSCORE("online_users", <user_id>)
    return (user_online_timestamp+SESSION_EXPIRETIME) < now()

    其中 SESSION_EXPIRETIME 为 SESSION 的有效期秒数。

    这个方案的优点是信息齐全,能够通过有序集合的特性方便地执行区间操作( O(logN)),也可以快速地获取指定用户的登录时间( O(1))。缺点是耗费的内存比较大,并且需要手动删除有序集合中已经过期的用户信息。


    方案 2 :使用 HyperLogLog
    --------------------------------------

    用户上线:

    PFADD("online_users", <user_id>)

    获取在线人数:

    PFCOUNT("online_users")

    这个方案的优点是非常节约内存,无论网站的用户数量有多大,一个 HyperLogLog 都只消耗 12 KB 内存。当然,这个方案的缺点也非常明显:

    1. 它无法获取用户的具体登录时间。
    2. 因为 HyperLogLog 是一个概率算法,所以它无法准确地判断一个用户是否在线。

    以上缺点都可以通过增加一个储存用户登录时间的 Hash 来解决,不过这一样一来,需要消耗的内存也会增加。


    方案 3 :使用 bitmap
    ---------------------------------------

    上线:

    SETBIT("online_users", <user_id>, 1)

    检查指定的用户是否上线:

    GETBIT("online_users" <user_id>) == 1

    统计在线人数:

    BITCOUNT("online_users")

    这个方案最有趣的地方,就是可以对多个 bitmap 执行聚合计算,从而计算出诸如“有多少个人连续一周都上线了(全勤)”、“这周一共上线了多少个人”、“有多少人今天上线了但是昨天没上线”等问题:

    BITOP("AND", "one_week_both_online", "day_1_online", "day_2_online", ..., "day_7_online") # 计算一周都上线的人

    BITOP("OR", "one_week_online_total", "day_1_online", ..., "day_7_online") # 计算这周一共有多少人上线

    这个方案储存一个用户的在线信息只需要使用一个二进制位,对于用户数为 100 万的网站来说,使用这一方案只需要花费 125 KB 内存,而储存 1000 万的用户信息只需要花费 1.25 MB 。

    虽然 bitmap 节约内存的效果不及 HyperLogLog ,但是使用 bitmap 可以准确地判断一个用户是否上线。对于想要尽量节约内存,但又需要准确地知道用户是否在线,又或者需要对用户的在线信息进行聚合计算的应用来说,这个方案是最佳之选。


    结语
    ---------------------------------------

    好的,关于统计在线用户的备选方案就介绍到这里,希望这些方案会给大家带来帮助和启发。

    最后打个小广告,我正在写一本名为《 Redis 使用教程》的书,里面不仅对用户 SESSION 储存、用户在线统计等问题给出了详细的解法,还提供了实际可运行的 Python 代码,上面给出的一些方案在书中也有介绍,有兴趣的朋友可以关注一下: RedisGuide.com 非常感谢!

    huangz
    2016.8.13
    2016-08-08 15:03:16 +08:00
    回复了 huangz 创建的主题 Redis 赠送几本即将出版的《Redis 实战》
    @markme 谢谢支持。
    2015-11-03 14:41:51 +08:00
    回复了 huangz 创建的主题 Redis 赠送几本即将出版的《Redis 实战》
    @boboweb 谢谢支持!等电子版出了之后会第一时间发布消息的。
    2015-11-03 11:16:12 +08:00
    回复了 huangz 创建的主题 Redis 赠送几本即将出版的《Redis 实战》
    @ynztyl10 不客气,收到就好!
    2015-11-03 11:15:35 +08:00
    回复了 lijinma 创建的主题 Redis 感谢 huangz 送的《Redis 实战》
    不客气,收到就好!
    2015-10-20 19:57:44 +08:00
    回复了 huangz 创建的主题 Redis 赠送几本即将出版的《Redis 实战》
    @ynztyl10 没关系,已经给你回邮件了。
    2015-10-20 13:46:40 +08:00
    回复了 huangz 创建的主题 Redis 赠送几本即将出版的《Redis 实战》
    @ynztyl10 hi ,在吗?你中奖了,请给我发邮件。
    2015-10-19 17:01:24 +08:00
    回复了 huangz 创建的主题 Redis 赠送几本即将出版的《Redis 实战》
    @lijinma OK 。
    2015-10-19 12:40:33 +08:00
    回复了 huangz 创建的主题 Redis 赠送几本即将出版的《Redis 实战》
    @lijinma 你好,我收到了你一封邮件,并且已经回复了,是你本人吗?
    2015-10-19 12:36:04 +08:00
    回复了 huangz 创建的主题 Redis 赠送几本即将出版的《Redis 实战》
    @rangercyh 已回复你的邮件,谢谢!
    DigitalOcean
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   511 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.0 · 43ms · UTC 23:24 · PVG 07:24 · LAX 15:24 · JFK 18:24
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1