我有一个带有单一复制的cassandra 2数据中心对,每个数据中心包含一个节点,每个数据中心位于网络上的不同物理服务器上。如果一个数据中心崩溃,另一个数据中心将继续可用于读取和写入我启动了我的java应用程序,在第三台服务器上,以及它运行正常的一切。它正在读写cassandra。
接下来我断开连接,从网络中拔出网线,第二个数据中心服务器。 我希望应用程序继续运行,对第一个数据中心没有例外,但事实并非如此。
应用程序中开始出现以下异常:
me.prettyprint.hector.api.exceptions.HUnavailableException: : May not be enough replicas present to handle consistency level.
at me.prettyprint.cassandra.service.ExceptionsTranslatorImpl.translate(ExceptionsTranslatorImpl.java:60)
at me.prettyprint.cassandra.service.KeyspaceServiceImpl$9.execute(KeyspaceServiceImpl.java:354)
at me.prettyprint.cassandra.service.KeyspaceServiceImpl$9.execute(KeyspaceServiceImpl.java:343)
at me.prettyprint.cassandra.service.Operation.executeAndSetResult(Operation.java:101)
at me.prettyprint.cassandra.connection.HConnectionManager.operateWithFailover(HConnectionManager.java:232)
at me.prettyprint.cassandra.service.KeyspaceServiceImpl.operateWithFailover(KeyspaceServiceImpl.java:131)
at me.prettyprint.cassandra.service.KeyspaceServiceImpl.getSuperColumn(KeyspaceServiceImpl.java:360)
at me.prettyprint.cassandra.model.thrift.ThriftSuperColumnQuery$1.doInKeyspace(ThriftSuperColumnQuery.java:51)
at me.prettyprint.cassandra.model.thrift.ThriftSuperColumnQuery$1.doInKeyspace(ThriftSuperColumnQuery.java:45)
at me.prettyprint.cassandra.model.KeyspaceOperationCallback.doInKeyspaceAndMeasure(KeyspaceOperationCallback.java:20)
at me.prettyprint.cassandra.model.ExecutingKeyspace.doExecute(ExecutingKeyspace.java:85)
at me.prettyprint.cassandra.model.thrift.ThriftSuperColumnQuery.execute(ThriftSuperColumnQuery.java:44)
将网线重新连接到第二台服务器后,错误停止了。
以下是关于cassandra 1.0.10
的更多细节1)以下是来自两个数据中心的cassandra的以下描述
Keyspace: AdvancedAds:
Replication Strategy: org.apache.cassandra.locator.NetworkTopologyStrategy
Durable Writes: true
Options: [DC2:1, DC1:1]
2)我针对每个实例运行了一个节点工具环
./nodetool -h 111.111.111.111 -p 11000 ring
Address DC Rack Status State Load Owns Token
1
111.111.111.111 DC1 RAC1 # <-- usUp Normal 1.07 GB 100.00% 0
111.111.111.222 DC2 RAC1 Up Normal 1.1 GB 0.00% 1
./nodetool -h 111.111.111.222 ring -port 11000
Address DC Rack Status State Load Owns Token
1
111.111.111.111 DC1 RAC1 Up Normal 1.07 GB 100.00% 0
111.111.111.222 DC2 RAC1 # <-- usUp Normal 1.1 GB 0.00% 1
3)我检查了cassandra.yaml
the seeds are 111.111.111.111, 111.111.111.222
4)我检查了cassandra-topology.properties
111.111.111.111
# Cassandra Node IP=Data Center:Rack
# datacenter 1
111.111.111.111=DC1:RAC1 # <-- us
# datacenter 2
111.111.111.222=DC2:RAC1
default=DC1:r1
111.111.111.222
# Cassandra Node IP=Data Center:Rack
# datacenter 1
111.111.111.111=DC1:RAC1
# datacenter 2
111.111.111.222=DC2:RAC1 # <-- us
default=DC1:r1
5)我们在java应用程序中将consistencyLevel设置为LOCAL_QUORUM,如下所示:
public Keyspace getKeyspace(final String keyspaceName, final String serverAddresses)
{
Keyspace ks = null;
Cluster c = clusterMap.get(serverAddresses);
if (c != null)
{
ConfigurableConsistencyLevel policy = new ConfigurableConsistencyLevel();
policy.setDefaultReadConsistencyLevel(consistencyLevel);
policy.setDefaultWriteConsistencyLevel(consistencyLevel);
// Create Keyspace
ks = HFactory.createKeyspace(keyspaceName, c, policy);
}
return ks;
}
我被告知这种配置可行,但也许我错过了什么。
感谢您的任何见解
答案 0 :(得分:1)
众所周知,Hector会返回虚假的不可用错误。本机协议Java驱动程序没有此问题:https://github.com/datastax/java-driver
答案 1 :(得分:0)
如果您只有两个节点,并且您的数据将放在实际关闭的节点上,那么当需要一致性时,您可能无法实现完全写入可用性。 Cassandra将使用Hinted Handoff实现这一目标,但对于QUORUM一致性级别,无论如何都会抛出UnavailableException
。
请求属于down节点的数据时也是如此。
然而,您的群集似乎没有很好地平衡。您的节点111.111.111.111
拥有100%,然后111.111.111.222
似乎拥有0%,看着您的令牌,他们似乎就是这个原因。
在此处查看如何设置初始令牌:http://www.datastax.com/docs/0.8/install/cluster_init#token-gen-cassandra
此外,如果出现这种情况,您可能需要查看Another Question,其中包含更多理由的答案。
答案 2 :(得分:0)
LOCAL_QUORUM
, NetworkTopologyStrategy
将无效:
Options: [DC2:1, DC1:1] # this will make LOCAL_QUORUM and QUORUM fail always
LOCAL_QUORUM
和(根据我的经验)QUORUM
要求数据中心至少拥有2个副本。如果您希望跨越数据中心的法定数量,则必须将一致性级别设置为与数据中心无关TWO
。
更多例子:
Options: [DC2:3, DC1:1] # LOCAL_QUORUM for clients in DC2 works, QUORUM fails
Options: [DC2:2, DC1:1] # LOCAL_QUORUM in DC2 works, but down after 1 node failure
# QUORUM fails, TWO works.