我正在使用Astyanax客户端从Cassandra数据库中读取数据。
我在Cassandra数据库中有大约一百万个唯一行。我有一个包含四个节点的交叉colocation centre群集。
这是我的四个节点:
node1:9160
node2:9160
node3:9160
node4:9160
我启用了KeyCaching并且也启用了SizeTieredCompaction策略。
我有一个多线程的客户端程序,它将使用Astyanax客户端从Cassandra数据库读取数据,并且我运行20个线程。如果我使用20个线程运行我的客户端程序,那么从Cassandra数据库读取数据的性能会降低。
所以我想到的第一件事是可能存在与Cassandra连接的争用(他们是否使用了池,如果有的话,维护了多少连接)?我使用以下代码使用Astyanax客户端建立连接。
private CassandraAstyanaxConnection() {
context = new AstyanaxContext.Builder()
.forCluster(ModelConstants.CLUSTER)
.forKeyspace(ModelConstants.KEYSPACE)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
)
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
.setPort(9160)
.setMaxConnsPerHost(1)
.setSeeds("nod1:9160,node2:9160,node3:9160,node4:9160")
)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setCqlVersion("3.0.0")
.setTargetCassandraVersion("1.2"))
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
context.start();
keyspace = context.getEntity();
emp_cf = ColumnFamily.newColumnFamily(
ModelConstants.COLUMN_FAMILY,
StringSerializer.get(),
StringSerializer.get());
}
我是否需要在上述代码中进行任何类型的更改以提高性能?
这种方法有什么作用?
setMaxConnsPerHost(1)
我是否需要增加它以提高性能?我有四个节点,所以我应该将其更改为4?
setMaxConns(20)方法会调用吗?我是否还需要添加它以提高性能?因为我将用多个线程运行我的程序。
答案 0 :(得分:9)
有关maxConnsPerHost
/ maxConns
的详细信息您可以查看以下答案:setMaxConns and setMaxConnsPerHost in Astyanax client
是的,应该增加maxConnsPerHost
以获得良好的性能。最佳值取决于网络拓扑,请求复制因子,存储配置,缓存,读/写比率等。
我不认为在没有实验和模拟的情况下,可以为重载集群实现最佳性能。
对于Cassandra中等负荷的任务,我通常使用经验法则:
maxConnsPerHost ~= <Number of cores per host>/<Replication factor> + 1
也就是说,对于具有复制因子3的8核盒的簇,maxConnsPerHost
应该是4左右。该值也是重载场景中实验的良好起点。
动机:每个N
核心的C
个节点集群总共有N * C
个核心。要处理具有复制因子R
的请求,需要R
核心(不同节点)。因此,在每个给定时刻,群集最多可以处理N * C / R
个请求。保持此数字周围的并发连接数是个好主意。除以N
以计算每个主机的连接数。为每个主机添加1个备用连接以用于网络延迟等等。就是这样。
更新:简单客户端性能调整:
maxConnsPerHost
值org.apache.cassandra.request->***Stage->pendingTasks
JXM属性maxConnsPerHost
,直到pendingTasks
开始迅速增加。这可能是最佳值。