当前位置: 首页 > news >正文

贵阳建设银行网站久久文化传媒有限公司招聘信息

贵阳建设银行网站,久久文化传媒有限公司招聘信息,丽水建设公司网站,分析一个网页设计开发的过程中#xff0c;可能会遇到用户签到、统计当天的活跃用户、以及每个用户的在线状态#xff0c;用户留存率的开发需求#xff0c;可能会用传统的方法#xff0c;根据相应的需求设计数据库表等#xff0c;但这样耗费的存储空间大#xff0c;以及性能方面也不会太好…开发的过程中可能会遇到用户签到、统计当天的活跃用户、以及每个用户的在线状态用户留存率的开发需求可能会用传统的方法根据相应的需求设计数据库表等但这样耗费的存储空间大以及性能方面也不会太好下面为大家介绍一些使用的方法redis官方文档http://www.redis.cn/documentation.html一.用redis的set集合统计日活用户数用户登录以后把用户id添加到redis的set中set会自动进行去重127.0.0.1:6379 sadd users_2023_02_21 user1 (integer) 1 127.0.0.1:6379 sadd users_2023_02_21 user2 (integer) 1 127.0.0.1:6379 sadd users_2023_02_21 user3 (integer) 1统计只需一条命令127.0.0.1:6379 scard users_2023_02_21 (integer) 3可以看出来2023_02_21的用户数是3个,很简单但是集合只适用于用户数比较少的场合假如用户有100万set存储100万个id号如果一个id号占32个字节总共就是差不多32M一个月就是960M 差不多一个G了,用户量大的项目不适用二.用redis中bitmap统计用户签到活跃用户用户在线状态用户留存率等思路 1.设置一个key专门用来记录用户日活的可以使用时间来翻滚 2.使用每个用户的唯一标识映射一个偏移量比如使用id这里可以把id换算成一个数字或直接使用id的二进制值作为该用户在当天是否活跃偏移量 3.用户登录则把该用户偏移量上的位值设置为1 4.每天按日期生成一个位图bitmap 5.计算日活则使用bitcount即可获得一个key的位值为1的量 6.计算月活一个月内登陆的用户去重总数即可把30天的所有bitmap做or计算然后再计算bitcount 7.计算留存率次日留存昨天今天连续登录的人数/昨天登录的人数 即昨天的bitmap与今天的bitmap做and计算就是连续登录的再做bitcount就得到连续登录人数再bitcount得到昨天登录人数就可以通过公式计算出次日留存1.bitmap介绍 (1).BitMap是什么就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身我们知道8个bit可以组成一个Byte所以bitmap本身会极大的节省储存空间但其位计算和位表示数值相对于局限故如要用位来做业务数据记录那么就不要在意value的值了(2).Redis中的BitMapRedis从2.2.0版本开始新增了setbit,getbit,bitcount等几个bitmap相关命令虽然是新命令但是并没有新增新的数据类型因为setbit等命令只不过是在set上的扩展(3).几个前提数据在redis中都是二进制存储setbit和getbit和bitcount是string数据类型的命令8bit表示一个ascll字符因为是c写的redisoffset偏移量是从0开始(4)空间占用、以及第一次分配空间需要的时间在一台2010MacBook Pro上offset为2^32-1分配512MB需要大约300msoffset为2^30-1(分配128MB)需要大约80msoffset为2^28-1分配32MB需要大约30msoffset为2^26-1分配8MB大约需要8ms来自官方文档大概的空间占用计算公式是($offset/8/1024/1024)MB(5)getbit命令指令 GETBIT key offset返回值字符串值指定偏移量上的位(bit)。当偏移量 OFFSET 比字符串值的长度大或者 key 不存在时返回 0 。对 key 所储存的字符串值获取指定偏移量上的位(bit)注offset表示偏移量127.0.0.1:6379 set A a OK 127.0.0.1:6379 get A a 127.0.0.1:6379 getbit A 0 (integer) 0 127.0.0.1:6379 getbit A 1 (integer) 1 127.0.0.1:6379 getbit A 2 (integer) 1 127.0.0.1:6379 getbit A 3 (integer) 0 127.0.0.1:6379 getbit A 4 (integer) 0 127.0.0.1:6379 getbit A 5 (integer) 0 127.0.0.1:6379 getbit A 6 (integer) 0(5)setbit命令指令 SETBIT key offset value返回值指定偏移量原来储存的位设置或者清除key的value(字符串)在offset处的bit值(只能只0或者1)将上述A的值“a”的第6位修改为1也就是相当于ASCLL码加2从而值从a变成了c127.0.0.1:6379 setbit A 6 1 (integer) 0 127.0.0.1:6379 get A c 127.0.0.1:6379 (6).Bitcount 命令指令BITCOUNT key [start] [end]返回值1比特位的数量计算给定key的字符串值中被设置为 1 的比特位的数量不存在的 key 被当成是空字符串来处理因此对一个不存在的 key 进行 BITCOUNT 操作结果为 0 值c的二进制数应该是01100011故bitcount计算出来应该是4127.0.0.1:6379 get A c 127.0.0.1:6379 bitcount A (integer) 4(7).bitop 命令指令 operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种 BITOP AND destkey key [key ...] 对一个或多个 key 求逻辑并并将结果保存到 destkey BITOP OR destkey key [key ...] 对一个或多个 key 求逻辑或并将结果保存到 - destkey BITOP XOR destkey key [key ...] 对一个或多个 key 求逻辑异或并将结果保存到 destkey BITOP NOT destkey key 对给定 key 求逻辑非并将结果保存到 destkey除了 NOT 操作之外其他操作都可以接受一个或多个 key 作为输入对一个或多个保存二进制位的字符串 key 进行位元操作并将结果保存到 destkey 上BITOP 的复杂度为 O(N) 当处理大型矩阵(matrix)或者进行大数据量的统计时最好将任务指派到附属节点(slave)进行避免阻塞主节点2.使用场景一用户签到需要展示最近一个月的签到情况使用bitmap?php $redis new Redis(); $redis-connect(127.0.0.1); //用户uid $uid 1; //记录有uid的key $cacheKey sprintf(sign_%d, $uid); //开始有签到功能的日期 $startDate 2023-02-21; //今天的日期 $todayDate 2023-02-21; //计算offset $startTime strtotime($startDate); $todayTime strtotime($todayDate); $offset floor(($todayTime - $startTime) / 86400); echo 今天是第{$offset}天 . PHP_EOL; //签到 //一年一个用户会占用多少空间呢大约365/845.625个字节好小 $redis-setBit($cacheKey, $offset, 1); //查询签到情况 $bitStatus $redis-getBit($cacheKey, $offset); echo 1 $bitStatus ? 今天已经签到啦 : 还没有签到呢; echo PHP_EOL; //计算总签到次数 echo $redis-bitCount($cacheKey) . PHP_EOL;3.使用场景二统计活跃用户使用时间作为cacheKey然后用户ID为offset如果当日活跃过就设置为1那么该如果计算某几天/月/年的活跃用户呢(暂且约定统计时间内只有有一天在线就称为活跃)命令 BITOP operation destkey key [key ...]说明对一个或多个保存二进制位的字符串 key 进行位元操作并将结果保存到 destkey 上说明BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种参数$redis Yii::$app-redis_sms; //日期对应的活跃用户 $data array( 2023-02-21 array(10000030, 10600031, 10050031, 10040031, 10200031, 10020031, 10001001, 10000011, 10000021, 10000131), 2023-02-20 array(10000030, 10600031, 10050031, 10040031, 10200031, 10020031, 10110001, 10000011), 2023-02-19 array(10000030, 10600031, 10050031, 10040031, 10200031), 2023-02-18 array(10000030, 10600031), 2023-02-17 array(10000030, 10600031, 10050031,) );//批量设置活跃状态 foreach ($data as $date $uids) {$y date(Y, strtotime($date));$m date(m, strtotime($date));$d date(d, strtotime($date));$cacheKey sprintf(active_user:%s:%s:%s, $y, $m, $d);foreach ($uids as $uid) {$redis-setbit($cacheKey, $uid - 10000000, 1); // 偏移量用户初始id较大时使用减少redis计算} }$redis-bitop(AND, active_user:stat, active_user:2023:02:21, active_user:2023:02:200) . PHP_EOL; //总活跃用户6 echo 总活跃用户 . $redis-bitcount(active_user:stat) . PHP_EOL; $redis-bitop(AND, active_user:stat1, active_user:2023:02:19, active_user:2023:02:18, active_user:2023:02:12) . PHP_EOL; //总活跃用户2 echo 总活跃用户 . $redis-bitcount(active_user:stat1) . PHP_EOL; $redis-bitop(AND, active_user:stat2, active_user:2023:02:18, active_user:2023:02:12) . PHP_EOL; //总活跃用户8 echo 总活跃用户 . $redis-bitcount(active_user:stat2) . PHP_EOL;// 获取活跃状态的用户id $result $this-get_bitmap_all(active_user:2023:02:19);public function get_bitmap_all($key){$redis Yii::$app-redis;$result [];$value $redis-get($key);if ($value) {/*** 解包(redis返回来的是二进制字符串我们需要把它解成对应的数字)* 关于unpack的用法如果不了解大家可以网上搜索学习改天可以单独写篇文章分享*/$bitmap unpack(C*, $value);if ($bitmap) {foreach ($bitmap as $key $number) {// 下标是从1开始的; 1个字节8位$offset ($key - 1) * 8;// 过滤没有标记的字节段if ($number) {for ($i 0; $i 8; $i) {// 遍历这个字节的每一位是否有为1的值如果有那就记录这个位置的偏移量就是用户idif (($number $i 1) 1) {// 8位范围是0~7,因为redis是高位到低位存储所以要反过来计算偏移量$result[] $offset (7 - $i);}}}}}}return $result;} /*** 新增上一天的日活跃用户数以及更新上一天所在的月份的月活跃用户数*/public function actionActiveUser(){$day 1;$date_key date(Y:m:d, strtotime(-{$day} day));$date date(Y-m-d, strtotime(-{$day} day));$redisUser Yii::$app-redis_user;$platforms array_keys(Common::fromPlatformText());//获取平台//保存对应日期平台活跃的用户到数据库foreach ($platforms as $platform) { //循环平台$key sprintf(active_user:%s:%s, $date_key, $platform);//1.查询redis活跃用户id//2.查询到的用户id组成一个数组(该数组可能会很大)$userIds $this-get_bitmap_all($key);if ($userIds) {//3.循环查询使用yield生成器用户注册表t_reg获取代理渠道相关信息$i_userIds $this-activeUser($userIds);foreach ($i_userIds as $userId) {$key sprintf(active_user:%s:%s, $date_key, $platform);//从用户注册表reg中获取对应用户渠道相关数据$reg Reg::getGameUserData([id $userId], [agency_from, time]);if (!$reg) {continue;}$agencyFromPId $reg[id]; //渠道id,默认为00 无渠道//4.重组key, 增加渠道id,把数据保存到redis服务器中$key . : . $agencyFromPId;$redisUser-setbit($key, $userId, 1);$redisUser-expire($key, 15552000);//半年过期时间}}}//5.添加数据到活跃用户数据表进行统计//获取代理渠道类型以及对应的代理渠道商$agency_from Common::agencyFrom();//保存当前日期平台对应的所有渠道对应的活跃用户到数据库foreach ($platforms as $platform) { //循环平台foreach ($agency_from as $id) { //循环渠道相关信息//构建活跃用户key$key sprintf(active_user:%s:%s:%s, $date_key, $platform, $id);if ($redisUser-exists($key)) { // 判断key是否存在$num $redisUser-bitcount($key);//获取当前日期对应平台对应的渠道的活跃用户//5.添加用户活跃数据ActiveUser::addInfo([date $date, platform $platform, num $num, agency_from_id $id]);}}}//保存当前日期所在月份平台对应的所有渠道的活跃用户到数据库//生成月份数据$month date(Y-m, strtotime($date));$timestamp strtotime($month);$month_format date(Y:m, $timestamp); // 月份时间格式$m_days date(t, $timestamp); //当前月份的天数$date_start strtotime(date(Y-m-01, $timestamp)); //当前月份开始日期戳$date_end strtotime(date(Y-m- . $m_days, $timestamp));//当前月份结束日期戳for ($i $date_end; $i $date_start; $i - 86400) { // 循环当前月份所在日期$dateKey date(Y:m:d, $i);foreach ($platforms as $platform) { //循环平台,添加并更新当前月份活跃用户数据总数到redis服务器中foreach ($agency_from as $id) { //循环渠道相关信息$monthKey active_user_month_num: . $month_format . : . $platform . : . $id; // 月份活跃用户数量key$key sprintf(active_user:%s:%s:%s, $dateKey, $platform, $id     ); //获取活跃用户keyif ($redisUser-exists($key)) {//添加并更新当前月份活跃用户数据总数到后台redis服务器中$redisUser-bitop(or, $monthKey, $monthKey, $key); //bitop活跃用户$redisUser-expire($monthKey, 15552000);//半年过期时间 }}}}//保存当前月份平台对应的所有代理渠道商对应的活跃用户到数据库foreach ($platforms as $platform) { //循环渠道,bitOp活跃用户foreach ($agency_platform as $id) {$monthKey active_user_month_num: . $month_format . : . $platform . : . $id; // 月份活跃用户数量keyif ($redisUser-exists($monthKey)) {$num $redisUser-bitcount($monthKey); //bitop活跃用户//保存前日期所在月份的渠道活跃的用户到数据库ActiveUser::addOrUpdate([date $month, platform $platform, num $num, agency_from_id $id]);}}}}/*** yield生成器* param $userIds* return \Generator*/public function activeUser($userIds) {//使用yield生成器foreach ($userIds as $userId) {yield $userId;}}4.使用场景三实现用户上线次数统计需求 假设希望记录开发网站上的用户上线的频率比如计算用户 A 上线了多少天用户 B 上线了多少天从而决定让哪些用户参加 某个活动这个功能可以使用 SETBIT 和 BITCOUNT 来实现。 每当用户在某一天上线的时候我们就使用 SETBIT 以用户id作为 key 将那天所代表的网站的上线日作为 offset 参数并将这个 offset 上的为设置为 1 案例 如果今天是网站上线的第365天而用户10001在今天浏览过网站那么执行命令 SETBIT 10001 365 1 如果明天用户10001 也继续浏览网站那么执行命令 SETBIT 10001 366 1 以此类推。当要计算用户10001 总共以来的上线次数时就使用 BITCOUNT 命令执行 BITCOUNT 10001 得出的结果就是 用户10001上线的总天数5.使用场景四用户在线状态思路 查询当前用户是否在线使用bitmap是一个节约空间效率又高的一种方法设置一个key用户ID为offset如果在线就设置为1不在线就设置为0 $redis Yii::$app-redis;//时段对应的在线用户$data array(2023-02-14 05:00:00 array(10000030, 10600031),2023-02-15 05:00:00 array(10000030, 10600031),2023-02-15 13:00:00 array(10000030, 10600031, 10050031, 10050031, 10040031, 10200031, 10020031, 10110001),2023-02-19 12:00:00 array(10000030, 10600031, 10050031, 10040031, 10200031, 10020031, 10001001, 10000011, 10000021, 10000131),2023-02-18 13:00:00 array(10000030, 10600031, 10050031, 10050031, 10040031, 10200031, 10020031, 10110001),2023-02-16 13:00:00 array(10000030, 10600031, 10050031, 10040031, 10200031),);//批量设置在线用户状态foreach ($data as $date $uids) {$y date(Y, strtotime($date));$m date(m, strtotime($date));$d date(d, strtotime($date));$H date(H, strtotime($date));$cacheKey sprintf(online_user:%s:%s:%s:%s, $y, $m, $d, $H);foreach ($uids as $uid) {$redis-setbit($cacheKey, $uid - 10000000, 1);}}$redis-bitop(AND, online_user:stat, online_user:2023:02:17:13, online_user:2023:02:18:13) . PHP_EOL;//总在线用户6echo 总在线用户 . $redis-bitcount(online_user:stat) . PHP_EOL;$redis-bitop(AND, online_user:stat1, online_user:2023:02:18:13, online_user:2023:02:15:11) . PHP_EOL;//总在线用户2echo 总在线用户 . $redis-bitcount(online_user:stat1) . PHP_EOL;6.使用场景五计算用户留存率 /*** 计算用户留存率并保存到mysql30天用户留存率* return string*/public function actionRetentionRateUser(){$date_start date(Y-m-d, strtotime(-1 month));$date_end date(Y-m-d);$date_start strtotime($date_start);$date_end strtotime($date_end);$redis Yii::$app-redis_user;$platforms array_keys(Common::fromPlatformText()); //平台//循环日期获取日期范围对应的用户留存率并保存到数据库for ($i $date_end; $i $date_start; $i - 86400) {//当前日期$date date(Y:m:d, $i);//次日$date2 date(Y:m:d, strtotime(1 day, $i));//三日$date3 date(Y:m:d, strtotime(3 day, $i));//四日$date4 date(Y:m:d, strtotime(4 day, $i));//五日$date5 date(Y:m:d, strtotime(5 day, $i));//六日$date6 date(Y:m:d, strtotime(6 day, $i));//七日$date7 date(Y:m:d, strtotime(7 day, $i));//十五日$date15 date(Y:m:d, strtotime(15 day, $i));//三十日$date30 date(Y:m:d, strtotime(30 day, $i));//平台foreach ($platforms as $platform) {$key1 active_user: . $date . : . $platform;$key2 $platform;$dest_day2 retention_rate_user: . $date . :2day: . $key2;$dest_day3 retention_rate_user: . $date . :3day: . $key2;$dest_day4 retention_rate_user: . $date . :4day: . $key2;$dest_day5 retention_rate_user: . $date . :5day: . $key2;$dest_day6 retention_rate_user: . $date . :6day: . $key2;$dest_day7 retention_rate_user: . $date . :7day: . $key2;$dest_day15 retention_rate_user: . $date . :15day: . $key2;$dest_day30 retention_rate_user: . $date . :30day: . $key2;//获取当前日期上一天连续登录的人数$redis-bitop(AND, $dest_day2, $key1, active_user: . $date2 . : . $key2);//获取当前日期第三天连续登录的人数$redis-bitop(AND, $dest_day3, $key1, active_user: . $date3 . : . $key2);//获取当前日期第四天连续登录的人数$redis-bitop(AND, $dest_day4, $key1, active_user: . $date4 . : . $key2);//获取当前日期第五天连续登录的人数$redis-bitop(AND, $dest_day5, $key1, active_user: . $date5 . : . $key2);//获取当前日期第六天连续登录的人数$redis-bitop(AND, $dest_day6, $key1, active_user: . $date6 . : . $key2);//获取当前日期第七天连续登录的人数$redis-bitop(AND, $dest_day7, $key1, active_user: . $date7 . : . $key2);//获取当前日期第十五天连续登录的人数$redis-bitop(AND, $dest_day15, $key1, active_user: . $date15 . : . $key2);//获取当前日期第三十天连续登录的人数$redis-bitop(AND, $dest_day30, $key1, active_user: . $date30 . : . $key2);//计算登录人数//当前日期登录人数$curCount $redis-bitcount($key1);//当前日期上一天连续登录的人数$nextCount $redis-bitcount($dest_day2);//当前日期第三天连续登录的人数$threeCount $redis-bitcount($dest_day3);//当前日期第四天连续登录的人数$fourCount $redis-bitcount($dest_day4);//当前日期第五天连续登录的人数$fiveCount $redis-bitcount($dest_day5);//当前日期第六天连续登录的人数$sixCount $redis-bitcount($dest_day6);//当前日期第七天连续登录的人数$sevenCount $redis-bitcount($dest_day7);//当前日期第十五天连续登录的人数$fifteenCount $redis-bitcount($dest_day15);//当前日期第三十天连续登录的人数$thirtyCount $redis-bitcount($dest_day30);//设置半年过期时间$redis-expire($dest_day2, 15552000);$redis-expire($dest_day3, 15552000);$redis-expire($dest_day4, 15552000);$redis-expire($dest_day5, 15552000);$redis-expire($dest_day6, 15552000);$redis-expire($dest_day7, 15552000);$redis-expire($dest_day15, 15552000);$redis-expire($dest_day30, 15552000);//判断登录人数是否为0为0的就不插入数据库了$count $curCount $nextCount $threeCount $fourCount $fiveCount $sixCount $sevenCount $fifteenCount $thirtyCount;if ($count 0) {continue;}$params [cur_day $curCount,next_day $nextCount,three_day $threeCount,four_day $fourCount,five_day $fiveCount,six_day $sixCount,seven_day $sevenCount,fifteen_day $fifteenCount,thirty_day $thirtyCount,date $date,from_platform $platform,];//插入用户留存统计表RetentionRateUser::saveInfo($params); }}}参考https://blog.csdn.net/maoyuanming0806/article/details/81813776参考https://www.php.cn/php-weizijiaocheng-387074.html
http://www.dnsts.com.cn/news/201033.html

相关文章:

  • 国外做的比较的ppt网站有哪些方面建设论坛网站
  • 住建部网站建设部免费咨询产科医生
  • 电子商城网站建设价格南通企业建设网站电话
  • 外贸整合营销网站政务网站模板
  • 旅游网站建设ppt模板下载网站轮播图片psd源码
  • 网站开发设计工程师岗位职责wordpress放产品
  • cae毕业设计代做网站做网站找景安
  • 怎么优化一个网站关键词wordpress文章图片怎么居中
  • 牛天下网站建设wordpress导航模板下载
  • pc网站是什么表格 wordpress
  • 给别人做网站需要什么许可证网站哪个公司做的比较好
  • 建设银行网站修改密码嘉兴推广网站
  • 中国反钓鱼网站联盟信息如何优化上百度首页公司
  • 狮山建网站推广是做什么工作的
  • 做网站多少费用昆明网络优化
  • 网站的注册和登录怎么做烟台快速建站有哪些公司
  • 商城型网站建设怎么创建自己的网络平台
  • 找网络公司做的网站可以出售吗英文 网站 字体
  • 兴义网站建设公司无锡网站推广电话
  • 微网站建站平台天津市建设信息网官网
  • 闵行网站制作公司ppt模板免费下载第一ppt
  • 手机网站的优势个人网站空间
  • 抚州市建设局网站查询免费下载百度
  • 鹤山市网站建设公司免费建站平台官网
  • 旅游网站内容规划特点资金盘网站怎么建设
  • 做外贸 网站深圳一元购网站建设
  • 住房和城乡建设部网站干部学院北京网站设计学习
  • 做私活的网站承德网站建设电话
  • 建筑招工人在哪个网站比较好找建设旅游网站的意义
  • 郧阳网站建设网站域名备案主机名