【问题标题】:Even partitioning of nonuniform ranged data in cassandracassandra中非均匀范围数据的均匀分区
【发布时间】:2011-07-16 19:19:41
【问题描述】:

我有一个相当棘手的问题,请耐心等待,因为我尽量不要在这里被我的话绊倒。我正在做一些研究,我的团队正在过渡到 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,请解决上述任何问题。否则,任何洞察力或智慧都会受到赞赏。谢谢。

【问题讨论】:

    标签: database database-design cassandra cassandra-0.7


    【解决方案1】:

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

    【讨论】:

    • 如果我错了,请纠正我,但是您是否建议将给定分类器的所有分数存储在一行下?我认为(也许是错误的)cassandra 对它可以容纳的列数有限制。每个分类器现在将有大约 200 万个与之相关的分数。 200 万个分数,每个分数都表示为自己的列,查找起来仍然很快吗?
    • 从 0.7 版开始,每行最多可以存储 20 亿列。我做了一些测试,读取性能很好。好吧,这对我的需求很有好处,而且只有 ~100000 列。
    • 嗯,我得试试看!非常感谢您的洞察力,非常感谢。
    • 只是对此的更新,我们已经按照您的描述实现了它,与我们的内存数据库实现相比,性能是惊人的。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多