3

我有一个相当棘手的问题,请耐心等待,因为我尽量不要在这里被我的话绊倒。我正在做一些研究,我的团队正在过渡到 cassandra 数据库。我们的研究以前使用 MySQL,但数据超出了数据库(内存中有 1.92 亿行 @ 16G ——这是查询数据足够快的唯一方法)。数据本身有点静态。它有很多,但在这一点上,任何新数据都是缓慢的涓涓细流。

数据由一大堆分类器分数对组成。我们为数据库制定查询,基本上说,“给我以下分类器的前 500 个”。然后数据库返回那么多分数。例如,如果我们要求 2 个分类器的前 500 个分数,我们会返回 1000 行(每行由一个分类器 ID 和一个分数组成——即 [4, 9100])。分数本身是不均匀的(分布倾向于聚集在值的一端——顺便说一下,从 -10000 到 10000)

当我们过渡到 cassandra 时,有许多要求。首先,我们需要能够在每个分类器的基础上查询前 N 个分数和后 N 个分数。通常我可以看到一个有序的分区器适合这个,但是就像我说的那样,分数往往会聚集在极端情况下(这会给一个节点带来太多的负担)。所以我的第一个问题是,如何在仍然能够查询顶部或底部 N 的同时均匀分布分类器/分数对。

有一个次要要求几乎搞砸了第一个要求。有时有必要找到靠近另一个分数的所有分数。因此,如果我看到分类器 6 的分数为 400,我可能会问,显示最接近该分数的 500 个分数(都在分类器 6 内)。我完全被这个难住了。我读过 cassandra 支持二级索引(耶),但只支持散列类型(嘘 - 无范围)。我们是否为此用例创建单独的 ColumnFamily?

最后,速度是最重要的。数据正在交互式 GUI 应用程序中使用。理想情况下,查询应该只需要几秒钟。如果数据都卡在一个特定的节点上,它会减慢速度。

我们尝试了各种巧妙的技巧。我们最好的想法是将数据放入桶中,这样前 500 条进入桶 1,接下来的 500 条进入桶 2,依此类推。优点是要获得前 500 名,我们只需要存储桶 1。此外,所有数据都将使用随机分区器均匀分布。然而,由于我们的大多数查询只对存储桶 1 感兴趣,因此它只会给一个节点带来很多负担(请记住,如果涉及 N 个分类器,实际上每个存储桶有 500 * N 个分数)。这种方案的真正缺点是,当我们需要根据与分数的接近程度进行查询时,它就会崩溃(我们必须对桶进行某种奇怪的二进制搜索才能找到我们的起始值)。

在这一点上,我们的想法很少。我所看到的关于 cassandra 的一切都让我怀疑它是否适合这项任务。我们选择它主要是因为它的水平可扩展性,这一点很重要(添加节点比分片 RDBM 容易得多)。所以我想我的总体问题是:你将如何处理这个问题?如果是 cassandra,请解决上述任何问题。否则,任何洞察力或智慧都会受到赞赏。谢谢。

4

1 回答 1

3

为什么不将分类器存储为列族行键和列名中的分数。由于列已排序,因此查询给定分类器的前/后 500 列非常快。第二种类型的查询也是可能的,当您查找s附近的分数时,您可以例如选择 s 之前500 列和s之后的 500 列,然后过滤s附近的 500 列。

于 2011-03-16T22:19:40.750 回答