• 用redis统计大量用户的登陆情况[只判断是否活跃]


    有这样的一个场景需求:有上亿的用户,要统计这批用户的登陆情况,例如一周连续登陆,连续三天是是否登陆,一周活跃天数等用户

    存在的挑战

    1. 数据如何尽可能用小的空间存储
    2. 如何能快速获取指定的数据

    如果使用文件保存

       会有如下问题:

    1. 文件分割变得十分麻烦

    2. 数据检索非常不方便

    3. 用户关联操作复杂

    如果使用数据库表

       会有如下问题:

    1. 占用空间增长速度快,表急剧增大
    2. 使用索引,易产生碎片,每次插入数据还要维护索引,影响性能
    3. 要用group ,sum等运算,计算较慢

    使用redis位图进行存储(setbit/getbit)

       优点:

    1. 由于我的业务中只需要根据某个用户id查询是否是活跃用户,不存在复杂的查询条件,所以用redis很合适。
    2. redis中所有数据都是二进制形式存储的。redis支持一个setbit和getbit操作,它支持在某个key的value上直接对某个二进制位操作,每个二进制位都只有0和1两种状态,正好可以表示用户是否活跃两种状态。
    3. 存取速度非常快

    思路

    1. 记录用户登陆:每天按日期生成一个位图, 用户登陆后,把user_id位上的bit值置为1
    2. 把1周的位图用 and 计算, 是否连续登陆用and计算,得到1即为连续登陆的用户,简单来说,能快速的拿到用户是否登陆的0/1状态,就能快速的计算出某段日期内登陆了几天
    3. 如果每次执行redis比较繁琐,可以简单的生成追加文件的方式,追加redis命令,例setbit到文件中,隔一段时间统一利用pipe mode通过管道的方式直接快速存入redis

    命令

    redis 127.0.0.1:6379> setbit mon 3 1

    (integer) 0

    redis 127.0.0.1:6379> setbit mon 5 1

    (integer) 0

    redis 127.0.0.1:6379> setbit mon 7 1

    (integer) 0

    redis 127.0.0.1:6379> setbit thur 100000000 0

    (integer) 0

    redis 127.0.0.1:6379> setbit thur 3 1

    (integer) 0

    redis 127.0.0.1:6379> setbit thur 5 1

    (integer) 0

    redis 127.0.0.1:6379> setbit thur 8 1

    (integer) 0

    127.0.0.1:6379> getbit thur 8
    (integer) 1

    高效插入举例

    1. 新建一个文本文件,包含redis命令

    *4    # 表示下面的命令有四个参数
    $6   #第一个参数的长度
    setbit   # 参数值
    $3       #第二个参数的长度
    mon    # 参数值
    $1  #第三个参数的长度
    3    # 参数值
    $1  #第四个参数的长度
    1   # 参数值

        存于data.txt

       2. 利用管道插入

       cat data.txt | redis-cli --pipe

    可参考学习:http://blog.csdn.net/lglgsy456/article/details/39394961

  • 相关阅读:
    Python异常处理
    Python 线程、进程和协程
    python版本升级及pip部署方法
    Python socket编程
    循环遍历方法笔记
    TCP/IP协议分为哪四层,具体作用是什么。
    Python Paramiko模块与MySQL数据库操作
    Python面向对象编程(二)
    h5专题常用小代码
    sethc问题
  • 原文地址:https://www.cnblogs.com/zhenghongxin/p/8612399.html
Copyright © 2020-2023  润新知