关于Youtube的观点数

时间:2011-09-28 19:16:17

标签: database ruby-on-rails-3 database-performance

我正在实施一个应用程序,可以跟踪帖子的查看次数。但我想保持一种“聪明”的跟踪方式。这意味着,我不想仅仅因为用户刷新浏览器而增加视图计数器。

因此,如果IP和用户代理(浏览器)是唯一的,我决定只增加视图计数器。到目前为止哪个是有效的。

但后来我想。如果Youtube正在这样做,他们有几个视频有数千甚至数百万的视图。这意味着他们在数据库中的视图表将过多地填充IP和用户代理....

这使我假设他们的视频表具有视图的计数器缓存(即views_count)。这意味着,当用户点击视频时,将存储IP和用户代理。此外,视频表中的计数器缓存列也会增加。

每次点击视频。 Youtube需要查询视图表并计算条目数。这不会对性能造成太大影响吗?

这是他们这样做的吗?或者有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

如果您想存储所有IP和浏览器,请确保您有足够的数据库存储空间,添加索引就可以了。 如果没有,那么您可以使用rails会话来存储用户访问过的视频列表,并且只在访问新视频时增加视频的view_count属性。

答案 1 :(得分:1)

首先,afaik,youtube使用BigTable,所以不要担心查询计数,我们无论如何都不知道数据库的确切结构。

假设您使用的是关系模型,请创建列view_count,但不要在每次刷新时更新它。记录访问者并定期更新缓存。

此外,您可以从IP,浏览器,日期以及用于检测这是否是唯一视图的任何其他信息生成哈希值,并且不存储整个数据。

此外,您可以使用session / cookie记录正在查看的视图。由于它将过期,它不会是这样的记忆问题 - 我不相信任何人在一次会议中观看数千个视频

答案 2 :(得分:1)

我会利用客户端浏览器指纹识别来唯一地识别视图计数。这个图书馆似乎有了很大的吸引力:

https://github.com/Valve/fingerprintJS

我还建议使用Redis处理与计数有关的任何事情。它的原子增量命令易于使用,并保证您的计数永远不会因竞争条件而搞砸。

这将是您希望用于递增计数器的命令:

http://redis.io/commands/incr

这种情况下的密钥是从客户端发送给您的浏览器指纹哈希。然后,您可以使用Redis“set”,其中包含已知与给定user_id相关联的所有浏览器指纹的列表(该组的键将是user_id)。

最后,如果您确实需要,则运行cron作业或其他异步进程,将每个用户的视图计数转储到关系数据库的计数器缓存字段中。

您还可以采用在关系数据库(mysql?)中存储user_id,浏览器指纹和时间戳的方法,并定期将它们缓存到用户表中(可能通过cron)。