Cassandra NoHostAvailable并且无法打开与Cassandra的本地连接

时间:2017-01-09 18:56:48

标签: apache-spark cassandra

我正在尝试设置cassandra,并且有一些问题,谷歌和其他问题在这里没有帮助。

从cqlsh开始,当我在创建表后尝试查询表时,我得到NoHostAvailable:

Connected to DS Cluster at 10.101.49.129:9042.
[cqlsh 5.0.1 | Cassandra 3.0.9 | CQL spec 3.4.0 | Native protocol v4]
Use HELP for help.
cqlsh> use test;
cqlsh:test> describe kv;

CREATE TABLE test.kv (
    key text PRIMARY KEY,
    value int
) WITH bloom_filter_fp_chance = 0.01
    AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
    AND comment = ''
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
    AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND crc_check_chance = 1.0
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99PERCENTILE';

cqlsh:test> select * from kv;
NoHostAvailable:

根据nodetool启动并运行所有节点。

当我尝试从Spark连接时,我得到类似的东西 - 一切正常我可以操作并连接到表,直到我尝试访问任何数据,然后它失败。

val df = sql.read.format("org.apache.spark.sql.cassandra").options(Map("keyspace" -> "test2", "table" -> "words")).load
df: org.apache.spark.sql.DataFrame = [word: string, count: int]
df.show
org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 1.0 failed 4 times, most recent failure: Lost task 0.3 in stage 1.0 (TID 25, HOSTNAME): java.io.IOException: Failed to open native connection to Cassandra at {10.101.49.129, 10.101.50.24, 10.101.61.251, 10.101.49.141, 10.101.60.94, 10.101.63.27, 10.101.49.5}:9042
    at com.datastax.spark.connector.cql.CassandraConnector$.com$datastax$spark$connector$cql$CassandraConnector$$createSession(CassandraConnector.scala:162)
    at com.datastax.spark.connector.cql.CassandraConnector$$anonfun$3.apply(CassandraConnector.scala:148)
    at com.datastax.spark.connector.cql.CassandraConnector$$anonfun$3.apply(CassandraConnector.scala:148)
    at com.datastax.spark.connector.cql.RefCountedCache.createNewValueAndKeys(RefCountedCache.scala:31)
    at com.datastax.spark.connector.cql.RefCountedCache.acquire(RefCountedCache.scala:56)
    at com.datastax.spark.connector.cql.CassandraConnector.openSession(CassandraConnector.scala:81)
    at com.datastax.spark.connector.rdd.CassandraTableScanRDD.compute(CassandraTableScanRDD.scala:325)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:306)
...
Caused by: java.lang.NoSuchMethodError: com.google.common.util.concurrent.Futures.withFallback(Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/util/concurrent/FutureFallback;Ljava/util/concurrent/Executor;)Lcom/google/common/util/concurrent/ListenableFuture;
    at com.datastax.driver.core.Connection.initAsync(Connection.java:177)
    at com.datastax.driver.core.Connection$Factory.open(Connection.java:731)
    at com.datastax.driver.core.ControlConnection.tryConnect(ControlConnection.java:251)

如果这是一个天真的问题,我道歉,并提前感谢你。

2 个答案:

答案 0 :(得分:2)

NoHostAvailable

Cassandra中的

Replication是通过可在特定键空间指定的两种策略之一完成的。

SimpleStrategy

表示一种天真的方法,并根据每个节点拥有的令牌范围在节点之间全局传播数据。不同数据中心的节点之间没有区别。

SimpleStrategy有一个参数可选择整个群集中存在多少个副本的副本。

NetworkTopologyStrategy

表示每个数据中心复制策略。使用此策略,数据将根据节点拥有的令牌范围进行复制,但仅限于数据中心内。

这意味着,如果您有两个数据中心,其节点为[Token],且整个范围为[0-20]

 Datacenter A : [1], [11]
 Datacenter B : [2], [12]

然后使用简单的策略,范围将被视为像这样分割

[1] [2-10] [11] [12 -20]

这意味着我们最终会得到两个非常不平衡的节点,它们只拥有一个令牌。

如果我们使用NetworkTopologyStrategy,那么责任就像

Datacenter A : [1-10], [11-20]
Datacenter B : [2-11], [12-01]

策略本身可以用字典作为参数来描述,该参数列出了每个数据中心以及该数据中心应该存在多少副本。

例如,您可以将复制设置为

'A' : '1'
'B' : '2'

这将为数据创建3个副本,在B中创建2个副本但在A中仅创建1个副本。

这是许多用户遇到麻烦的地方,因为你可以指定

a_mispelled : '4'

这意味着不存在的数据中心应该具有该特定键空间的副本。然后Cassandra会在对该密钥空间发出请求时响应它无法获取副本,因为它无法找到数据中心。

使用VNodes,您可以通过为不同节点提供不同数量的VNode来获得偏移复制(如果需要)。如果没有VNode,它只需要缩小容量较小的节点所覆盖的范围。

如何读取数据

无论复制如何,都可以从任何节点读取数据,因为映射是完全确定的。给定密钥空间,表和分区密钥,Cassandra可以确定任何特定令牌应存在于哪个节点上,并且只要满足查询的一致性级别就可以获取该信息。

番石榴错误

您最常见的错误来自使用的Spark Cassandra Connector的错误包。使用Java Cassandra驱动程序和Hadoop有困难,因为它们都需要不同(不兼容)的Guava版本。为了解决这个SCC provides builds与SCC番石榴版本的阴影,但重新包括Java驱动程序作为依赖或使用旧版本可能会破坏。

答案 1 :(得分:1)

对我来说,它看起来像两个问题:

对于cqlsh,您似乎错过了配置密钥空间的复制因子。您在那里使用的RF是什么?

See also the datastax documentation.

对于火花问题,似乎某些谷歌番石榴依赖与你的驱动程序不兼容?

在最新的番石榴版本中,有一个API更改。见

java.lang.NoClassDefFoundError: com/google/common/util/concurrent/FutureFallback