他们可以将我的IP地址存储在表格中,但不会它使它变慢吗?他们将需要为每个请求再查询一次数据库。
#1 楼
我最近研究了Stack Overflow视图计数器的功能,因为我想实现类似的功能(我做了)。我对此事的讨论在这里:剖析Stack Overflow视图计数器那么,这件事是如何工作的?事实证明,这很简单。
每个问题页面上都嵌入了该计数器链接:
http://stackoverflow.com/posts/3590653/ivc/[Random code]
每个页面加载(无论是否缓存)。
有某种限制机制在起作用。它成对保存每个访问者关于问题视图的信息,如成对保存:
对于匿名用户,它是
IP + QuestionNr
。对于经身份验证的用户,它是UserNr + QuestionNr
。此信息将在过期的缓存条目中保存约15分钟。如果随后的匹配项仍然存在,它将丢弃新的匹配项。如果已消失,则允许新记录。
每次注册新命中时,除了过期的缓存条目外,它还被添加到内存缓冲区中。缓冲区本身也会在几分钟后或填充到一定大小后到期,以先到者为准。到期后,它累积的所有内容都会批量写入数据库。他们称其为“缓冲写入方案”。我喜欢这个词。基本上,缓冲区条目是按每个问题分组的,然后仅添加到问题视图的总和中,没有特定的表来存储每个访问详细信息(太多存储),例如:
UPDATE Question
SET Views = Views + @NewViews
WHERE Nr = 36278
对于在缓冲区中注册了任何视图的每个问题也是如此。为了优化和最小化数据库访问,您可以一次运行将多个问题的全部数据发送到更新查询。您可以将数据格式化为XML,在查询中加入数据,然后在一条语句中执行更新。
差不多。
我还无法弄清计数器网址中的[Random code]是什么,但这没关系。没有这个神秘的部分,大约两周前,我已经在ASP.NET MVC + SQL Server下为我当前正在从事的项目实现了该方案。从那时起,我就在我的开发机器上运行了它,它的运行就像是一种魅力。视图已正确注册。 :)
评论
为什么他们需要将命中信息存储在缓冲区和缓存中?缓冲区在缓存中吗?当您说它过期时,您是否使用CacheItemRemovedCallback处理过期的缓存以更新sqlserver?谢谢。
–雷
2011年6月29日在1:01
缓冲区也位于缓存中,并且比命中缓存更频繁地过期。匹配缓存用于将来自同一用户的匹配限制为每15分钟一次。从收到的匹配中,将新匹配(在匹配缓存的帮助下检测到)放入缓冲区,并使用回调方法定期将其刷新到数据库中。
–user136634
2011年6月29日14:38
感谢开发人员艺术!缓存是为了防止同一用户每15分钟访问太多次,但是我仍然不清楚,如果缓存已经收集了匹配并在过期时写入数据库,为什么还要使用额外的缓冲区?换句话说,如果我仅使用高速缓存来收集问题的IP记录15分钟,并在该时间段内丢弃来自高速缓存中现有IP条目的所有匹配,然后当cahce在15分钟结束时过期时,我将更新数据库,这行得通吗?你能对此发表评论吗?谢谢。
–雷
2011年6月29日19:39
@ ray247:您可以只使用一个缓冲区来命中。但是,在那种情况下,您的回调函数将针对每个匹配命中,并且您将以与命中相同的时间更新数据库。这可能是一项昂贵的操作。带有附加缓冲区的想法是累积命中数,将它们按其所属的问题分组,然后批量更新数据库,每潜在的数百次命中一次。
–user136634
2011年7月3日在13:19
嗨,Developer Art,我的想法是在缓存中有一个List对象,然后在列表中将请求的所有IP都放入页面中。因此,List对象将所有点击累积到页面上,我将List obj缓存了15分钟。因此,我不会为每次命中写入数据库,当缓存过期时,我将List中的所有IP加起来,然后将该编号添加到数据库中。
–雷
2011年7月5日14:27
@ ray247:不太一样。在您的方法中,假设用户在缓存过期前1分钟访问了一个页面。访问被注册,然后缓存被快速擦除。原始访问两分钟后,用户再次访问该页面,并且由于旧缓冲区已用完,该匹配将被重新注册-两分钟内两次-这显然是错误的。如果将每对(用户+页面)存储在单独的过期缓存条目中,则将提供一种真正的限制机制,而不会出现边缘情况。
–user136634
2011年7月5日在16:36
@ ray247:由于所有匹配都没有共享存储,因此添加一个额外的缓冲区是有意义的。不过,请使其尽快过期,因为用户会想知道为什么自创建问题后的前15分钟内没有注册视图。 3-5分钟与他们的不耐烦相处的可能性更大。
–user136634
2011年7月5日在16:36
嗨,Developer Art,非常好的观点。我想问一下缓冲区快于缓存过期的时间,您用什么时间呢?您是否使用线程并让它每5分钟休眠一次,然后更新数据库,然后再次休眠,或者您使用什么?非常感谢。
–雷
2011年7月7日在15:25
@ ray247:我通过将缓冲区自身放入即将过期的缓存条目来简化缓冲区。一旦到期或达到预定义的计数大小(无论先发生什么),其内容都会刷新到数据库中。我相信其他技术也是可以想到的。
–user136634
2011年7月9日在17:26
@Developer Art,真棒响应。谢谢。我一直在寻找有关此方面的信息,因此很难获得。我有两个问题:1)当您说“不是每个问题的更新声明”时,您是什么意思?我认为缓冲区存储是某种类型的结构或带有postId / hits值对的数组,并通过查询来循环以更新问题。 2)是按个别方式存储匹配数据,还是将它们放入存储所有匹配数据的内存结构/表中?
– Mohamad
2011年7月11日23:10
@Mohamad:1)查看更新。 2)我确实将它们放入单独的缓存条目中。当它投入生产时,是否最优是很清楚的。
–user136634
2011年7月13日在20:23
这些答案很老,但我仍然感到好奇,如果我在登录时每小时检查自己的问题的观看次数,是否会增加OWN问题的观看次数?
–塔利亚
2014-09-23 19:27
@Thalia:是的,它应该增加计数。查看您自己的问题是否增加了其查看次数?
– jfs
18年5月19日在17:34
如何添加缓冲区和缓存?在PHP中?
–马文
19年5月21日在1:36
#2 楼
我试图欺骗编写一个脚本,该脚本不断获取页面以获取10k的浏览量和金牌,但没有用:)它保存了上次查看该页面的所有IP地址一个小时左右。如果IP已经查看过该问题,则查看次数不会增加。这是一种资源密集型的操作,但这是获得准确的视图计数的唯一方法。
一个小时左右后,条目将被删除,因此表不会变得太大和太慢。
评论
[需要引用]
– balpha
2010年1月23日14:07在
清理桌子,使其不会变大是这里的窍门,所以:)谢谢。
– andrerpena
2010年1月23日在19:24
我也很想知道这个答案的有效性
– barfoon
2011年2月11日在17:01
@balpha:观察不够好吗?
–托马斯·博尼尼(Thomas Bonini)
2011-2-23在13:36
@Kop:如果您能够观察到从数据库中的表中删除了什么,则我们有很大的问题:)
– balpha
2011-2-23在13:48
@balpha:现在您可以访问了,您是在说我的帖子不正确吗? :P
–托马斯·博尼尼(Thomas Bonini)
2011-2-23在16:53
您是否尝试过使用多代理?
–systempuntoout
11年4月30日在21:34
@Kop,当您说桌子时,您在说什么?数据结构?一个SQL表?我想,无论它是什么,它都是存储在内存中而不是HD的内容,对吗?
– Mohamad
2011年7月11日23:00
@Mohamad,只是一个疯狂的猜测,但更有可能是Redis。
– Arjan
2012年7月26日在8:40
至于“最后一个小时左右”,Jeff在2010年10月评论说:“我们的观看次数非常严格-更加类似于访问,因为每15分钟间隔每个IP的访问次数是唯一的”。但是从那以后,情况肯定会发生变化。
– Arjan
2012年7月26日9:09
如果他们在一小时后删除了视图数据,那么任何人都可以每隔一小时通过调用脚本来注册视图计数,那么注册用户呢?他们如何处理27k视图= 27k记录
– Vikas Kandari
20年1月31日,9:55
评论
+1是个好问题。 @Peter感谢您开始赏金。希望有内部知识的人会回答;但是,我打赌不会,因为他们不想公开这个数字。关于SO的问题很多,表明正确获取视图有多困难。您必须担心巨型IP表,具有相同NATed IP的大量人员等。希望有人对内部工作原理有所了解。RE:“他们将需要为每个请求再查询一次数据库。”实际上,对于智能设计而言,事实并非如此。您每次只需将IP发送到数据库,然后使用存储过程确定是否应增加计数。如果是这样,则递增,然后返回计数。看到?一次数据库往返。 ;)