为什么80%的码农都做不了架构师?>>>
如何统计网站的在线人数呢?
首先很简单的思想就是,如果只针对会员用户进行统计,在登录登出时加判断,然后维护一个表(或者其他存储方式)来存储在线会员即可。
但是有个问题就是,对于正常退出的会员当然可以使用这种方式,那如果该会员是关闭了网页或者停电或者其他因素,那如何得知这些情况呢?
1. 维护在线用户表
假设使用数据库来完成这个功能,想要达到最快的速度,就直接使用MYSQL内存表来保存在线会员的记录,
1:当会员登录时(包含自动登录),便去查找该会员是否存在于内存表当中,如果存在,则更新在线表当中的时间,如果不存在,则插入相应数据到内存表当中去
2:在用户退出时,由于没有进行办法实时的更新,因为用户有可能直接关闭网页离开,只能根据时间段来解决这个问题,写一个计划任务,每隔半个小时(或者其他时间),执行一次该程序,该程序主要的作用是扫描当前在线表当中,更新时间是否有小于当前时间10分钟或者多少分钟(这个根据具体情况自定义)的,如果有,则直接删除该条记录,这样便保证了大概的在线人数的统计。
这种做法的缺点,当用户数量很大时,对数据库压力会很大。
2. 使用Redis统计
将第一种方案的数据库改成使用redis,能够减轻数据库的负担,读写也更快。
当然我们可以从另一个角度来看,如果要统计的不仅仅是会员,要统计来访问网站的在线人数,我们可以考虑保存session(详情请查看服务器集群session共享),当session过期时则删除记录,相比于第一种方案,这种方案准确率就低了很多,但是性能更好。
3. 统计活跃用户
这里要提到的另一种思考是,如何统计网站的活跃用户呢?(比如把每天都登录称为活跃用户)
假设某网站有1亿用户,就算平均每天登录3000W用户,这个数据每天也相当庞大。
这里可以使用bitmap来保存用户登录状况,因为是否登录其实就是0/1,所以只用一位来保存就够了。这样存储就大大降低了。
我们把每天的用户登录信息记录到一个key中,值中的每个offset的值就是用户登录的标识
(1)设置关键字的指定offset的值为 0 或 1
setbit key 100 1
(2)bit运算
例如
key1 -> 0101
key2 -> 0011
and 运算
bitop and ret key1 key2
就是对 key1 key2 各位进行 and 运算后赋值给 ret,结果为 0001
or 运算
bitop or ret key1 key2
就是对 key1 key2 各位进行 or 运算后赋值给 ret,结果为 0111
(3)bit值为1的数量
bitcount key
通过bit操作就可以实现用户统计的需求了
例如今天为 2016-05-28
把 key 定义为 userlogin:20160528
(1)用户登录
ID为 100 的用户登录了,执行
setbit userlogin:20160118 100 1
(2)统计今天登录的用户数
bitcount userlogin:20160118
(3)统计3天内都登录过的用户
“都登录过”是要取得bit值都为1的,通过 and 计算获取
bitop or ret userlogin:20160116 userlogin:20160117 userlogin:20160118
(4)统计7天内登录过的用户
“登录过”表示bit值有一个为 1 即可,所以通过 or 计算获取
命令与上一个类似
Reference:
1. http://bbs.csdn.net/topics/330154127
2. http://blog.edagarli.com/2016/01/20/%E4%BD%BF%E7%94%A8Redis%E7%BB%9F%E8%AE%A1%E6%B4%BB%E8%B7%83%E7%94%A8%E6%88%B7/