Cassandra Cluster无法通过Spark查看节点

时间:2016-08-17 14:23:11

标签: scala apache-spark cassandra apache-spark-sql spark-cassandra-connector

我正在尝试通过Spark进行写入。 我的集群中有6个节点,在其中我创建了我想要写入数据的密钥空间:

CREATE KEYSPACE traffic WITH replication = {'class': 'SimpleStrategy',    'replication_factor': '2'}  AND durable_writes = true;

当我尝试从Spark编写时,我遇到了这种错误:

16/08/17 16:14:57 ERROR QueryExecutor: Failed to execute:  com.datastax.spark.connector.writer.RichBatchStatement@7409fd2d
com.datastax.driver.core.exceptions.UnavailableException: Not enough replicas available for query at consistency ONE (1 required but only 0 alive)

这是代码片段我正在做什么:

import org.apache.spark.sql.SQLContext
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark
import org.apache.spark.storage.StorageLevel
import org.apache.spark.sql.types.{StructType, StructField, DateType,  IntegerType};




object ff {
def main(string: Array[String]) {

val conf = new SparkConf()
  .set("spark.cassandra.connection.host", "127.0.0.1")
  .set("spark.cassandra.connection.host","ONE")
  .setMaster("local[4]")
  .setAppName("ff")

val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)

val df = sqlContext.read
  .format("com.databricks.spark.csv")
  .option("header", "true") // Use first line of all files as header
  .option("inferSchema", "true")
  .load("test.csv")

df.registerTempTable("ff_table")
//df.printSchema()

df.count
time {
  df.write
    .format("org.apache.spark.sql.cassandra")
    .options(Map("table" -> "ff_table", "keyspace" -> "traffic"))
    .save()
}
def time[A](f: => A) = {
  val s = System.nanoTime
  val ret = f
  println("time: " + (System.nanoTime - s) / 1e6 + "ms")
  ret
}



 }
}

另外,如果我运行nodetool describecluster,我得到了这个结果:

Cluster Information:
Name: Test Cluster
Snitch: org.apache.cassandra.locator.DynamicEndpointSnitch
Partitioner: org.apache.cassandra.dht.Murmur3Partitioner
Schema versions:
    bf6c3ae7-5c8b-3e5d-9794-8e34bee9278f: [127.0.0.1, 127.0.0.2, 127.0.0.3, 127.0.0.4, 127.0.0.5, 127.0.0.6]

我尝试在replication_factor:2的行中插入CLI并且它正在工作,因此每个节点都可以看到对方。 为什么Spark不能插入任何东西,为什么节点在尝试从Spark插入数据时无法看到对方,任何人都有想法?

1 个答案:

答案 0 :(得分:2)

看起来你通过环回在一台机器上运行了6个节点。这意味着很有可能该机器的资源被过度订阅。各种Cassandra实例最有可能轮流或交换,导致它们在重负载下丢失。增加复制因子会增加有效目标启动的可能性,但会进一步增加负载。

C *需要它的核心来自你的系统的几个不同的资源,如果这些中的任何一个成为瓶颈,那么任何一个节点都有可能在足够的时间内不响应八卦。

这些资源是    RAM - JVM能够获取多少内存,这也受操作系统交换的影响。这意味着如果您分配大型JVM但操作系统将其交换到磁盘,则可能会出现大量性能问题。如果同一台机器上有多个节点,则需要确保每个节点的JVM都有足够的内存。此外,如果任何一个实例的JVM接近完全,您将进入GC并可能进入GC Storm,这将基本上锁定该实例。其中许多细节将在system.log中明确。

CPU - 如果没有对至少一个cpu的独占访问权限,几乎可以保证在C *中安排一些重要的线程,它们之间会有很长的延迟。这可能会导致八卦线程被忽略而八卦会失败。这将为一些节点提供具有故障机器的集群的视图,并导致不可用的错误。

DISK - 每个Cassandra实例都将维护自己的CommitLog和HD文件。提交日志每10秒刷新一次,如果你有多个实例,只有1个硬盘,则commitlog和普通memtables之间的刷新可以很容易地相互阻塞。压缩需要另外大量的IO,这进一步加剧了这一点。

NETWORK - 虽然这不是同一台机器上多个节点的问题。

总之,   确保分配给C *实例的资源足够小,以防任何实例都不会超出另一个实例的空间/ ram / cpu,这一点很重要。如果这样做,您将最终得到一个群集,其在负载下通信失败,因为上述资源之一是瓶颈。这并不意味着在同一台机器上运行多个节点是不可能的,但这意味着您必须注意配置。您还可以尝试通过限制写入速度来减轻负载,从而减少节点相互破坏的可能性。