我们有一个包含7个节点的集群,我们使用datastax java驱动程序连接到集群。问题是我得到像这样的常量NoHostAvailableException:
引起: com.datastax.driver.core.exceptions.NoHostAvailableException:全部 尝试查询失败的主机(尝试:/172.31.7.243:9042 (com.datastax.driver.core.exceptions.DriverException:Timeout while 试图获得可用的连接(你可能想要增加 每个主机连接的驱动程序数)),/ 172.31.7.245:9042 (com.datastax.driver.core.exceptions.DriverException:Timeout while 试图获得可用的连接(你可能想要增加 每个主机连接的驱动程序数)),/ 172.31.7.246:9042 (com.datastax.driver.core.exceptions.DriverException:Timeout while 试图获得可用的连接(你可能想要增加 每个主机连接的驱动程序数)),/ 172.31.7.247:9042, /172.31.7.232:9042, / 172.31.7.233:9042,/ 172.31.7.244:9042 [仅限 显示前3个主机的错误,使用getErrors()获取更多详细信息])
所有节点都已启动:
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
任何人都知道如何解决这个问题?或者至少有人暗示如何处理这种情况?
更新:如果我通过.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:[/ 177.31.7.244:9042]操作超时, /172.31.7.245:9042=com.datastax.driver.core.OperationTimedOutException:[/ 177.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]操作超时}
更新
对于删除我使用不同的文件运行它们与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。
以前的每个文件都包含这样的删除:
DELETE FROM keyspace_name.search WHERE idline1 = 837 and idline2 = 841 and partid = 8558 and id = 18c04c20-8a3a-11e5-9e20-0025905a2ab2;
CREATE TABLE搜索( idline1 bigint, idline2 bigint, partid int, id uuid, field3 int, field4 int, field5 int, field6 int, field7 int, field8 int, field9 double, field10 bigint, field11 bigint, field12 bigint, field13 boolean, field14 boolean, field15 int, field16 bigint, field17 int, field18 int, field19 int, field20 int, field21 uuid, field22布尔值, PRIMARY KEY((idline1,idline2,partid),id) )WITH bloom_filter_fp_chance = 0.010000 AND 缓存=' KEYS_ONLY'和 comment ='表格与行之间的snp'和 dclocal_read_repair_chance = 0.000000 AND gc_grace_seconds = 0 AND index_interval = 128 AND read_repair_chance = 0.100000 AND replicate_on_write ='真'和 populate_io_cache_on_flush ='假'和 default_time_to_live = 0 AND speculative_retry =' 99.0PERCENTILE'和 memtable_flush_period_in_ms = 0 AND 压缩= {' class':' SizeTieredCompactionStrategy'} AND 压缩= {' sstable_compression':' LZ4Compressor'};
CREATE INDEX search_partid ON search(partid);
CREATE INDEX search_field8 ON search(field8);
更新(18-03-2016):
删除开始执行后,我发现一些节点的cpu增加了很多:
我检查那些节点上的进程,只有cassandra正在运行,但消耗了大量的cpu。其余的节点几乎没有使用cpu。
更新(04-04-2016):我不知道它是否相关。我检查了许多CPU(接近96%)和gc活动保持在1.6%的节点(仅使用已分配的10个中的3 GB)。
欺骗线程池统计信息:
nodetool tpstats 池名称活动待定已完成阻止所有时间都被阻止 ReadStage 0 0 20042001 0 0 RequestResponseStage 0 0 149365845 0 0 MutationStage 32 117720 181498576 0 0 ReadRepairStage 0 0 799373 0 0 ReplicateOnWriteStage 0 0 13624173 0 0 GossipStage 0 0 5580503 0 0 CacheCleanupExecutor 0 0 0 0 0 AntiEntropyStage 0 0 32173 0 0 MigrationStage 0 0 9 0 0 MemtablePostFlusher 0 0 45044 0 0 MemoryMeter 0 0 9553 0 0 FlushWriter 0 0 9425 0 18 ValidationExecutor 0 0 15980 0 0 MiscStage 0 0 0 0 0 PendingRangeCalculator 0 0 7 0 0 CompactionExecutor 0 0 1293147 0 0 commitlog_archiver 0 0 0 0 0 InternalResponseStage 0 0 0 0 0 HintedHandoff 0 0 273 0 0
消息类型已删除 RANGE_SLICE 0 READ_REPAIR 0 PAGED_RANGE 0 二进制0 阅读0 突变0 _TRACE 0 REQUEST_RESPONSE 0 COUNTER_MUTATION 0
我意识到未决的突变阶段正在增长但活跃值仍然相同,可能是这个问题吗?
答案 0 :(得分:0)
我发现您的数据模型存在两个问题。
您使用两个二级索引。一个是在分区键上的字段上。在这种情况下,我不知道cassandra的行为。最糟糕的情况是,即使您使用完整的分区键(就像您在示例中删除一样),cassandra也会在二级索引中进行查找。在这种情况下,这将意味着完整的群集扫描,因为二级索引仅存储在每个分区中。由于只有一部分分区键被索引,cassandra不知道索引信息位于哪个分区上。这种行为至少可以解释超时。
你说过,你删除了特定分区中的很多行。这也是一个问题。对于每次删除,cassandra都会创建一个墓碑。墓碑越多,读取的速度就越慢。这迟早会导致超时或异常(我相信cassandra会在达到1000个墓碑时发出警告,并在达到10,000个墓碑时抛出异常)。顺便说一句。这些墓碑也在二级索引中创建。默认情况下,执行压缩后,cassandra将在gc_grace_seconds(默认为10天)后删除逻辑删除。您可以为每个表更改此属性。有关这些表属性的更多信息,请访问:Table Properties
我认为第一点可能是超时的原因。