背景:
原始数据是上线一条数据纪录,下线一条数据数据纪录。并且数据量巨大,每秒产生20K~50K条数据。
数据纪录格式为文本,大概是这样: IP地址,端口号,时间,上线/下线现在需要当收到下线数据纪录时,找到之前的上线数据纪录。同时计算出该用户上网的时长。上网时间=下线时间-上线时间。
需要注意的问题:
1、上网时间可能会超过一周,因此前面上线纪录的数据需要保存较长时间,假设最长一周。
2、如何高效迅速的查到的对应的上线数据纪录,而不至于整个处理程序被堵塞。
3、按照IP地址、端口号来标识唯一一次用户上线行为,用户记录数最大可能会达到20M条纪录。假设可以全部放入内存中。
4、收到用户下线纪录后,完成上线时长的计算后,应该将内存中的相应上线纪录数据删除。删除也会有性能开销。请各位大牛给一些思路和方案,感觉应该有对应这个问题的数据结构和算法。谢谢!!!最多只能一次给100分,如果问题解决,可以另外开帖子散分。高性能计算算法内存
原始数据是上线一条数据纪录,下线一条数据数据纪录。并且数据量巨大,每秒产生20K~50K条数据。
数据纪录格式为文本,大概是这样: IP地址,端口号,时间,上线/下线现在需要当收到下线数据纪录时,找到之前的上线数据纪录。同时计算出该用户上网的时长。上网时间=下线时间-上线时间。
需要注意的问题:
1、上网时间可能会超过一周,因此前面上线纪录的数据需要保存较长时间,假设最长一周。
2、如何高效迅速的查到的对应的上线数据纪录,而不至于整个处理程序被堵塞。
3、按照IP地址、端口号来标识唯一一次用户上线行为,用户记录数最大可能会达到20M条纪录。假设可以全部放入内存中。
4、收到用户下线纪录后,完成上线时长的计算后,应该将内存中的相应上线纪录数据删除。删除也会有性能开销。请各位大牛给一些思路和方案,感觉应该有对应这个问题的数据结构和算法。谢谢!!!最多只能一次给100分,如果问题解决,可以另外开帖子散分。高性能计算算法内存
这样在内存中储存时只需要一个map,key是用户id可以为 ip:port,数据为上线时间对于那个文件,可以用个watcher只观察modify这个事件,每此收到此事件获得新的文件大小,对比上次事件的大小只处理这两个事件变化的部分
此外删除上线数据并不需要实时,开一个线程定时遍历并删除那些过期的map entry,好处是某些用户可能重复登陆,重复使用可减少GC。
关于文件其实不需要watcher,既然数据量很大,那么就可以假设文件每时都在变化,一个定时检查器就足够了。整个程序的驱动器就像这里所说的LogView http://sunnylocus.iteye.com/blog/694666
1. 数据库2个表,一个存储当前在线状态,一个存储历史上线与离线状态。
2. 缓存例如1000个用户状态,缓存满了就写入数据库,这样用于减轻数据库访问压力。缓存有许多优秀的框架,直接用。
那就都放HASHMAP好了 一开始初始化的时候开大点,以避免扩容带来的性能损耗。
当用户下线的时候,组织session(IP+端口号) 新开线程去查询和得到上线时间并把该用户的上线记录删除?这所有的逻辑都在一起了,处理起来估计效率有点慢吖!或者直接把数据丢给其他程序处理,主程序只做数据转发,开多个客户端处理,主程序和客户端程序用socket通讯?