我在com.netflix.astyanax.connectionpool.NodeDiscoveryType中为Cassandra找到了Astyanax客户端中的TOKEN_AWARE
枚举值,并且我想了解它的作用?
package com.netflix.astyanax.connectionpool;
public enum NodeDiscoveryType {
/**
* Discover nodes exclusively from doing a ring describe
*/
RING_DESCRIBE,
/**
* Discover nodes exclusively from an external node discovery service
*/
DISCOVERY_SERVICE,
/**
* Intersect ring describe and nodes from an external service. This solve
* the multi-region ring describe problem where ring describe returns nodes
* from other regions.
*/
TOKEN_AWARE,
/**
* Use only nodes in the list of seeds
*/
NONE
}
假设我有24个节点cross colo cluster
,其中PHX colo/datacenter
有12个节点,SLC colo/datacenter
有12个节点。
我使用Astyanax客户端连接到Cassandra,如下所示:
private CassandraAstyanaxConnection() {
context = new AstyanaxContext.Builder()
.forCluster(ModelConstants.CLUSTER)
.forKeyspace(ModelConstants.KEYSPACE)
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
.setPort(9160)
.setMaxConnsPerHost(40)
.setSeeds("cdb03.vip.phx.host.com:9160,cdb04.vip.phx.host.com:9160")
)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setCqlVersion("3.0.0")
.setTargetCassandraVersion("1.2")
.setDiscoveryType(NodeDiscoveryType.TOKEN_AWARE))
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
context.start();
keyspace = context.getEntity();
emp_cf = ColumnFamily.newColumnFamily(
ModelConstants.COLUMN_FAMILY,
StringSerializer.get(),
StringSerializer.get());
}
任何人都可以解释一下TOKEN_AWARE
NodeDiscoveryType
与TOKEN_AWARE
ConnectionPoolType
之间的区别是什么?
感谢您的帮助。
更新代码
以下是我在进行更改后使用的代码 -
private CassandraAstyanaxConnection() {
context = new AstyanaxContext.Builder()
.forCluster(ModelConstants.CLUSTER)
.forKeyspace(ModelConstants.KEYSPACE)
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
.setPort(9160)
.setMaxConnsPerHost(40)
.setSeeds("cdb03.vip.phx.host.com:9160,cdb04.vip.phx.host.com:9160")
.setLocalDatacenter("phx")
)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setCqlVersion("3.0.0")
.setTargetCassandraVersion("1.2")
.setConnectionPoolType(ConnectionPoolType.TOKEN_AWARE))
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
context.start();
keyspace = context.getEntity();
emp_cf = ColumnFamily.newColumnFamily(
ModelConstants.COLUMN_FAMILY,
StringSerializer.get(),
StringSerializer.get());
}
您在示例中提到您将使用 -
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
.setConnectionPoolType(ConnectionPoolType.TOKEN_AWARE)
这两个在一起吗?但我相信TOKEN_AWARE ConnectionPoolType
默认使用RING_DESCRIBE
,因此再次添加它是没有意义的。我是对的吗?
如果我错了,请纠正我?
答案 0 :(得分:12)
当谈到“节点发现”时,NodeDiscoveryType的TOKEN_AWARE与ConnectionPoolType的TOKEN_AWARE之间的关系是相互关联的,并且有些混乱。
现在我们已经确定了如何设置NodeDiscoveryType,让我们see它如何影响实际发现节点。节点发现归结为使用HostSupplier(即Supplier<List<Host>>
)的实现。
withHostSupplier
)。withHostSupplier
)则使用带有RingDescribeHostSupplier的FilteringHostSupplier。根据您提供的配置,您最终将获得RingDescribeHostSupplier。除非您指定了数据中心,否则RingDescribeHostSupplier允许连接到环中的所有节点。因此,在使用ConnectionPoolConfigurationImpl设置AstyanaxContext时,您可能希望使用所需的DC setLocalDatacenter。这将确保来自其他DC的主机不在连接池中,并且您的请求是本地的。
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
.setPort(9160)
.setMaxConnsPerHost(40)
.setLocalDatacenter("phx")
.setSeeds("cdb03.vip.phx.host.com:9160,cdb04.vip.phx.host.com:9160")
)
您还可能希望将ConnectionPoolType设置为TOKEN_AWARE。当该值未设置时,它将默认为ROUND_ROBIN(使用上述节点发现工作中的节点)。 TOKEN_AWARE ConnectionPoolType将“跟踪哪些主机具有哪些令牌并尝试智能地引导流量”。
除非你提供HostSupplier,否则我会为Astyanax配置执行类似的操作。
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
.setConnectionPoolType(ConnectionPoolType.TOKEN_AWARE)
)
另一个考虑因素是在ConnectionPoolConfigurationImpl上使用Astyanax“延迟感知”优化池使用,但在设置上使用YMMV。例如:
.setLatencyScoreStrategy(new SmaLatencyScoreStrategyImpl(10000,10000,100,0.50))
// The constructor takes:
// UpdateInterval: 10000 : Will resort hosts per token partition every 10 seconds
// ResetInterval: 10000 : Will clear the latency every 10 seconds
// WindowSize: 100 : Uses last 100 latency samples
// BadnessThreshold: 0.50 : Will sort hosts if a host is more than 100%
见Astyanax Configuration
总之,将NodeDiscoveryType设置为RING_DESCRIBE(如果您没有使用HostSupplier),将ConnectionPoolType设置为TOKEN_AWARE。此外,使用setLocalDatacenter将请求保持在dc本地,并考虑延迟感知设置。
答案 1 :(得分:0)
明智地实施ConnectionPoolType.TOKEN_AWARE
通过拥有正在操作的令牌的主机对连接进行分区的连接池。当令牌不可用或已知跨越多个令牌的操作(例如批量变异或索引查询)时,使用循环法挑选主机池。
NodeDiscoveryType.TOKEN_AWARE
在多数据中心场景中重新发现铃声描述信息。