4

基本上,我想跟踪的一些指标的一部分是某些对象在我们的营销平台上获得的展示量。如果您想象我们展示了很多对象,我们希望在每次提供对象时进行跟踪。

每个对象都通过单个网关/接口返回给客户端。因此,如果您想象一个请求进入一个带有一些搜索条件的页面,然后搜索请求被代理到我们的 Solr 索引。

然后我们得到 10 个结果。

这 10 个结果中的每一个都应该被视为一个印象。

我正在努力寻找一个令人难以置信的快速和准确的实现。

关于如何做到这一点的任何建议?你可以投入任意数量的技术。我们目前使用的是 Gearman、PHP、Ruby、Solr、Redis、Mysql、APC 和 Memcache。

最终所有的印象最终都应该保存到 mysql 上,我可以每小时做一次。但我不确定如何在不影响实际搜索请求的加载时间的情况下快速将印象存储在内存中。

想法(我刚刚添加了选项 4 和 5)

  1. 一旦结果返回给客户端,客户端就会在我们的平台上请求一个 base64 编码的 URI,该 URI 包含它们所服务的所有对象的 ID。然后将此对象传递给 gearman,然后将计数保存到 redis。每小时一次,redis 被刷新,并且计数是 mysql 中每个对象的增量。

  2. 从 Solr 返回结果后,循环并直接保存到 Redis。(尚未对此进行速度基准测试)。每隔一小时重复一次对 mysql 的刷新。

  3. 从 Solr 返回项目后,将单个作业中的所有 ID 发送给 gearman,然后将其提交给 Redis..

  4. 新想法由于返回的项目数量最多约为 20,我可以设置一个 X-Application-Objects 标头,其中包含返回的 ID 的 base64 标头。然后,这些 ID(在标头中)可以被 nginx 剥离,并使用自定义 LUA nginx 模块,我可以将 ID 从 nginx 直接写入 Redis。不过,这可能有点矫枉过正。这样做的好处是我可以告诉 nginx 在写入 redis 时立即返回响应对象。

  5. 新思路用于fastcgi_finish_request()将请求刷新回 nginx,然后将结果插入 Redis。

  6. 还有其他建议吗?

编辑回答问题:

这些数据的可靠性并不重要。只要是最好的猜测。我不希望看到 30% 的展示次数下降。但我会允许 10% -/+ 的精度。

4

2 回答 2

2

我认为您的两个最佳选择是:

  1. 使用 increment 命令我 redis 在你拉 dis 时增加计数器。使用 Id 作为键并在 Redis 中递增。Redis 每秒可以轻松处理数十万个增量,因此速度应该足够快,不会对客户端产生任何明显的影响。如果 PHP 语言绑定支持它,您甚至可以对每个请求进行管道传输。我认为确实如此。

  2. 使用 redis 作为普通缓存。在此选项中,您只需使用 Redis 列表并执行包含由例如分隔的 ID 的字符串的 rpush。一个逗号。您可以使用一天中的小时作为键。然后,您可以有一个单独的进程通过抓取前一个小时并按您想要的方式将其按摩到 MySQL 中来将其拉出。我希望您在密钥上设置一个过期时间,您可以在一段时间后将它们清除,或者只是通过后处理过程删除密钥。

如果你有非常高的 redis 流量,或者只是想卸载它并获得它的备份作为奖励,你也可以使用读取从属来导出到 MySQL。如果这样做,您可以将主 redis 实例设置为不刷新到磁盘,从而提高写入性能。

有关更广泛地使用 redis 的功能进行此类跟踪的一些其他选项,请参阅此答案您还可以避免 MySQL 部分并从 redis 中提取数据,从而使整个系统更简单。

于 2012-07-14T15:43:22.070 回答
0

我会执行 #2 之类的操作,然后将数据交给您可以更新 Redis 计数器的最快队列。我对 Gearman 不是很熟悉,但我敢打赌这很慢。如果您的 Redis 客户端支持异步写入,我会使用它,或者将它放在单独线程的队列中。您不想在等待更新计数器时减慢响应速度。

于 2012-07-14T02:08:30.583 回答