【问题标题】:UnavailableException() in Apache-Cassandra 0.8.2Apache-Cassandra 0.8.2 中的 UnavailableException()
【发布时间】:2011-10-24 02:16:03
【问题描述】:

我是 Apache-Cassandra 0.8.2 的新手。我正在尝试插入一些数据,但收到此异常。

线程“主”中的异常 UnavailableException() 在 org.apache.cassandra.thrift.Cassandra$insert_result.read(Cassandra.java:14902) 在 org.apache.cassandra.thrift.Cassandra$Client.recv_insert(Cassandra.java:858) 在 org.apache.cassandra.thrift.Cassandra$Client.insert(Cassandra.java:830) 在 TestCassandra.main(TestCassandra.java:166)

我的代码是:

公共类TestCassandra { 公共静态无效 createKeySpace(Cassandra.Client 客户端,字符串 ksname) 抛出 TException、InvalidRequestException、UnavailableException、UnsupportedEncodingException、NotFoundException、TimedOutException、SchemaDisagreementException { KsDef ksdef = 新的 KsDef(); ksdef.name = ksname; ksdef.strategy_class= "网络拓扑策略"; 列表 l = new ArrayList(); ksdef.cf_defs = l; client.system_add_keyspace(ksdef); System.out.println("KeySpace 创建"); } 公共静态无效 createColumnFamily(Cassandra.Client 客户端,字符串 ksname,字符串 cfname) 抛出 TException、InvalidRequestException、UnavailableException、UnsupportedEncodingException、NotFoundException、TimedOutException、SchemaDisagreementException { CfDef cfd = 新 CfDef(ksname, cfname); client.system_add_column_family(cfd); System.out.println("列族创建"); } 公共静态无效主要(字符串 [] 参数) 抛出 TException、InvalidRequestException、UnavailableException、UnsupportedEncodingException、NotFoundException、TimedOutException、SchemaDisagreementException { TTransport tr = new TFramedTransport(new TSocket("localhost", 9160)); TProtocol proto = new TBinaryProtocol(tr); Cassandra.Client 客户端 = 新 Cassandra.Client(proto); tr.open(); 字符串 keySpace = "Keyspace1"; 字符串 columnFamily = "用户"; //删除键空间 client.system_drop_keyspace(keySpace); //创建键空间 KsDef ksdef = 新的 KsDef(); ksdef.name = keySpace; ksdef.strategy_class= "网络拓扑策略"; 列表 l = new ArrayList(); ksdef.cf_defs = l; client.system_add_keyspace(ksdef); System.out.println("KeySpace 创建"); //createKeySpace(client,keySpace); client.set_keyspace(keySpace); //创建列族 CfDef cfd = new CfDef(keySpace, columnFamily); client.system_add_column_family(cfd); System.out.println("列族创建"); //createColumnFamily(client,keySpace,columnFamily); ColumnParent parent = new ColumnParent(columnFamily); 列描述 = new Column(); description.setName("描述".getBytes()); description.setValue("我是个好人".getBytes()); description.setTimestamp(System.currentTimeMillis()); ConsistencyLevel 一致性级别 = ConsistencyLevel.ONE; ByteBuffer rowid = ByteBuffer.wrap("0".getBytes()); //第166行 client.insert(rowid,父级,描述,一致性级别); System.out.println("记录插入..."); tr.flush(); tr.close(); } }

谁能帮我解释一下为什么会这样?

【问题讨论】:

  • 您的堆栈跟踪表明问题出在第 166 行。您的代码 sn-p 没有行号。因此,您需要告诉我们第 166 行是什么,因为我确信您的代码 sn -p 不是整个文件。
  • 哦!对不起。异常出现在代码 client.insert(rowid, parent, description, contrastLevel);
  • 建议:使用Hector客户端,不要直接玩Thrift API。你的代码会更干净,更不容易出错。
  • 顺便说一句,UnavailableException 表示Not all the replicas required could be created and/or read.

标签: java cassandra


【解决方案1】:

UnavailableException 的原因是因为在您的createKeySpace 方法中,您从未为您的键空间定义KsDef 指定replication_factor

2 Strategy 类NetworkTopologyStrategySimpleStrategy 需要设置复制因子。在 Cassandra 0.8 及更高版本中,KsDef 中不再有 replication_factor 字段,因此您必须自己添加它,就像这样(我已经更新了您的代码,但没有经过测试。另外,请注意我已经更改你的strategy_classSimpleStrategy):

KsDef ksdef = new KsDef();
ksdef.name = ksname;
ksdef.strategy_class = SimpleStrategy.class.getName(); 

//Set replication factor
if (ksdef.strategy_options == null) {
    ksdef.strategy_options = new LinkedHashMap<String, String>();
}

//Set replication factor, the value MUST be an integer
ksdef.strategy_options.put("replication_factor", "1");

//Cassandra must now create the Keyspace based on our KsDef
client.system_add_keyspace(ksdef);

对于NetworkTopologyStrategy,您需要为您创建的每个数据中心指定复制因子(参见说明here)。

欲了解更多信息,请查看我的 Interfacing with Apache Cassandra 0.8 in Java 博客。

【讨论】:

  • 对于 NTS,您必须指定每个数据中心的副本数(即 NTS 的点)。因此,除非您有一个名为 replication_factor 的数据中心,否则这不会满足您的要求。这是一个常见的错误,我们在 0.8.3 中添加了一个特殊的检查:ConfigurationException("replication_factor is an option for SimpleStrategy, not NetworkTopologyStrategy")
  • @jbellis。谢谢你。它不起作用,因为我没有在 ksdef.strategy_options 中指定任何数据中心。当我指定它时,它工作正常。检查这个:breiftechnews.blogspot.com/2011/08/…
  • 现在有人如何将 Json 字符串直接插入 Cassandra?有没有办法像 client.insert(jsonString); ?
  • @Anand Soni,新问题,新问题! :-)
【解决方案2】:

请注意,我遇到了类似的问题(收到许多 Unavailable 异常),因为我在只有 3 个节点的集群上进行测试时,通过代码创建了一个 KsDef 并无意中将 10 放在那里。

所以复制因子为 10,因此尝试执行 QUORUM 读取或 QUORUM 写入总是会失败,因为永远无法达到 QUORUM(即 10 / 2 + 1 = 至少 6 个节点。)

修复我的复制因子修复了 QUORUM 一致性级别的所有问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 2013-05-16
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 2020-03-31
    相关资源
    最近更新 更多