cassandra中的主键和索引

Posted

技术标签:

【中文标题】cassandra中的主键和索引【英文标题】:Primary key and indexing in cassandra 【发布时间】:2014-10-22 11:36:33 【问题描述】:

cassandra 新手,仍在学习中。

create table url (
  id_website int,
  url varchar,
  data varchar,
  primary key(url, id_website)
);

您好,我有一个网站的网址表。

我不希望所有的 url 都在同一个节点上,这就是为什么主键是 url 首先,所以它将是分区键。

大部分时间我会检索特定 url 的数据,例如:“url = ? and id_website = ?”

但是,当我想检索网站的部分/全部 url 时,性能如何:

select * from url where id_website = 1 allow filtering limit XX;

我认为这个查询将在所有节点上分派,然后,表扫描 id_website= 1 直到达到限制,然后合并并发回我的客户端。

但是这种扫描是要使用索引并且是有效的,还是会一一读取 id_website 列的值并进行比较(这样无效)?我确实设置了主键的 id_website 部分,所以我希望它被索引,但我真的不知道。

我们在 cassandra 上是否有一些工具,例如 mysql 的 EXPLAIN 来检查查询是否使用索引。

谢谢。

--

编辑

使用 id_website 作为分区键创建第二个表(以及 批量写入/删除)

我不想使用这个解决方案,因为我可能有一两个非常庞大的网站,并且有数百万个网址(还有数百万个网址很少的其他网站)。

如果我在 id_website 上有一个分区键,并且这两个或三个网站位于同一个节点上,则可能会导致存储问题,或者处理这些网站的节点可能被请求过多,而另一个则一无所获。我想将数据分布在所有节点上。所以我坚持要对url进行分区。

您在 id_website 上创建了一个二级索引(它为 你)

这个解决方案怎么样?如果我理解的话,每个节点都会有一个表来索引它基于 id_website 存储的行(而不是其他节点的行)。所以我可以将我的 url 分布在许多节点上,我不会让一个节点处理包含特定网站所有 url 的大型索引。

现在当我使用我的查询时

select * from url where id_website = 1 allow filtering limit XX;

每个节点都接收到查询,但这次不必循环遍历分区(url列),它们可以直接在索引中查找属于id_website的url,并返回行(或不返回)。对吧?

这个解决方案的反面是每次请求完成时,它都会到达每个节点,但是,由于新的索引,它应该很快?

【问题讨论】:

【参考方案1】:

你是在正确的方式。使用允许过滤您只是要求 cassandra 扫描所有节点:非常无效。 id_website 在每个分区中都有索引,但是由于您没有告诉 Cassandra 去哪里,他必须访问所有分区(所有节点),即使是那些不包含所选 id_website 信息的分区 - 一旦 Cassandra 访问分区就知道如何查找此信息,无需扫描整个分区即可取回数据。

要在 Cassandra 中解决此问题,您必须进行非规范化,在这种情况下,您可以通过两种可能的方式来解决:

    使用 id_website 作为分区键创建第二个表(并批量写入/删除) 您在 id_website 上创建二级索引(它会为您创建一个表)

**因问题编辑**

你说的没错:二级索引作为“本地索引”处理——每个节点只为它拥有的数据创建一个本地索引表。以下是关于二级索引的good reading(你已经了解了)

创建索引后,您必须从查询中删除 ALLOW FILTERING

HTH, 卡罗

【讨论】:

所以你告诉我在这种情况下接收查询的节点上不会使用 id_website 索引。它只会在我做 url=x 和 id_website=y 的情况下使用,对吗? 我告诉你,如果你有 3000 个分区用于“url”表,其中 1000 个包含 id_website=1 的信息,cassandra 将查询所有 3000 个分区,其中 2000 个将以空值回复剩余 1000 个不会“扫描”分区,因为 id_website 在分区内被索引。 如果“url”表有 3000 个分区,其中 1000 个包含 id_website=1 的信息,cassandra 将查询所有 3000 个分区。 -> 好的,我想我明白了,就像在 mysql 中一样,如果你有一个主键 (foo,bar) 你不能使用 bar 索引而不使用 foo 之前。 -> 所以 Cassandra 会扫描所有分区(url)并为每个 url 使用 id_website 索引,但它是无效的,因为它必须先扫描分区?所以是的,我们使用索引,但它没有效果。 谢谢@Carlo 我改进了我的问题,如果你能看一下。 嗯,我正在为我的下一个软件寻找存储,我首先深入研究 cassandra,然后是 hbase(我想要宽列、可扩展的存储)。我想知道事情是如何工作的,并且对于分布式宽列存储,我认为在构建/非规范化模式时了解事情在后台如何工作非常重要。幸运的是,有很多关于 Cassandra 内部技术细节的博客。感谢您的链接,它准确地解释了我对缩放和索引的想法。

以上是关于cassandra中的主键和索引的主要内容,如果未能解决你的问题,请参考以下文章

cassandra中的主键是唯一的吗?

尝试使用 C# 中的 Guid 作为 Cassandra 中的主键

Cassandra 简单的主键查询

使用键和索引进行 Cassandra 建模

Cassandra 数据如何更新

Cassandra 学习七 cassandra研究