最近有个问题 :实现显示用户本月登录日期 ,累计天数到一定数目可参加活动,和下图展示的功能类似。
过去看过使用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));
相关推荐
shiro+spring+data+session+redis实现单点登录,这是一个不错的案例,学习和参考都是很不错的
在ASP.NET MVC中使用Redis 的Demo:通过Redis实现用户登陆,并保持登陆状态,设置过期时间,检测在线用户。
在ASP.NET MVC中使用Redis 的Demo:通过Redis实现用户登陆,并保持登陆状态,设置过期时间,检测在线用户 开发工具VS2013,StackExchange.Redis
使用redis实现集群登录,将session存入redis,一个方法类,直接配置即可使用
redis实现简单排行榜,和消息处理。
Qt 使用 Redis实现 消息队列,点对点 生产者-消费者 模式
tomcat-redis实现session共享
SpringBoot+MyBatis+SpringSession+Redis实现session共享及单点登录开发实例
Spring Boot 使用 AOP 和 Redis 实现接口限流是一种高效且实用的方法,用于控制对特定接口的访问频率。以下是实现这个功能的基本步骤: 引入依赖:首先,在 Spring Boot 项目中引入 Redis 和 AOP 的相关依赖。这...
shiro+redis 实现登录控制及密码重试次数超过5次后账号锁定一分钟不能登录
redis实现登录退出代码(包括工具类)
springboot 整合springsession的使用,并且整合redis实现登录拦截功能,保证分布式状态下session能够一致性。
今天用了一天来搞定了ssm+redis集成和nginx实现负载均衡,这里只有ssm+redis简单d集成demo,希望大家一起来讨论
主要介绍了Java基于redis实现分布式锁代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
redis页面缓存html使用redis实现页面缓存.docx
Springboot前后端分离,JWT+Security+Redis实现登录拦截及权限认证,包含全局异常处理以及统一返回风格
Redis开发基于redis实现高并发异步秒杀点评项目.zipRedis开发基于redis实现高并发异步秒杀点评项目.zipRedis开发基于redis实现高并发异步秒杀点评项目.zipRedis开发基于redis实现高并发异步秒杀点评项目.zipRedis...
基于mq和redis实现的秒杀系统基于mq和redis实现的秒杀系统
php(TP5)+redis实现秒杀抢购(不限制用户购买次数和限制用户购买次数)
本篇文章主要介绍了基于 Redis 实现分布式应用限流的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧