【问题标题】:Cassandra NoHostAvailableException when deletes are executed with cqlsh使用 cqlsh 执行删除时出现 Cassandra NoHostAvailableException
【发布时间】:2016-06-30 12:49:34
【问题描述】:

我们有一个包含 7 个节点的集群,我们使用 datastax java 驱动程序连接到集群。问题是我得到了像这样的常量 NoHostAvailableException:

原因: com.datastax.driver.core.exceptions.NoHostAvailableException:全部 尝试查询的主机失败(尝试:/172.31.7.243:9042 (com.datastax.driver.core.exceptions.DriverException:超时而 尝试获取可用连接(您可能需要增加 每个主机连接的驱动程序数)),/172.31.7.245:9042 (com.datastax.driver.core.exceptions.DriverException:超时而 尝试获取可用连接(您可能需要增加 每个主机连接的驱动程序数)),/172.31.7.246:9042 (com.datastax.driver.core.exceptions.DriverException:超时而 尝试获取可用连接(您可能需要增加 每个主机连接的驱动程序数)),/172.31.7.247:9042, /172.31.7.232:9042, /172.31.7.233:9042, /172.31.7.244:9042 [仅 显示前 3 个主机的错误,使用 getErrors() 了解更多详细信息])

所有节点都up了:

UN  172.31.7.244  152.21 GB  256     14.5%  58abea69-e7ba-4e57-9609-24f3673a7e58  RAC1
UN  172.31.7.245  168.4 GB   256     14.5%  bc11b4f0-cf96-4ca5-9a3e-33cc2b92a752  RAC1
UN  172.31.7.246  177.71 GB  256     13.7%  8dc7bb3d-38f7-49b9-b8db-a622cc80346c  RAC1
UN  172.31.7.247  158.57 GB  256     14.1%  94022081-a563-4042-81ab-75ffe4d13194  RAC1
UN  172.31.7.243  176.83 GB  256     14.6%  0dda3410-db58-42f2-9351-068bdf68f530  RAC1
UN  172.31.7.233  159 GB     256     13.6%  01e013fb-2f57-44fb-b3c5-fd89d705bfdd  RAC1
UN  172.31.7.232  166.05 GB  256     15.0%  4d009603-faa9-4add-b3a2-fe24ec16a7c1  RAC1

但其中两个 CPU 负载很高,尤其是 232,因为我在该节点中使用 cqlsh 运行了很多删除操作。

我知道删除会生成墓碑,但是集群中有 7 个节点,我认为所有主机都无法访问是不正常的。

我们对java连接的配置是:

com.datastax.driver.core.Cluster cluster = null;
        //Get contact points
        String[] contactPoints=this.environment.getRequiredProperty(CASSANDRA_CLUSTER_URL).split(",");
        cluster = com.datastax.driver.core.Cluster.builder()
            .addContactPoints(contactPoints))
            .withCredentials(this.environment.getRequiredProperty(CASSANDRA_CLUSTER_USERNAME), 
                this.environment.getRequiredProperty(CASSANDRA_CLUSTER_PASSWORD))
                .withQueryOptions(new QueryOptions()
                .setConsistencyLevel(ConsistencyLevel.QUORUM))
                .withLoadBalancingPolicy(new TokenAwarePolicy(new RoundRobinPolicy()))
                .withRetryPolicy(new LoggingRetryPolicy(DowngradingConsistencyRetryPolicy.INSTANCE))
                .withPort(Integer.parseInt(this.environment.getRequiredProperty(CASSANDRA_CLUSTER_PORT)))
                .build();

        Metadata metadata = cluster.getMetadata();
        for ( Host host : metadata.getAllHosts() ) {
            LOG.info("Datacenter: "+host.getDatacenter()+"; Host: "+host.getAddress()+"; DC: "+host.getDatacenter()+"\n");
        }

联络点是:

172.31.7.244,172.31.7.243,172.31.7.245,172.31.7.246,172.31.7.247

有人知道我该如何解决这个问题吗?或者至少有人对如何处理这种情况有一些提示?

更新:如果我得到错误消息 withe.getErrors() 我会得到:

/172.31.7.243:9042=com.datastax.driver.core.OperationTimedOutException: [/172.31.7.243:9042] 操作超时, /172.31.7.244:9042=com.datastax.driver.core.OperationTimedOutException: [/172.31.7.244:9042] 操作超时, /172.31.7.245:9042=com.datastax.driver.core.OperationTimedOutException: [/172.31.7.245:9042] 操作超时, /172.31.7.246:9042=com.datastax.driver.core.OperationTimedOutException: [/172.31.7.246:9042] 操作超时, /172.31.7.247:9042=com.datastax.driver.core.OperationTimedOutException: [/172.31.7.247:9042] 操作超时}

更新:

  • 键空间的复制因子为 3。
  • 对于删除,我使用带有 cql 查询的不同文件运行它们:

    cqlsh ip_node_1 -f script-1.duplicates cqlsh ip_node_1 -f script-2.duplicates cqlsh ip_node_1 -f script-3.duplicates ...

  • 我没有指定任何一致性级别,因此使用默认级别 ONE。

  • 之前的每个文件都包含这样的删除:

从 keyspace_name.search 中删除,其中 idline1 = 837 和 idline2 = 841 和 partid = 8558 和 id = 18c04c20-8a3a-11e5-9e20-0025905a2ab2;

  • 列族是:

创建表搜索 ( idline1 大整数, idline2 bigint, 部分整数, id uuid, 字段3 int, field4 整数, field5 整数, field6 整数, field7 整数, field8 整数, field9 双, field10 大整数, field11 大整数, field12 bigint, field13 布尔值, field14 布尔值, field15 整数, field16 大整数, field17 整数, field18 整数, field19 整数, field20 整数, 字段21 uuid, field22 布尔值, 主键((idline1,idline2,partid),id) ) 和 bloom_filter_fp_chance=0.010000 和 缓存='KEYS_ONLY' 和 注释='表与行之间的 snp' 和 dclocal_read_repair_chance=0.000000 和 gc_grace_seconds=0 和 index_interval=128 和 read_repair_chance=0.100000 和 复制_on_write ='真'和 populate_io_cache_on_flush='false' AND default_time_to_live=0 和 speculative_retry='99.0PERCENTILE' AND memtable_flush_period_in_ms=0 和 compaction={'class': 'SizeTieredCompactionStrategy'} AND 压缩={'sstable_compression': 'LZ4Compressor'};

CREATE INDEX search_partid ON search (partid);

CREATE INDEX search_field8 ON search (field8);

更新(2016 年 3 月 18 日):

delete开始执行后,我发现一些节点的cpu增加了很多:

我检查了那些节点上的进程,只有 cassandra 正在运行,但消耗了大量的 cpu。其余节点几乎没有使用cpu。

UPDATE (04-04-2016):我不知道这是否相关。我检查了很多 CPU(接近 96%)和 gc 活动保持在 1.6% 的节点(仅使用已分配的 10 个中的 3 GB)。

查看线程池统计信息:

nodetool tpstats 池名称 Active Pending Completed Blocked All time Blocked 读取阶段 0 0 20042001 0 0 请求响应阶段 0 0 149365845 0 0 突变阶段 32 117720 181498576 0 0 读取修复阶段 0 0 799373 0 0 ReplicateOnWriteStage 0 0 13624173 0 0 八卦舞台 0 0 5580503 0 0 缓存清理执行器 0 0 0 0 0 反熵阶段 0 0 32173 0 0 迁移阶段 0 0 9 0 0 MemtablePostFlusher 0 0 45044 0 0 内存表 0 0 9553 0 0 FlushWriter 0 0 9425 0 18 验证执行器 0 0 15980 0 0 杂项阶段 0 0 0 0 0 待定范围计算器 0 0 7 0 0 压实执行器 0 0 1293147 0 0 commitlog_archiver 0 0 0 0 0 内部响应阶段 0 0 0 0 0 提示切换 0 0 273 0 0

消息类型已删除 RANGE_SLICE 0 READ_REPAIR 0 PAGED_RANGE 0 二进制 0 读 0 突变 0 _跟踪 0 请求响应 0 COUNTER_MUTATION 0

我意识到待定突变阶段正在增长,但活动值保持不变,这可能是问题所在吗?

【问题讨论】:

  • 你能显示你执行删除的键空间吗?您使用的是什么复制因子?
  • delete 语句的示例也可能会有所帮助。
  • 你的删除操作的一致性级别是多少?
  • 我已经用 cmets 中要求的所有信息更新了问题的描述
  • 您对每个分区执行了多少次删除?那么,例如,您对“idline1 = 837 and idline2 = 841 and partid = 8558”上的元素执行了多少次删除?每个分区存储多少行?另外,您在另一个表上创建的索引(snpsearch?)还是这是复制/粘贴错误并且属于搜索?

标签: cassandra datastax-java-driver


【解决方案1】:

我发现您的数据模型存在两个问题。

  • 您使用了两个二级索引。一个在分区键上的字段上。我不知道 cassandra 在这种情况下的表现如何。最坏的情况是,即使您使用完整的分区键(就像您在示例删除中所做的那样),cassandra 也会在二级索引中进行查找。在这种情况下,这将意味着完整的集群扫描,因为二级索引仅存储在每个分区中。由于只有分区键的一部分被索引,cassandra 不知道索引信息位于哪个分区。这种行为至少可以解释超时。

  • 您说,您删除了特定分区中的很多行。这也是一个问题。对于每个删除,cassandra 都会创建一个墓碑。墓碑越多,读取速度就越慢。这迟早会导致超时或异常(我相信 cassandra 会在达到 1000 个墓碑时写入警告,并在达到 10.000 个墓碑时抛出异常)。顺便提一句。这些墓碑也在二级索引中创建。默认情况下,cassandra 将在 gc_grace_seconds(默认为 10 天)执行压缩时删除墓碑。您可以更改每个表的此属性。可以在此处找到有关这些表属性的更多信息:Table Properties

我认为第一点可能是超时的原因。

【讨论】:

  • 关于索引,我将删除索引并检查是否有所改善。这是模型中的错误,我们首先考虑使用二级索引,最后我们决定将其包含在分区键中。就墓碑而言,我们已将这些 cf 的 gc_grace_seconds 配置为零,以避免在删除期间生成墓碑。
  • @ftrujillo 只是一个旁注:仍然会生成墓碑,但每次压缩都会删除它们。
  • @hashtagmarkus感谢您的澄清。无论如何,我还尝试在执行了一些删除操作后运行压缩,以在继续删除结果之前删除墓碑。
  • 我已删除索引并再次开始执行删除操作,几分钟后我遇到了同样的问题。更新了我的问题。
猜你喜欢
  • 1970-01-01
  • 2017-10-16
  • 1970-01-01
  • 2015-12-22
  • 2015-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-15
相关资源
最近更新 更多