点击进入“编程经验共享”
在线人数统计业务是我们开发过程中必不可少的业务逻辑,今天就php+redis的几种设计方案,来分析一下各个方案的优缺点:
一. 集合
redis的集合是String类型的无序集合,集合成员是唯一的,没有重复的元素。
集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
这种方案能储存在线的用户数,也能执行一定的聚合计算,随着用户量的增加,消耗内存空间随之增加。
再来看看集合能统计出哪些信息吧
//key根据天来变化,储存的值为用户id$redis = new \Redis();//判断用户是否在线$redis->sIsMenber('online_user_20220506','用户标识')//每天在线用户总量的统计或者最近一周每天在线用户总量$end_time = strtotime('00:00:00');for($i=0;$i<6;$i++){//统计日期$date = $end_time-$i*24*60*60;//获取某一天的在线用户数,可以用数组储存再返回给前端显示$redis->sCard('online_user_'.date('Ymd',$date));}//两日连续在线用户总量(通过计算集合的交集获取连续在线用户总量)$redis-sInter('online_user_20220506','online_user_20220507')//七日在线总用户量(通过计算集合的并集获取在线用户总量)$redis->sUnion('online_user_20220506','online_user_20220507','online_user_20220508','online_user_20220509','online_user_20220510','online_user_20220511','online_user_20220512')
集合的作用看起来还不错,但是无法获取某天里某个时间段的在线用户总量。例如:中午12点~2点的在线用户总量,也不知道用户当天打开的时间。对于这一点有序集合就提供了很好的帮助
二. 有序集合
有序集合与集合一样都是string类型元素的集合,且不能有重复的元素。
集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
不同的是,有序集合每一个元素都会关联一个double类型的分数,通过分数给元素排序。
我们来看看有序集合能统计出来的数据有哪些吧
//通过有序集合存储在线用户时,元素为用户标识,分数为进入app或者登录时间$redis = new \Redis();//判断用户是否在线及用户某日首次进入app的时间//(不存在集合中返回null,否则返回分数值即进入app/登录时间)$redis->zScore('online_user_20220506','用户标识')//每天在线用户总量的统计或者最近一周每天在线用户总量$end_time = strtotime('00:00:00');for($i=0;$i<6;$i++){//统计日期$date = $end_time-$i*24*60*60;//获取某一天的在线用户数,可以用数组储存再返回给前端显示$redis->sCard('online_user_'.date('Ymd',$date));}//两日连续在线用户总量(通过计算集合的交集获取连续在线用户总量),并储存在新的key中$redis-zInterStore('online_user_zand0607',['online_user_20220506','online_user_20220507'])//七日在线总用户量(通过计算集合的并集获取在线用户总量)$redis->zUnionStore('online_user_zand0607',['online_user_20220506','online_user_20220507','online_user_20220508','online_user_20220509','online_user_20220510','online_user_20220511','online_user_20220512'])//统计中午12点~2点在线用户总量(通过分数计算某个时间段在线总量)$redis->zCount('online_user_20220506',mktime(12,0,0),mktime(14,0,0));
有序集合确实比集合要好得很多。缺点和集合一样,当数据量越大时,占用内存越大。
在redis中还有两种数据类型:hyperLogLog和bitmap
每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是无法存储用户首次访问的时间,也无法计算中午12点到14点的在线用户数。如果需要统计就需要更多的redis键去存储更多的数据,不利于代码编写,还容易出错。
bitmap也叫位图,也就是用一个bit位来表示一个东西的状态,我们都知道bit位是二进制,所以只有两种状态,0和1。个人不建议大家使用该数据类型,不利于业务系统的发展。
综上所述,个人推荐使用有序集合存储用户在线信息。有序集合能够更好得聚合运算,有助于业务系统的发展。




