【问题标题】:Getting "unable to complete request: one or more nodes were unavailable" when performing insert statement using cqlsh使用 cqlsh 执行插入语句时出现“无法完成请求:一个或多个节点不可用”
【发布时间】:2014-04-11 22:24:10
【问题描述】:

我正在尝试在全新安装的 Cassandra 2 上执行插入操作,虽然我能够很好地设置新的键空间和表,但在尝试执行插入操作时出现上述错误。

我没有任何花哨的多服务器设置,它只是运行一台带有测试数据库的计算机,因此我对节点配置感到困惑

用于创建上述项目的命令是:

CREATE KEYSPACE demodb WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'DC1' : 3 };
USE demodb;
CREATE TABLE users (user_name varchar, state varchar, birth_year bigint, PRIMARY KEY (user_name));
INSERT INTO users (user_name, state, birth_year) VALUES ('canadiancreed', 'PA', 1976);

【问题讨论】:

    标签: cassandra cqlsh


    【解决方案1】:
    CREATE KEYSPACE demodb WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'DC1' : 3 };
    

    很可能是你的罪魁祸首。它说 demodb 键空间中的数据属于 DC1,应该复制 3 次。如果您的单个测试节点未指定为 DC1 的成员,则任何插入此键空间的请求都将失败。此外,如果它是 DC1 的成员并且一致性级别大于 1,则所有请求都会失败,因为写入不可能获得多个确认。

    检查您的数据中心的名称(nodetool 状态)并调整它们的键空间复制详细信息以匹配。这很可能会解决您的问题。

    ---- 编辑以获得更多细节和更好的格式----

    这是新用户使用 Cassandra 时最常见的错误之一。基本上在 Cassandra 中有我们称之为数据中心的硬件逻辑单元。数据中心应该代表一组地理上或以其他方式不同的机器组。您可以进行许多此类操作,并防止在一个地理位置发生故障而导致您的应用程序脱机。

    键空间是用于组织信息组的逻辑结构,它类似于关系世界中的数据库。每个 Keyspace 都可以指定它应该在哪些机器和多少台机器上进行复制。如果我们使用 NetworkTopologyStrategy,则复制是在每个数据中心的基础上指定的。我们使用“CREATE KEYSPACE .... WITH REPLICATION”在创建时指定这些详细信息(尽管它们可以稍后修改)。

    在您的上述声明中,您已指定 Keyspace demodb 中的所有信息都应放置在数据中心“DC1”中,并且该数据中心中应该有 3 个数据副本。这基本上意味着您在 DC1 中至少有 3 个节点,并且您需要每个节点上的数据副本。除非 Cassandra 集群不知道整个数据中心,否则这本身不会导致插入失败。如果您没有对 C* 集群进行初始配置,而只是使用库存 yaml,就会出现这种情况。

    运行 nodetool status 将显示当前节点对集群状态的看法。这是 C* 在我的本地机器上运行的输出。

    Datacenter: Cassandra
    =====================
    Status=Up/Down
    |/ State=Normal/Leaving/Joining/Moving
    --  Address    Load       Owns (effective)  Host ID                               Token                                    Rack
    UN  127.0.0.1  93.37 KB   100.0%            50be3bec-7e30-4385-bd4a-918055a29292  4731866028208108826                      rack1
    

    此输出显示我在名为“Cassandra”的集群中运行了一个节点。这意味着任何需要在其他数据中心复制的键空间的插入都会失败,因为集群不知道如何处理这些请求。 (如果节点只是关闭,但我们在保存提示之前已经看到它们,但如果从未看到其他 DC,我们会拒绝请求,因为集群很可能配置错误。)

    为了解决这种情况,我会修改我的 Keyspace 使用

    cqlsh:demodb> ALTER KEYSPACE demodb WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'Cassandra' : 1 };
    

    现在 demoDB 需要数据中心 Cassandra 中一台机器中的数据副本。这很好,因为我的 nodetool 输出状态是,我在名为 Cassandra 的数据中心中有一个节点。如果我现在尝试插入,它会通过。

    cqlsh:demodb> INSERT INTO users (user_name, state, birth_year) VALUES ('canadiancreed', 'PA', 1976);
    cqlsh:demodb> select * from users where user_name = 'canadiancreed' ;
    
     user_name     | birth_year | state
    ---------------+------------+-------
     canadiancreed |       1976 |    PA
    
    (1 rows)
    

    我会更改我的设置架构脚本以具有正确的数据中心名称

    CREATE KEYSPACE demodb WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'Cassandra' : 1 };
    

    【讨论】:

    • 这就是我做 nodetool 状态时所拥有的。没有看到任何说明键空间代表详细信息的内容。主机ID可能吗?这就是我所拥有的。 -- 地址加载令牌拥有主机 ID 机架 UN 127.0.0.1 132.76 KB 256 100.0% 22d3305d-b09f-4ccf-b61b-8c3ddc12605d rack1
    • 你跳过了关键的第一行Datacenter: Cassandra ===================== Status=Up/Down |/ State=Normal/Leaving/Joining/Moving -- Address Load Owns (effective) Host ID Token Rack UN 127.0.0.1 93.37 KB 100.0% 50be3bec-7e30-4385-bd4a-918055a29292 4731866028208108826 rack1
    • 不用担心。不过,我仍然对我应该看什么感到困惑。
    • 我对原始答案进行了进一步的编辑。但基本上在 cqlsh 中,您创建了一个正在寻找不存在的数据中心的键空间。您要么需要重命名机器所在的数据中心,要么更改该键空间的复制设置。
    • 这对我有用 cqlsh:demodb> 使用复制 = {'class':'NetworkTopologyStrategy', 'datacenter1' : 1} 更改键空间 demodb ;
    【解决方案2】:

    如果您在 Google 搜索后最终出现在此处,我发现如果您使用一致性级别 ALL(具有特定复制因子编号的 QUORUM 也可能是这种情况)和您使用的密钥空间设置为在不存在或已失效的数据中心上复制。

    更新键空间复制以删除对不存在的数据中心的引用解决了该问题。

    (在这种情况下,消息是完全合乎逻辑的:您希望从不再存在的节点获得结果)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-08
      • 2012-12-24
      • 1970-01-01
      • 2017-10-16
      • 2017-02-13
      • 2018-05-08
      • 1970-01-01
      相关资源
      最近更新 更多