我是Apache-Cassandra 0.8.2的新手。我试图插入一些数据,但得到这个例外。
Exception in thread "main" UnavailableException() at org.apache.cassandra.thrift.Cassandra$insert_result.read(Cassandra.java:14902) at org.apache.cassandra.thrift.Cassandra$Client.recv_insert(Cassandra.java:858) at org.apache.cassandra.thrift.Cassandra$Client.insert(Cassandra.java:830) at TestCassandra.main(TestCassandra.java:166)
我的代码是:
public class TestCassandra { public static void createKeySpace( Cassandra.Client client,String ksname) throws TException, InvalidRequestException, UnavailableException, UnsupportedEncodingException, NotFoundException, TimedOutException, SchemaDisagreementException { KsDef ksdef = new KsDef(); ksdef.name = ksname; ksdef.strategy_class = "NetworkTopologyStrategy"; List l = new ArrayList(); ksdef.cf_defs =l; client.system_add_keyspace(ksdef); System.out.println("KeySpace Created"); } public static void createColumnFamily(Cassandra.Client client,String ksname,String cfname) throws TException, InvalidRequestException, UnavailableException, UnsupportedEncodingException, NotFoundException, TimedOutException, SchemaDisagreementException { CfDef cfd = new CfDef(ksname, cfname); client.system_add_column_family(cfd); System.out.println("ColumnFamily Created"); } public static void main(String[] args) throws TException, InvalidRequestException, UnavailableException, UnsupportedEncodingException, NotFoundException, TimedOutException, SchemaDisagreementException { TTransport tr = new TFramedTransport(new TSocket("localhost", 9160)); TProtocol proto = new TBinaryProtocol(tr); Cassandra.Client client = new Cassandra.Client(proto); tr.open(); String keySpace = "Keyspace1"; String columnFamily = "Users"; //Drop the Keyspace client.system_drop_keyspace(keySpace); //Creating keyspace KsDef ksdef = new KsDef(); ksdef.name = keySpace; ksdef.strategy_class = "NetworkTopologyStrategy"; List l = new ArrayList(); ksdef.cf_defs =l; client.system_add_keyspace(ksdef); System.out.println("KeySpace Created"); //createKeySpace(client,keySpace); client.set_keyspace(keySpace); //Creating column Family CfDef cfd = new CfDef(keySpace, columnFamily); client.system_add_column_family(cfd); System.out.println("ColumnFamily Created"); //createColumnFamily(client,keySpace,columnFamily); ColumnParent parent = new ColumnParent(columnFamily); Column description = new Column(); description.setName("description".getBytes()); description.setValue("I’m a nice guy".getBytes()); description.setTimestamp(System.currentTimeMillis()); ConsistencyLevel consistencyLevel = ConsistencyLevel.ONE; ByteBuffer rowid = ByteBuffer.wrap("0".getBytes()); //Line No. 166 client.insert(rowid, parent, description, consistencyLevel); System.out.println("Record Inserted..."); tr.flush(); tr.close(); } }
有人可以帮我解释为什么会这样吗?
答案 0 :(得分:6)
UnavailableException
的原因是由于您的createKeySpace
方法中的事实,您从未为密钥空间定义replication_factor
指定KsDef
。
2策略类NetworkTopologyStrategy
和SimpleStrategy
需要设置复制因子。在Cassandra 0.8及更高版本中,replication_factor
中不再有KsDef
字段,因此您必须自己添加它,就像这样(我已更新您的代码,但未经过测试。另外,请参阅我已将您的strategy_class
更改为SimpleStrategy
):
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博客。
答案 1 :(得分:1)
请注意,我遇到了类似的问题(接收到许多不可用的异常),因为我在代码中创建了一个KsDef,当我在只有3个节点的集群上进行测试时,无意中将10个放在那里。
因此复制因子表示10因此尝试进行QUORUM读取或QUORUM写入总是会失败,因为永远无法达到QUORUM(即10/2 + 1 =至少6个节点。)
修复我的复制因子修复了QUORUM一致性级别的所有问题。