首页 新闻 会员 周边 捐助

每天3000W数据,每次访问都要查询此IP当天访问次数,高并发怎么处理?

1
悬赏园豆:50 [待解决问题]

数据库是sqlserver,已分表,每天一张数据表,大概3000W数据一天

需求是每次别人访问,都必须查询一下当天的访问状态,比如访问A页面多少次,访问B页面多少次(没办法,需求是这样)

还要通过一定条件去判断是否是代理(也是查数据库)

之前是按cookies,但这东西不靠谱,很多相同的IP但空cookies过来

但每次都要连接一次数据库查几百万数据,性能又吃不消,而且是高并发状态,高的时候可能1分钟好十几万访问量

也考虑过nosql,但不熟悉,请问高人是否有解决方案

问题补充:

------------抱歉,数字写错了,不是300W而是3000W一天(3000W是包括所有访问轨迹,包括访问JS,img,css等等)

其实就是个流量系统的日志和防火墙类似的功能,每个访问的目标,要按N个条件去比较数据库里的数据,以判断来的是真实用户还是机器人(很多刷子),包括了IP(一定时间内重复次数,黑名单),UA,来源地址,cookies等等

最主要的问题是高并发,可能会有1分钟内十几万的并发量,而且所有的访问日志都要再进入这个表里。查询条件比较复杂,因为涉及多个条件,而且还有一段时间内的重复IP判断,甚至是虽然不同IP(可能是加了代理刷的)但要判断UA和reffer还有其他的一些条件做出相似性的分数判断,差不多有些每次都要大数据分析的概念。我就在想,这种情况下,怎么个解决方案比较好。。。

大米DM的主页 大米DM | 初学一级 | 园豆:109
提问于:2017-10-09 15:28
< >
分享
所有回答(7)
1

用redis的自增命令吧.

吴瑞祥 | 园豆:29449 (高人七级) | 2017-10-09 15:42
1

没搞懂啊,你这个300w数据,根据ip做一个索引,至于那么慢么?

再说,300w又不是很大的数据量。而且你还可以做缓存把查询的结构存一下。

实在不行,扔Mongo(比较像SQL的NOSQL),查询也是不会慢。

幻天芒 | 园豆:37207 (高人七级) | 2017-10-09 16:33

我的意见是分时段聚合。3000w这个表作为数据源表。然后每个时间段(每小时),利用定时任务聚合到某个特定的表上,然后将源表的多余记录干掉。这样的话,基本上数据量就会很小,查询的时候,只需要union下两张表的数据即可。

支持(0) 反对(0) 幻天芒 | 园豆:37207 (高人七级) | 2017-10-09 22:33
1

查数据库的这个过程要挪出来,不管你是什么规则匹配或是什么其他的玩意,就算不用nosql你把规则信息写配置文件里面一次性加载都可以。

统计这个用redis自增可以,如果仅仅只是统计某个页面ip去重的总访问量可以用hyperloglog(省空间,但有一定误差,不过误差很低),不考虑空间开销的话hash也可以(但看你的场景可能到了第二天时前一天的hash就没用,这个时候要注意前面一天hash的删除或者过期可能会使redis卡一下)

 

update:

你附加问题中提到的规则也是可以拿到缓存里面来的啊,以你可能出现的规则中也出现需要查询的场景(比如黑名单),这种可以直接在缓存中exists判断下就完了

单位时间内重复ip也容易,你直接加个有expire的key,每次去incr下,如果incr的结果大于你的设置值就拦下来了,其他的以此类推

归根结底如果一分钟几十万次调用只能允许极少量的请求直接落到db上,否则需要对db的硬件需求量就大了

Daniel Cai | 园豆:10424 (专家六级) | 2017-10-09 16:42
1

就是一个以页面和日期(天)为索引的列(广义列)和一个计数列 的表就解决了。

请求进来直接匹配此索引,而该表数量肯定是非常有限的,而且这种写入不必等待,你还想抛开这种等待,可以有单独的此任务的任务队列去执行处理。

花飘水流兮 | 园豆:13617 (专家六级) | 2017-10-09 16:58
0

根本性的解决方法是在原来的基础上增加一个统计表,统计表的数据是在统计数据新增的时候,另外再写入,每个页面一条统计数据,累计统计访问量,具体的还可以再分出更多字段,比如来源自搜索引擎的点击。至于ip的重复访问,就需要再另建一个表来统计,每个ip一条数据……所有的工作量集中在统计写入的时候处理。如果这种统计是在页面前端用js调用的形式来统计,放在页尾基本也不会影响网页打开速度了。

然后查看的时候调用统计表,每个统计表如果要看详细数据,再点击去检索那详细表的数据出来,通常这个也只是管理后台在用,对整站不会有多大性能上的影响。。。

如果按你原来的思路,只能硬统计,没办法的事情。

陈子 | 园豆:241 (菜鸟二级) | 2017-10-11 14:59
0

实在不行,找一台机器专门做缓存。频繁使用的,缓存一下,

还有一种,关键字既然是IP,考虑一下,数据再按照IP分表存一下。临时。

Supper_litt | 园豆:1036 (小虾三级) | 2017-10-12 10:42
0

这个东西还是程序来搞吧
每次访问就在Redis里面搞一个计数器记录起来
查询的时候。就直接读缓存就可以了

Giant150 | 园豆:1172 (小虾三级) | 2017-11-23 16:45
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册