7
回答
大批量的IP地理位置查询如何保证性能问题?
终于搞明白,存储TCO原来是这样算的>>>   

最近做一个用户信息统计的课题,其中有一项是要根据来访者IP统计各个省份用户的流量信息。

网上有很多http接口实现ip位置查询,但是如果在统计的时候每个ip都连一次http获取位置在数据量大的情况下肯定是不现实的。

我的一个想法是在数据库表中新增一个location字段,在每次插入一条ip记录的时候就调用http接口获取位置并存入location字段,而不是在取出所有IP记录后再去一条条进行查询并返回结果。不知道这样的想法合理不?还是或者网上有相关ip/省份的划分映射表可以供参考?

另外,我这个系统从数据库中取很多数据记录并且做相关分析,取出一批浏览记录,我可能会根据其中的user agent字段分析生成另一批数据。如果我想缓存原始的数据和处理后的数据(比如2014年4月24日11:00-12:00的浏览记录,并根据这个记录分析生成11:00-12:00浏览器使用情况数据,我想把这两个数据都做缓存),那么在service层和dao层都调用相关的cache.get之类的缓存接口,这是不是一种不良好的设计?

或者dao返回数据库中取出的原始结果,service对数据做中间处理并返回最终结果,因为处理过程耗时比较长,就直接在service做最终结果的缓存,而dao层就不缓存最终结果。那么cache只在service层出现。

再或者我直接就在dao层把最终结果加工好返回,并且做缓存,这样cache只在dao层出现。

按理来说一般最后一种设计方式是最切贴的,数据怎么去取数据、数据是从cache还是从db来等是dao层干的事,但是最后这种方式dao层又做了service层该干的事(处理数据结果),有点多管闲事的感觉。

有没有一种比较合理的设计方式呢?


补充一下,这个是一个平台,也就是说统计的不只是一个网站,而是很多个站点。类似百度统计或者google analystic的简化版。

举报
kliyn
发帖于3年前 7回/532阅
共有7个答案 最后回答: 3年前


设计先别提前介入。

首先考虑应用场景:

1.需求是查询IP对应的位置的。

2.目的是统计各省份流量信息。

然后,明显你的需求是离线的数据分析。

其实用python之类的脚本语言进行字符串分析和统计就能解决。

3.看你用java的原因,是为了提供实时的结果。

为了实时查询,你需要的是实现流式统计数据叠加。

也就是实现需求

1.统计一个月的访问情况,存储结果。

2.统计到现在一周的访问情况。存储结果。

3.统计这周到今天0点的访问情况,存储结果。

4.统计0点到最近一个小时的访问结果。

5.统计最近一个小时到现在时刻的访问情况。

6.把上面的结果进行叠加,迅速得到你要的报告。

讨论啥dao,service都是南辕北辙。

在扩展一下,如果你要查询每一个时段的访问情况,可以按照小时的级别,天级别,周级别,月级别存储结果。你们网站的存在时间应该不超过10年,所以用月都有点多余。就按周生成报告,10年520条记录。按天生成的报告,3640条记录,按小时生成的记录,87360条记录,对数据库来说毛毛雨了。如果你设计数据库严格一点,一个省和地区还有国家一条记录,没份统计结果撑死30个,也就是200万条。。 这个可以再调一下,6个小时生成一次报告,降低为30万条左右。

生成报告的时候,现在一个2000条记录的表里面查,然后在一个2万条记录的表里面查,然后在一个30万条数据表里面查,最后在当前6个小时的访问记录表里面查询。应该能在1秒之内给出结果。

实现的时候,用quartz或者纯粹的java.utils.Timer类实现定时任务就行。

引用来自“Brin想写程序”的评论


设计先别提前介入。

首先考虑应用场景:

1.需求是查询IP对应的位置的。

2.目的是统计各省份流量信息。

然后,明显你的需求是离线的数据分析。

其实用python之类的脚本语言进行字符串分析和统计就能解决。

3.看你用java的原因,是为了提供实时的结果。

为了实时查询,你需要的是实现流式统计数据叠加。

也就是实现需求

1.统计一个月的访问情况,存储结果。

2.统计到现在一周的访问情况。存储结果。

3.统计这周到今天0点的访问情况,存储结果。

4.统计0点到最近一个小时的访问结果。

5.统计最近一个小时到现在时刻的访问情况。

6.把上面的结果进行叠加,迅速得到你要的报告。

讨论啥dao,service都是南辕北辙。

在扩展一下,如果你要查询每一个时段的访问情况,可以按照小时的级别,天级别,周级别,月级别存储结果。你们网站的存在时间应该不超过10年,所以用月都有点多余。就按周生成报告,10年520条记录。按天生成的报告,3640条记录,按小时生成的记录,87360条记录,对数据库来说毛毛雨了。如果你设计数据库严格一点,一个省和地区还有国家一条记录,没份统计结果撑死30个,也就是200万条。。 这个可以再调一下,6个小时生成一次报告,降低为30万条左右。

生成报告的时候,现在一个2000条记录的表里面查,然后在一个2万条记录的表里面查,然后在一个30万条数据表里面查,最后在当前6个小时的访问记录表里面查询。应该能在1秒之内给出结果。

实现的时候,用quartz或者纯粹的java.utils.Timer类实现定时任务就行。

你的提议很好。
但是就是有个问题我没有说明清楚,我的这个课题是提供一个平台多用户使用的,也就是说统计的站点是有许多个。单个网站使用定时作业调度是个非常好的选择,但是对于这种多个网站的,如果每个网站都这样执行,那肯定是很耗费资源的。所以我的想法就是在需要统计的时候取出原始数据,再做数据处理,再缓存。但是这个缓存是放在dao层还是service我就有点犹豫了,我在设计的时候想明确dao和service的职责边界。。。
--- 共有 2 条评论 ---
Brin想写程序如果写过redis和mysql混合编程的程序就知道了。是放在service层次去干这个事情的。 3年前 回复
Brin想写程序sevice层没那么扁平。应该放在service层。 3年前 回复

国内用纯真ip库(java代码网上有,自己搜下),国外用geo_ip库(有多种模式一种是他提供api,我使用的是cvs文件,将全部数据加载到treemap(将ip看成256进制))

开发者的福利到了,devstore将拿出十万,悬赏写评测报告的开发者,参与就有奖。                                               

顶部