`
OrangeHolic
  • 浏览: 260739 次
  • 来自: 北京
社区版块
存档分类
最新评论

用redis实现用户登录计数

阅读更多

最近有个问题 :实现显示用户本月登录日期 ,累计天数到一定数目可参加活动,和下图展示的功能类似。



 
过去看过使用redis bitmap进行活跃用户统计的例子,觉得和本功能非常match,决定用redis的bitset来实现。
 
每个用户每月产生一个key,字段意义如下 0 位表示某月1日登录  ,1表示某月2日登录,以此类推。
 
每个用户一月的活跃度需要8byte,1W用户每年需要1W*12*8byte 约1M数据


 
 
用户每次登录系统,需要用setBit设置用户本日登录,可用bitcount的到用户本月登录天数总和,因为PHP原生不对bitset进行支持,采用get得到字符串进行操作得到用户登录日期
测试代码如下:
 
<?php

/**
 *
 * User: shikiliu
 * Date: 14-8-27
 */

class ActiveDate
{


    private $redisConf = array('host' => 'localhost', 'port' => 6379);

    private $redis = null;

    private $userPrefix = 'user_active_';


    /**
     * 设置用户某天登录过
     */
    public function setActiveDate($userId, $time = null)
    {

        if (empty($time)) {

            $time = time();
        }

        $redis = $this->getRedis();

        $redis->setBit($this->userPrefix . $userId . '_' . date('Y-m', $time), intval(date('d', $time)) - 1, 1);

        return true;
    }


    /**
     * 得到用户本月登录天数
     * redis >= 2.6.0 才可以
     */
    public function getActiveDatesCount($userId, $time = null){

        if (empty($time)) {

            $time = time();
        }

        $redis = $this->getRedis();

        return $redis->bitcount($this->userPrefix . $userId . '_' . date('Y-m', $time));

    }


    /**
     * 得到用户某月所有的登录过日期
     */
    public function getActiveDates($userId, $time = null)
    {


        $result = array();

        if (empty($time)) {

            $time = time();
        }

        $redis = $this->getRedis();

        $strData = $redis->get($this->userPrefix . $userId . '_' . date('Y-m', $time));

        if (empty($strData)) {
            return $result;
        }

        $monthFirstDay = mktime(0, 0, 0, date("m", $time), 1, date("Y", $time));

        $maxDay = cal_days_in_month(CAL_GREGORIAN, date("m", $time), date("Y", $time));

        $charData = unpack("C*", $strData);

        for ($index = 1; $index <= count($charData); $index++) {

            for ($bit = 0; $bit < 8; $bit++) {

                if ($charData[$index] & 1 << $bit) {

                    //$intervalDay = ($index - 1) * 8 + 8-$bit;
                    $intervalDay = $index  * 8 -$bit;
                    //如果数据有大于当月最大天数的时候
                    if ($intervalDay > $maxDay) {

                        return $result;

                    }

                    $result [] = date('Y-m-d', $monthFirstDay + ($intervalDay-1) * 86400);

                }

            }

        }

        return $result;


    }


    /**
     *  redis连接
     */
    private function getRedis()
    {

        if (empty($this->redis)) {


            $redis = new Redis();

            if (!$redis->connect($this->redisConf['host'], $this->redisConf['port'])) {

                throw new Exception("Error Redis Connect", 100);

            }

            $redis->select(3);

            $this->redis = $redis;


        }

        return $this->redis;

    }


}


$activeDate = new ActiveDate();

var_dump($activeDate->setActiveDate(514540767,1406822600));//  2014/8/1 0:3:20
var_dump($activeDate->setActiveDate(514540767,1407225600));//  2014/8/5 16:0:0
var_dump($activeDate->setActiveDate(514540767,1409472000));//  2014/8/31 16:0:0

var_dump($activeDate->getActiveDates(514540767));

var_dump($activeDate->getActiveDatesCount(514540767));
	
 
 

 

  • 大小: 12.7 KB
  • 大小: 349.3 KB
分享到:
评论
1 楼 vae0921 2015-04-22  
很详细,刚好在考虑统计每个月登录超过多少天的用户
只不过我们是要到具体的用户,还要按一定的范围进行汇总,不是单纯的一个统计数字,容量即可,还是感觉有些局限。

我们的签到功能没有你们的详细,没有流水,如果考虑流水就可以借鉴你的思路了,赞一个。

相关推荐

    使用redis管理用户登录会话的方法

    本文将深入探讨如何利用Redis实现用户登录会话管理。 首先,我们需要了解两种常见的登录信息存储方式:签名(signed)cookie和令牌(token)cookie。签名cookie存储用户的用户名、ID等信息,并附加一个由服务器生成...

    基于Redis实现每日登录失败次数限制

    【基于Redis实现每日登录失败次数限制】的知识点详解 Redis是一种高效的内存数据结构存储系统,常用于缓存、消息队列、计数器等多种场景。在这个问题中,我们利用Redis来实现每日登录失败次数限制的功能,以防止...

    Redis实现高并发计数器

    本文将详细探讨如何利用Redis这一高效、轻量级的内存数据存储系统来实现高并发计数器。 Redis是一个开源的、基于键值对的数据结构服务器,它支持多种数据类型,如字符串、哈希、列表、集合和有序集合等。其中,...

    基于Redis对用户数量进行统计的Counter系统

    标题中的“基于Redis对用户数量进行统计的Counter系统”指的是使用Redis这个内存数据结构存储服务来构建一个计数器系统,专门用于统计用户数量。在高并发和实时性要求较高的场景下,传统的数据库可能无法满足需求,...

    C#操作redis,增删改查

    Redis是一个基于内存的key-value结构数据库; Redis特点: 基于内存处理,读写性能高;...同时,Redis的incr/decr等操作可以方便地实现计数功能。 处理任务队列:Redis的List数据结构可以用于实现队列(Queue)

    sprinvmvc+maven+redis

    综上所述,这个项目展示了如何利用SpringMVC、Maven和Redis这些技术来实现一个具有特定安全策略的用户登录系统,其中Redis作为缓存系统,有效地处理了登录错误计数,提高了系统的响应速度和效率。

    Redis实现唯一计数的3种方法分享

    相比之下,Redis 提供了三种高效的方法来实现唯一计数。 1. **基于 SET 的方法**: 使用 Redis 的 SET 数据结构,可以存储唯一的成员,同时支持添加、删除和检查成员是否存在。通过 `SISMEMBER` 判断元素是否存在...

    redis高可用笔记,包括RedisCluster集群方式和完全纯手写Redis缓存框架

    Redis,全称Remote Dictionary Server,是一种高性能的键值数据库,广泛应用于缓存、消息中间件、计数等多个场景。为了确保服务的稳定性和可靠性,Redis提供了多种高可用解决方案,其中最常见的是Redis Cluster集群...

    javaweb问答系统使用redis+jsp+mysql

    例如,当用户登录后,其会话信息可以存储在`Redis`中,减少每次请求都查询数据库的操作。同时,`Redis`还可以用作点赞计数的存储,快速增加或减少点赞数,并实时更新到前端展示。 权限访问是系统的重要组成部分,这...

    使用Redis的MVC示例

    5. **计数器**:如统计文章阅读次数,通过Redis的原子操作实现计数。 **四、集成Redis到MVC项目** 集成Redis到MVC项目通常涉及以下步骤: 1. **安装Redis**:首先在服务器上安装并配置Redis,确保服务运行正常。 ...

    Redis介绍与内部实现机制

    此外,Redis社区提供了大量的插件和工具,如RedisInsight可视化工具、RediSearch全文搜索引擎、RedisGears脚本执行框架等,这些都能帮助用户更好地管理和利用Redis。 总结来说,Redis是一个强大且灵活的内存数据...

    基于SpringBoot+Redis实现的仿QQ伪桌面聊天系统.zip

    《基于SpringBoot+Redis实现的仿QQ伪桌面聊天系统》 在现代互联网应用开发中,构建实时、高效的聊天系统已经成为了一项重要的需求。本项目旨在通过集成SpringBoot框架和Redis缓存技术,实现一个仿QQ的伪桌面聊天...

    php+redis+thinkphp实现的计数器

    本项目"php+redis+thinkphp实现的计数器"正是针对这一需求,通过集成PHP、Redis和ThinkPHP框架,构建了一个基于MVC模式的网页计数统计模块。下面我们将详细探讨这个系统的各个组成部分及其工作原理。 首先,PHP作为...

    使用redis构建简单的社交网站用户认证、发布消息、关注/取消关注其他用户

    使用Redis的集合(Set)数据结构可以轻松地实现用户之间的关注关系管理。对于每个用户,可以创建一个集合来存储他们关注的其他用户的ID。 - **关注**: 当一个用户关注另一个用户时,后者ID将被添加到前者的关注集合中...

    redis实战高清版

    2. 计数器:通过原子操作,Redis可以轻松实现计数功能,例如访问统计。 3. 排序:有序集合支持基于分数的排序,可用于生成排行榜等场景。 4. 分布式锁:Redis的单线程模型和过期时间功能使得它能实现简单的分布式锁...

    狂神说Redis笔记.pdf

    3. 分布式锁:利用Redis实现分布式环境下的锁服务,保证操作的互斥性。 4. 计数器:如热点商品访问计数、用户行为统计等。 【总结】 Redis因其高性能、丰富的数据结构和灵活的应用场景,在现代互联网应用中扮演着...

    Springboot使用redis进行api防刷限流过程详解

    使用 Redis 存储与计数 Redis 是一个高性能的键值存储系统,适合用来做限流计数。在这个场景中,我们可以将每个请求的唯一标识(例如:路径+IP)作为 Redis 的 key,访问次数作为 value。每次请求到来时,先检查 ...

    redis-windows-6.2.5.zip

    - **限流和计数**:Redis提供了一些内置的命令如`INCR`、`DECR`、`INCRBYFLOAT`等,可以方便地实现计数和流量控制。 在实际应用中,Redis通常用于: - **缓存**:由于其高读写速度,Redis常被用作Web应用的缓存,...

Global site tag (gtag.js) - Google Analytics