项目需求,试着写了一个简单登录统计,基本功能都实现了,日志数据量小。具体性能没有进行测试~ 记录下开发过程与代码,留着以后改进!
1. 需求
实现记录用户哪天进行了登录,每天只记录是否登录过,重复登录状态算已登录。不需要记录用户的操作行为,不需要记录用户上次登录时间和IP地址(这部分以后需要可以单独拿出来存储) 区分用户类型 查询数据需要精确到天
2. 分析
考虑到只是简单的记录用户是否登录,记录数据比较单一,查询需要精确到天。以百万用户量为前提,前期考虑了几个方案
2.1 使用文件
使用单文件存储:文件占用空间增长速度快,海量数据检索不方便,Map/Reduce操作也麻烦
使用多文件存储:按日期对文件进行分割。每天记录当天日志,文件量过大
2.2 使用数据库
不太认同直接使用数据库写入/读取
- 频繁请求数据库做一些日志记录浪费服务器开销。
- 随着时间推移数据急剧增大
- 海量数据检索效率也不高,同时使用索引,易产生碎片,每次插入数据还要维护索引,影响性能
所以只考虑使用数据库做数据备份。
2.3 使用Redis位图(BitMap)
这也是在网上看到的方法,比较实用。也是我最终考虑使用的方法,
首先优点:
数据量小:一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间。1亿人每天的登陆情况,用1亿bit,约1200WByte,约10M 的字符就能表示。
计算方便:实用Redis bit 相关命令可以极大的简化一些统计操作。常用命令 SETBIT、GETBIT、BITCOUNT、BITOP
再说弊端:
存储单一:这也算不上什么缺点,位图上存储只是0/1,所以需要存储其他信息就要别的地方单独记录,对于需要存储信息多的记录就需要使用别的方法了
3. 设计3.1 Redis BitMap
Key结构:前缀_年Y-月m_用户类型_用户ID
标准Key: KEYS loginLog_2017-10_client_1001
检索全部: KEYS loginLog_*
检索某年某月全部: KEYS loginLog_2017-10_*
检索单个用户全部: KEYS loginLog_*_client_1001
检索单个类型全部: KEYS loginLog_*_office_*
...
每条BitMap记录单个用户一个月的登录情况,一个bit位表示一天登录情况。
设置用户1001,217-10-25登录: SETBIT loginLog_2017-10_client_1001 25 1
获取用户1001,217-10-25是否登录:GETBIT loginLog_2017-10_client_1001 25
获取用户1001,217-10月是否登录: GETCOUNT loginLog_2017-10_client_1001
获取用户1001,217-10/9/7月是否登录:BITOP OR stat loginLog_2017-10_client_1001 loginLog_2017-09_client_1001 loginLog_2017-07_client_1001
...
关于获取登录信息,就得获取BitMap然后拆开,循环进行判断。特别涉及时间范围,需要注意时间边界的问题,不要查询出多余的数据
获取数据Redis优先级高于数据库,Redis有的记录不要去数据库获取
Redis数据过期:在数据同步中进行判断,过期时间自己定义(我定义的过期时间单位为“天”,必须大于31)。
在不能保证同步与过期一致性的问题,不要给Key设置过期时间,会造成数据丢失。
上一次更新时间: 2107-10-02
下一次更新时间: 2017-10-09
Redis BitMap 过期时间: 2017-10-05
这样会造成:2017-10-09同步的时候,3/4/5/6/7/8/9 数据丢失
所以我把Redis过期数据放到同步时进行判断
我自己想的同步策略(定时每周一凌晨同步):
一、验证是否需要进行同步:
1. 当前日期 >= 8号,对本月所有记录进行同步,不对本月之前的记录进行同步
2. 当前日期 < 8号,对本月所有记录进行同步,对本月前一个月的记录进行同步,对本月前一个月之前的所有记录不进行同步
二、验证过期,如果过期,记录日志后删除[/code]3.2 数据库,表结构
每周同步一次数据到数据库,表中一条数据对应一个BitMap,记录一个月数据。每次更新已存在的、插入没有的
3.3 暂定接口
- 设置用户登录
- 查询单个用户某天是否登录过
- 查询单个用户某月是否登录过
- 查询单个用户某个时间段是否登录过
- 查询单个用户某个时间段登录信息
- 指定用户类型:获取某个时间段内有效登录的用户
- 全部用户:获取某个时间段内有效登录的用户
4. Code
TP3中实现的代码,在接口服务器内部库中,Application\Lib\
├─LoginLog
│├─Logs 日志目录,Redis中过期的记录删除写入日志进行备份
│├─LoginLog.class.php 对外接口
│├─LoginLogCommon.class.php 公共工具类
│├─LoginLogDBHandle.class.php 数据库操作类
│├─LoginLogRedisHandle.class.php Redis操作类
4.1 LoginLog.class.php
<"htmlcode"><"htmlcode"><"htmlcode"><"_blank" href="https://segmentfault.com/a/1190000008188655" rel="external nofollow" >https://segmentfault.com/a/1190000008188655http://blog.csdn.net/rdhj5566/article/details/54313840
http://www.redis.net.cn/tutorial/3508.html
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]