【问题标题】:Cassandra NoHostAvailable and Failed to open native connection to CassandraCassandra NoHostAvailable 并且无法打开到 Cassandra 的本机连接
【发布时间】:2017-01-10 06:50:37
【问题描述】:

我正在尝试设置 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)

如果这是一个幼稚的问题,我深表歉意,并提前感谢您。

【问题讨论】:

  • 对于 cqlsh,您可能遇到了 RF 错误。我的猜测是密钥空间不会在您所在的节点上复制。对于第二个错误,它看起来像是 guava 的依赖错误,通常这意味着您使用了错误的 Spark Cassandra 连接器包。
  • 感谢 Russ,RF 修复成功了。我原以为 cassandra 会让每个节点上的每个键空间都可用,但是像 hadoop 一样分发数据?有什么需要调整的吗?
  • 默认策略“SimpleStrategy”将数据放在所有节点上,但不建议在生产环境中使用。 “NetworkTopologyStrategy”指定应在哪些数据中心复制数据。但是,数据中心名称与集群中的数据中心匹配很重要。
  • @RussS 如果你把这个作为答案,我会接受它是正确的......但如果你能向我解释更多关于这个神秘的复制策略的事情,我也会非常感激......我只是希望数据在复制不完善的节点(如 hadoop)之间拆分,但也能够从任何节点访问任何内容。我只有一个数据中心、一个集群、一个机架。

标签: apache-spark cassandra


【解决方案1】:

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 来获得倾斜复制(如果需要)。如果没有 VNodes,它只需要缩小容量较小的节点所覆盖的范围。

如何读取数据

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

番石榴错误

您最常看到的错误来自使用了错误的 Spark Cassandra 连接器包。使用 Java Cassandra 驱动程序和 Hadoop 存在困难,因为两者都需要不同(不兼容)的 Guava 版本。为了解决这个问题,SCC provides builds 带有 SCC guava 版本的阴影,但重新包含 Java 驱动程序作为依赖项或使用旧版本可能会破坏事情。

【讨论】:

    【解决方案2】:

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

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

    See also the datastax documentation.

    对于 spark 问题,似乎某些 google guava 依赖项与您的驱动程序不兼容?

    在最新的 guava 版本中,API 发生了变化。见

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

    【讨论】:

      猜你喜欢
      • 2015-09-04
      • 2020-08-16
      • 1970-01-01
      • 2021-08-04
      • 2017-12-26
      • 2019-08-20
      • 2016-06-14
      • 1970-01-01
      • 2015-01-23
      相关资源
      最近更新 更多