高效的分布式计数

时间:2013-08-26 20:59:03

标签: algorithm distributed counting hyperloglog

我有一系列事件流经系统(例如披萨订购系统),我想要计算每个事件的某些属性。例如,我可能想看看有多少独特的人在过去5分钟内订购了意大利辣香肠披萨,或者过去一周有多少披萨John Doe订购了。

这是很多事件,所以我们使用像Cassandra或HBase这样的东西,因为即使计数也不能存储在内存中。此外,由于我们需要跟踪集合成员资格(例如,为了统计排序特定种类披萨的独特人物),它会变得更大。

我们可以存储订单列表然后查询计数,但这很慢。我们大多不关心订购意大利辣香肠披萨,只是在特定时间窗口内制作了多少唯一订单。

存储此信息的最佳方式是什么,例如在Cassandra中,以便可以在某些时间间隔内检索信息?

我首先尝试使用Redis + bloom过滤器,但是存储bloom过滤器位向量需要事务以避免竞争条件,因此我使用了redis集。

然后我意识到整个事情太大而不能只是在内存中,所以我决定切换到磁盘支持的商店。但是,没有像redis那样的原生集。

我查看了像HyperLogLog这样的草图/流式算法,但结论是为了保存hyperloglog对象,我需要存储位数组(或者腌制对象或其他)...是犹太洁食,什么是最好的如果这确实是解决方案,那么这样做是什么?

我很想用时间戳单独保存每个事件,然后查询并按需计数,但这很慢。如果它存在,我正在寻找更好的东西。

示例请求:

  • 过去10分钟有多少独特的人有意大利辣味香肠披萨订单
  • 在过去的30分钟内,一些人John Doe订购了多少独特的意大利辣香肠披萨

2 个答案:

答案 0 :(得分:1)

根据我的学习,有几种方法可以解决这个问题。

  1. 使用锁定+设置成员资格/计数数据结构,例如hyperloglog或bloom过滤器。只要没有那么多针对特定锁的战斗,事情应该没问题。
  2. 使用具有内置集/集合支持的数据库。他们几乎在内部实施#1。

答案 1 :(得分:0)

我的猜测:

  • cassandra支持计数器 - 我想我看到了一些应该同时工作的incr操作 - 通过在你的事件上使用自由运行计数器,你只需要设置一些东西,以指定的间隔(5分钟?)对所有计数器进行采样然后你可以给两个样本之间的估计 (http://wiki.apache.org/cassandra/Counters
  • cassandra可以超时列..我从未真正使用它,但它可能值得一试