Redis集的替代品

时间:2012-09-06 02:46:21

标签: database-design nosql redis relational-database

为了进行设置,我有一家公司,我们有一些用户和一组标签来描述这些用户。 每个用户最多可以附加5000个标签。

我们有一个引擎,允许客户选择某些标签来制作标签组。引擎具有AND / Or功能和Include / Exclude。客户端可以创建标记组,我们的引擎会查找满足标记组中指定的逻辑要求的用户总数。基本上这只是交叉点,工会和排除,所以redis集合是完美的。

为了解决这个问题,我将数据存储起来。 Tag1:[user1,user2,user3] Tag2:[user1,user5,user6] 等

从这里开始,所有bool逻辑都是使用脚本完成的。

然而,我们的客户群正在快速扩张。在几年内,我们将需要几个64GB redis服务器或替代服务器。

这是我的问题。是否存在基于磁盘的交叉和联合的快速数据库选项?我试过Postgres,但性能是不可接受的。例如,500k用户集的集合比较需要1秒。在Postgres中,我看到大约30秒,如果标签组中有很多标签,我会看到更多。

我已经推荐过DynamoDB和其他一些人,但在挖掘太深之前只是想要一些受过教育的意见。

谢谢, 丹

3 个答案:

答案 0 :(得分:4)

Redis是获得快速交叉路口和工会的最佳方式。您可以做一些事情来限制Redis使用的内存:

使用IntSets

在内部,Redis使用数据结构IntSets。这是一个整数的排序数组。要在此集合中查找整数,复杂度为O(log N)。 IntSet有三种版本--16位,32位和64位。

从内存的角度来看,Int Sets非常优秀。如果您正在使用集合并关心内存,则应确保使用Int Sets。

要利用Int Sets,您需要做两件事 -

  1. 确保集合包含整数。如果您的用户ID是字符串,则必须稍微更改逻辑以使其成为整数。
  2. 在redis.conf中,将设置set-max-intset-entries更新为合理的数字。这将是给定标记的最大用户数。请注意,将其增加到一个点以上实际上会降低性能。
  3. 将用户对象移动到另一个商店

    这些集只需要用户ID,它们不需要整个用户对象。因此,如果内存成为约束,您还可以将User对象移动到另一个数据存储。也许是另一台Redis服务器,甚至是关系数据库。这种方法为您提供了两全其美的优势。

答案 1 :(得分:3)

“Lightning fast DB”和“基于磁盘”并不真正兼容。最快的商店是内存商店。

除了使用intset之外,另一种可能的优化是将集合表示为位图。这一切都取决于数据的基数,但假设用户数量增长的速度快于标签数量,那么每个标签有一个位图可能会很有趣。在位图中,给定位由用户的数字ID索引。

Redis 2.6正为此目的支持SETBITBITOPBITCOUNT操作。

每个用户一位,500K用户少于64K,乘以全局标签数。我怀疑你会发现它比使用intset更紧凑。

答案 2 :(得分:0)

很抱歉对这么老的问题发表评论。

我确定速度不会像redis一样低,但是我想提一下2个postgres功能,这些功能都在'标签'和'标签组'

Ltree是一种用于创建类别层次结构的方便语法:(支持全文搜索) http://www.postgresql.org/docs/9.1/static/ltree.html

和(我没有用过)hstore是一个标签实现 http://www.postgresql.org/docs/9.0/static/hstore.html

我相信如果你对如何使用这些工具很聪明(并构建正确的索引),你应该能够将查询时间缩短到合理的值。