我有一个允许用户提交博客文章的网络应用程序。我想跟踪每个博客文章页面的页面浏览量。因此,当一些访问:
/post/123
用户的访问者应该看到访问过此页面的人数。你知道吗
我想到的一个似乎无法扩展的解决方案是在Blog类型中添加一个page\u views属性:
class Blog(ndb.Model):
title = ndb.StringProperty()
page_views = ndb.IntegerProperty()
然后,每当访问页面时,只需执行blog.page_views
加1即可。然后blog.put()
。但是,这种尝试意味着我们将过于频繁地向db写入数据。你知道吗
有更好的办法吗?你知道吗
如果您的目的是获得非常准确的页面视图计数是的,那么您必须将其保存在数据存储中,并且必须解决超过最大实体组写入速率~1/秒的风险。本例中的典型方法是Sharding counters。你知道吗
但是,如果您对偶尔可能丢失一些视图(IMHO完全可以接受)感到满意,那么您可以使用不同的策略,使用memcache存储计数器和时间戳,您可以对其进行调整,使其在数据存储操作方面更加轻松。在每个页面视图上,您都会调用一个事务函数(以防止损坏数据存储计数器值),该函数将:
我会选择任务延迟值等于“最近足够”值。你知道吗
通过调整“足够新”值,可以控制更新数据存储计数器值的频率。你知道吗
当您想显示视图的数量时,您只需读取datastore值和memcache值(按此顺序,以防止可能的争用情况,在这种情况下,您需要对memcache计数器值进行两次计数),然后将它们相加即可获得访问计数。你知道吗
由于ndb中的一致性问题,写入数据存储中的计数器可能非常不准确,尤其是当你的应用程序获得大量流量时。您的一个实例可能读取1234
page_views
的当前计数,然后尝试将1235写入数据存储。但是,在此期间,可能其他访客也来了,他们都会看到相同的page_views
值。另外,由于一致性,您获得的读数可能会过时一分钟。所以,你的1235可能是1278,甚至更大。你知道吗为了避免这么多的写操作,请考虑在memcache中创建计数器,然后增加那里的计数。Memcache跨实例持久存在,值几乎是瞬间变化的。然后,定期将Memcache计数转储到数据存储,并在其中递增,然后将其删除。你知道吗
例如,每当访问者查看post时,增加memcache计数,并在5分钟后设置一个延迟任务,以将计数持久化到数据存储中。这样,你就可以在一个写操作中收集5分钟的视图
Memcache很容易失败,所以您的计数永远不会100%准确。但是,每5分钟左右倾倒一次可以减少误差。你知道吗
相关问题 更多 >
编程相关推荐