【问题标题】:Cassandra query table without partition key没有分区键的 Cassandra 查询表
【发布时间】:2020-03-03 05:50:44
【问题描述】:

作为迁移作业的一部分,我正在尝试从表中提取数据。

架构如下:

CREATE TABLE IF NOT EXISTS ${keyspace}.entries (
    username text,

    entry_type int,

    entry_id text,

    PRIMARY KEY ((username, entry_type), entry_id)
);

为了查询表,我们需要分区键,即主键的第一部分。 因此,如果我们知道usernameentry_type,我们就可以查询该表。

在这种情况下,username 可以是任意值,但 entry_type 是 0-9 范围内的整数。

在提取时,我们为每个用户名迭代表 10 次,以确保我们尝试所有版本的 entry_type

由于用户名列表已用完,我们再也找不到任何条目。但我们的nodetool tablestats 报告说,表中仍有数据,甚至数千兆字节。因此,我们假设该表不为空。

但我找不到检查表格以找出表格中剩余的用户名的方法。如果我可以检查它,我可以将表中留下的用户名添加到我们的提取作业中,最终我们可以耗尽表。但我不能像这样简单地查询表:

SELECT * FROM ${keyspace}.entries LIMIT 1

因为 cassandra 需要分区键才能进行有意义的查询。

我能做些什么来弄清楚我们的桌子上还剩下什么?

【问题讨论】:

  • 在“提取过程”中,您是否删除了找到的条目?我试图了解您为什么不希望检索数据。如果您正在删除记录,您是否考虑 GC 宽限期(gc_grace_seconds 设置)这将在删除执行和实际从系统中删除记录之间产生延迟
  • 是的,对于我们找到的每条记录,我们将它们插入到另一个表中,然后从相关表中删除它们。

标签: cassandra cql


【解决方案1】:

根据评论,迁移过程包括从 Cassandra 表中删除操作,但引擎在实际从磁盘中删除受影响的记录之前会有延迟;此过程由墓碑和表的gc_grace_seconds 属性在内部控制。这个延迟的原因在这个blog entry 中有充分的解释,对于一个tl dr,如果默认值仍然存在,Cassandra 将需要在实际执行删除之前至少经过 10 天(864,000 秒)删除数据。

对于您的情况,一种方法是:

  1. 确保所有节点都“正常”且“正常” (UN)
  2. 减少你的表的gc_grace_seconds属性,在例子中,它会设置为1分钟,而默认是

    GC_GRACE_SECONDS = 60 的 ALTER TABLE .entries;

  3. 手动压缩表格:

    nodetool 压缩条目

  4. 该过程完成后,nodetool tablestats 应该是最新的

【讨论】:

    【解决方案2】:

    为了回答您的第一个问题,我想进一步说明 gc_grace_seconds 属性。

    在 Cassandra 中,数据不会像在 RDBMS 中那样被删除。 Cassandra 专为高写入吞吐量而设计,并避免了先读后写。所以在 Cassandra 中,删除实际上是更新,而更新实际上是插入。 “墓碑” 标记被写入以指示数据现在(逻辑上)被删除(也称为软删除)。必须删除标记为墓碑的记录才能收回存储空间。这是由一个名为Compaction 的过程完成的。但请记住,只有在称为 gc_grace_seconds 的特定秒数之后,墓碑才有资格进行物理删除/垃圾收集。这是一个非常好的博客,可以详细阅读:https://thelastpickle.com/blog/2016/07/27/about-deletes-and-tombstones.html

    现在您可能正在查看 gc_grace_seconds 之前的表大小,并且数据仍然存在。

    谈到第二个问题,您希望在不提供分区键的情况下从表中获取一些样本。您可以使用 Spark 分析表格内容。 Spark Cassandra 连接器允许您创建使用 Spark 分析数据库数据的 Java 应用程序。您可以按照文章/文档编写一个快速方便的 Spark 应用程序来分析 Cassandra 数据。

    https://www.instaclustr.com/support/documentation/cassandra-add-ons/apache-spark/using-spark-to-sample-data-from-one-cassandra-cluster-and-write-to-another/

    https://docs.datastax.com/en/dse/6.0/dse-dev/datastax_enterprise/spark/sparkJavaApi.html

    我建议您在进行迁移时不要删除记录。而是首先完成迁移并发布快速验证/验证以确保成功迁移所有记录(使用 Spark 购买比较旧表和新表中的数据帧可以轻松完成此用途)。发布成功验证后会截断旧表,因为 truncate 不会创建墓碑,因此效率更高。请注意,大量的墓碑不利于集群健康。

    【讨论】:

    • 我去看看spark!至于实际的迁移任务;它有两个阶段,或者如果你愿意的话,有两个迭代。首先它插入到新表中,然后在第二遍中,当它在新表中找到匹配项时,它从旧表中删除。每次我们运行任务时,我们必须迁移的数据集都会缩小,它会找到新的迁移对象。我们的想法是,这将有助于加快进程,因为我们假设我们必须多次运行任务,因为 Cassandra 是部分一致的。不过,还是非常感谢您的建议。
    猜你喜欢
    • 1970-01-01
    • 2015-02-01
    • 1970-01-01
    • 2021-10-30
    • 2016-05-11
    • 2017-08-13
    • 1970-01-01
    • 2016-06-04
    相关资源
    最近更新 更多